c-Kuznyechik源代码(来自VeraCrypt密码)中的[uint64 x1=*(const uint64*)i



VeraCrypt源代码中的Kuznyechik源代码中有两个元素:https://github.com/veracrypt/VeraCrypt/blob/master/src/Crypto/kuznyechik.c#L2271-L2272

uint64 x1 = *(const uint64*)in;
uint64 x2 = *(((const uint64*)in)+1);

它们在Kuznyechik S-Box中处理如下:

#define LS(x1,x2,t1,t2) { 
t1 = T[0][(byte)(x1)][0] ^ T[1][(byte)(x1 >> 8)][0] ^ T[2][(byte)(x1 >> 16)][0] ^ T[3][(byte)(x1 >> 24)][0] ^ T[4][(byte)(x1 >> 32)][0] ^ T[5][(byte)(x1 >> 40)][0] ^ 
T[6][(byte)(x1 >> 48)][0] ^ T[7][(byte)(x1 >> 56)][0] ^ T[8][(byte)(x2)][0] ^ T[9][(byte)(x2 >> 8)][0] ^ T[10][(byte)(x2 >> 16)][0] ^ T[11][(byte)(x2 >> 24)][0] ^ 
T[12][(byte)(x2 >> 32)][0] ^ T[13][(byte)(x2 >> 40)][0] ^ T[14][(byte)(x2 >> 48)][0] ^ T[15][(byte)(x2 >> 56)][0]; 
t2 = T[0][(byte)(x1)][1] ^ T[1][(byte)(x1 >> 8)][1] ^ T[2][(byte)(x1 >> 16)][1] ^ T[3][(byte)(x1 >> 24)][1] ^ T[4][(byte)(x1 >> 32)][1] ^ T[5][(byte)(x1 >> 40)][1] ^ 
T[6][(byte)(x1 >> 48)][1] ^ T[7][(byte)(x1 >> 56)][1] ^ T[8][(byte)(x2)][1] ^ T[9][(byte)(x2 >> 8)][1] ^ T[10][(byte)(x2 >> 16)][1] ^ T[11][(byte)(x2 >> 24)][1] ^ 
T[12][(byte)(x2 >> 32)][1] ^ T[13][(byte)(x2 >> 40)][1] ^ T[14][(byte)(x2 >> 48)][1] ^ T[15][(byte)(x2 >> 56)][1]; 
}

/\https://github.com/veracrypt/VeraCrypt/blob/master/src/Crypto/kuznyechik.c#L2147-L2152

这是什么意思?这是否意味着x1将处理t1中的第一个到第八个字节,并将再次处理,但从第八个到第一个字节(按相反顺序(?我说得对吗?

查看比您发布的代码更多的代码,我发现in是一个声明为(的typedef(const char *的函数参数。考虑到这一点,你发布的第一个片段本可以作为写得更易读

const uint64_t *in_qword = (const uint64_t *)in;
uint64_t x1 = in_qword[0];
uint64_t x2 = in_qword[1];

(这个程序的uint64和标准的uint64_t看起来是一样的,但我没有足够仔细地挖掘这个程序头文件中#ifdefs的迷宫来确定这一点。实际上,我要说的其余内容并不重要。(

通过这种方式重写,我们可以看到我们有一个指向char数组的指针,并且程序正试图访问该数组的前几个char,就好像它一直是uint64_t类型的数组一样。这在密码学代码中相对常见,但C语言实际上不允许您这样做原始代码和我的重写都具有形式上称为";未定义行为";。根据我的经验,只要你不尝试使用链接时间优化,像这样的代码可能会按照预期运行,但这是你可以逃避的,而不是你可以依赖的。

(好吧,应该如何获取char数组的第一个sizeof(uint64_t)字节,并将它们作为机器端整数加载到uint64_t中?唯一严格符合的方法是

memcpy(&x1, &in[0], sizeof(uint64_t));

但这并没有给出";是的,它编译成一个加载指令";在这样的低级代码中,人们通常想要的性能保证。C语言没有提供任何替代方案,这就是为什么人们一直在使用";类型punning";尽管这是不正确的。(

您发布的第二个片段似乎正在以典型的难以辨认的方式对加密原语进行字节洗牌和S盒查找。我无法单独判断它是否是正确的C,我也没有资格说这个密码是否好。

相关内容

  • 没有找到相关文章

最新更新