我试图通过添加解密模块来扩展Speck密码(Ciphers)的以下实现。我按照美国国家安全局关于Speck和西蒙(https://eprint.iacr.org/2013/404)的原始论文的指令实现了解密算法。
目前,我有点卡住了,因为我不能正确地解码加密例程生成的密码文本。我已经看过其他类似的问题张贴在这里,所以没有任何结果。
通过检查我的代码和标准输出,我注意到在解密阶段存储在x_word中的值是不正确的,从第一次迭代开始。因此,下列指示可能有问题:
x_word = rotate_left( (sub_mod((x_word ^ *(round_key_ptr + 21 - i)), y_word, 65535)), 7);我在这里发布代码的相关部分:
#define rotate_left(x,n) (x >> (word_size - n)) | (x << n)
#define rotate_right(x,n) (x << (word_size - n)) | (x >> n)
void Speck_Encrypt_32(uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) {
const uint8_t word_size = 16;
uint16_t y_word = *(uint16_t *)plaintext;
uint16_t x_word = *(((uint16_t *)plaintext) + 1);
uint16_t *round_key_ptr = (uint16_t *)key_schedule;
uint16_t * word_ptr = (uint16_t *)ciphertext;
for(uint8_t i = 0; i < 22; i++) { // Block size 32 has only one round number option
x_word = ((rotate_right(x_word, 7)) + y_word) ^ *(round_key_ptr + i);
y_word = (rotate_left(y_word, 2)) ^ x_word;
printf("y_word - (%d) - %u\n", i, (unsigned int)y_word);
printf("x_word - (%d) - %u\n", i, (unsigned int)x_word);
}
// Assemble Ciphertext Output Array
*word_ptr = y_word;
word_ptr += 1;
*word_ptr = x_word;
return;
}
static inline uint16_t sub_mod(uint16_t a, uint16_t b, uint16_t m)
{
if ( a>=b )
return a - b;
else
return m - b + a;
}
void Speck_Decrypt_32(uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) {
const uint8_t word_size = 16;
// Swapping cipher text words
uint16_t y_word = *(uint16_t *)ciphertext;
uint16_t x_word = *(((uint16_t *)ciphertext) + 1);
uint16_t *round_key_ptr = (uint16_t *)key_schedule;
uint16_t * word_ptr = (uint16_t *)plaintext;
for(int i=0; i < 4; i++) {
printf("Ciphertext Byte %02d: %02x \n",i,ciphertext[i]);
printf("Plaintext Byte %02d: %02x \n",i,plaintext[i]);
}
// Reading round keys in reverse order
for(uint8_t i = 0; i < 22; i++) { // Block size 32 has only one round number option
//printf("y_word - (%d) - %u\n", i, (unsigned int)y_word);
//printf("x_word - (%d) - %u\n", i, (unsigned int)x_word);
// Inverting rotations and using custom modular subtraction
y_word = rotate_right((x_word ^ y_word), 2);
x_word = rotate_left( (sub_mod((x_word ^ *(round_key_ptr + 21 - i)), y_word, 65535)), 7);
}
// Assemble Plaintext - Swapping plaintext words
*word_ptr = y_word;
word_ptr += 1;
*word_ptr = x_word;
return;
}我已经有一段时间没有用C语言编码了,可能会有一些错误。
发布于 2017-07-11 13:40:06
好的旧笔和纸支票帮助我发现了两个错误:
a mod n-1而不是a mod n (我是作为除数传递错误的值)。在修复了前面提到的错误之后,我现在能够正确地用不同的块/bey大小加密/解密。
不管怎样,谢谢大家的帮助。
发布于 2017-07-07 19:48:30
鉴于回购的作者没有完成C解密例程的编写工作,我首先会担心C设置或en密码例程的有效性。
与其从那里开始,不如看看其中一个工作中的C实现:
https://github.com/mysummergit/myssl/blob/master/demos/mycipher/speck.c
发布于 2017-07-07 23:31:39
只需反向加密即可。因此,如果您的展开键是k_0,.,k_{21},那么您将在C中执行以下操作。
#定义ROTR (x,r) (x> r) \x(x<(16-r)&0 0xffff)
#定义ROTL (x,r) (x<< r) x(x>>(16-r)&0 0xffff)
#定义invR(x,y,k) (y=y^x,y=ROTR(y,2),x=x^k,x=(X)&0 0xffff,x=ROTL(x,7))
然后你就会做这样的事情:
对于(i=21;i>=0;i-) invR(x,y,ki)
FYI: SIMON和SPECK是近年来分析最多的分组密码。有70多篇“同行评审”论文对它们进行了分析(你可以通过在谷歌学者上进行搜索来查看),它们的安全性与AES-128类似。在x86处理器上,speed 128/256的速度与ChaCha20 (一种非常快的流密码)几乎相同。SPECK128 128/256在x86处理器上的快速软件实现比使用AES-NI (即硬件指令)的AES-256慢约50%。有关与超级for基准测试系统兼容的SIMON和SPECK的快速实现,请参见https://github.com/iadgov/simon-speck-supercop。
https://stackoverflow.com/questions/44977145
复制相似问题