蛇加密密钥时间表,如何通过密钥扩展到 256 位

serpent encryption key schedule, how to padd the key to expand to 256bits

我试图从头开始实现 serpent 加密算法作为个人项目,现在我被其中的密钥调度部分困住了。根据唯一的文档,https://www.cl.cam.ac.uk/~rja14/Papers/serpent.pdf,我需要将密钥填充到 256,这样我才能开始生成子密钥。

如何在不依赖外部库的情况下应用填充。

这是我编写的代码,我不是 100% 确定它会引导我实现我想要实现的目标

void prekeyexpasion(unsigned char * key,unsigned char * expandedkeys){
    //padd the key to 256
    int originalkeylen = strlen((const char*)key);
    int lenOfPaddedkey = originalkeylen;
    if(lenOfPaddedkey % 32 !=0){
        lenOfPaddedkey = (lenOfPaddedkey / 32 + 1) * 32;
    }
    unsigned char * paddedkey = new unsigned char[lenOfPaddedkey];

    for (int i = 0; i < lenOfPaddedkey; i++){
        if ( i >= originalkeylen){
            paddedkey[i] = 1;
        }
        else{
            paddedkey[i] = key[i];
        }
        
    }
    //expand to 33 128bit subkeys
    //split per 128bit subkeys to 8 32 bit subsubkey

    
    
}

让我们看一下标准,假设本文开头指出的小端表示法:

The user key length is variable, but for the purposes of this submission we fix it at 128, 192 or 256 bits; short keys with less than 256 bits are mapped to full-length keys of 256 bits by appending one “1” bit to the MSB end, followed by as many “0” bits as required to make up 256 bits.


然后看看你的代码:

int originalkeylen = strlen((const char*)key);

首先,密钥不是密码。它是二进制字符串,而不是文本字符串。这意味着 strlen 不能用在键上。相反,密钥的大小应该在提供时包含在密钥中(或者您应该使用更高级别的构造来传递密钥,毕竟这是 C++,而不是 C)。

int lenOfPaddedkey = originalkeylen;

通常我绝不会为变量分配不正确的值,即使是暂时的。

if(lenOfPaddedkey % 32 !=0){
    lenOfPaddedkey = (lenOfPaddedkey / 32 + 1) * 32;
}

您首先要使用守卫检查密钥大小是否正确。在那种情况下不需要 % 32,您不妨使用 lenOfPaddedkey != 32。除此之外,lenOfPaddedkey / 32 将始终为零,因此整行也可能是 int lenOfPaddedkey = 32,这应该是正确的。但是,如果它总是 32,为什么还需要一个变量?

unsigned char * paddedkey = new unsigned char[lenOfPaddedkey];

嗯,我不喜欢在这里使用 char *,但是好吧,我们有一个由字节组成的新缓冲区。请注意,此调用不会初始化为零,请参阅 here 了解更多信息。

for (int i = 0; i < lenOfPaddedkey; i++){

好的,很好,尽管只输入 32 位文字(作为常量/#define 可能会加快处理速度)。

    if ( i >= originalkeylen){
        paddedkey[i] = 1;
    }

这是不正确的,只应添加一位/字节,然后添加零位/字节。

    else{
        paddedkey[i] = key[i];
    }

是的,仅使用库调用来复制字节可能会更快。


改为:

  1. 检查密钥大小,应为 16、24 或 32 字节;

  2. 创建 padded_key 4 个 int32_t 值的缓冲区;

  3. 将字节复制到 padded_key 缓冲区(查看 this answer,注意 C++ 整数是未定义的混乱);

  4. 如果需要执行填充:

    一个。如果 2 int32_t 用于 128 位密钥,则将第 3 个 int32_t 设置为值 1,并将最后一个 int32_t 设置为零;

    b.如果 3 int32_t 用于 192 位密钥,则将第 4 个 int32_t 设置为值 1.

现在您可以根据 32 位字的填充密钥继续进行密钥扩展(您是否可能首先需要更大的缓冲区?)。