首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中的Speck密码解密问题

C中的Speck密码解密问题
EN

Stack Overflow用户
提问于 2017-07-07 18:06:38
回答 3查看 789关注 0票数 0

我试图通过添加解密模块来扩展Speck密码(Ciphers)的以下实现。我按照美国国家安全局关于Speck和西蒙(https://eprint.iacr.org/2013/404)的原始论文的指令实现了解密算法。

目前,我有点卡住了,因为我不能正确地解码加密例程生成的密码文本。我已经看过其他类似的问题张贴在这里,所以没有任何结果。

通过检查我的代码和标准输出,我注意到在解密阶段存储在x_word中的值是不正确的,从第一次迭代开始。因此,下列指示可能有问题:

代码语言:javascript
复制
x_word = rotate_left( (sub_mod((x_word ^ *(round_key_ptr + 21 - i)), y_word, 65535)), 7);

我在这里发布代码的相关部分:

代码语言:javascript
复制
#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语言编码了,可能会有一些错误。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-11 13:40:06

好的旧笔和纸支票帮助我发现了两个错误:

  1. 模块减法函数是错误的,因为我基本上是在执行a mod n-1而不是a mod n (我是作为除数传递错误的值)。
  2. 生成密钥调度的函数一开始是错误的。我不得不按照研究论文的规格重写它。

在修复了前面提到的错误之后,我现在能够正确地用不同的块/bey大小加密/解密。

不管怎样,谢谢大家的帮助。

票数 0
EN

Stack Overflow用户

发布于 2017-07-07 19:48:30

鉴于回购的作者没有完成C解密例程的编写工作,我首先会担心C设置或en密码例程的有效性。

与其从那里开始,不如看看其中一个工作中的C实现:

C

Speck

https://github.com/mysummergit/myssl/blob/master/demos/mycipher/speck.c

票数 1
EN

Stack Overflow用户

发布于 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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44977145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档