【问题标题】:Rijndael S-box in CRijndael S-box in C
【发布时间】:2021-11-03 02:06:35
【问题描述】:

我正在尝试根据这篇 Wikipedia 文章编写一个计算 Rijndael S-box 的函数。 Rijndael S-box

#define ROTL8(x,shift) ((uint8_t) ((x) << shift | ((x) >> (8 - (shift)))))
uint8_t sbox(uint8_t b)
{
    uint8_t s = b ^ ROTL8(b,1) ^ ROTL8(b,2) ^ ROTL8(b,3) ^ ROTL8(b,4) ^ 0x63;
    return s;
}

现在,当我尝试 sbox(0x00)=0x63 和 sbox(0x01)=0x7c 时,这有效,但它开始偏离 sbox(0x02),应该是 0x77,但我得到的是 0x5d。我怀疑问题可能是轮换工作不正常,但现在看来这不是问题......

这里有什么问题?

【问题讨论】:

    标签: c cryptography


    【解决方案1】:

    这是实现 AES 的 S-box 的错误方法 - 大多数实现要么是硬编码的(他们明确地将整个 S-box 写入为 256 字节数组),要么他们迭代构建条目的 S-box,如您链接的 Wikipedia 文章中所示:

    void initialize_aes_sbox(uint8_t sbox[256]) {
        uint8_t p = 1, q = 1;
        
        /* loop invariant: p * q == 1 in the Galois field */
        do {
            /* multiply p by 3 */
            p = p ^ (p << 1) ^ (p & 0x80 ? 0x1B : 0);
    
            /* divide q by 3 (equals multiplication by 0xf6) */
            q ^= q << 1;
            q ^= q << 2;
            q ^= q << 4;
            q ^= q & 0x80 ? 0x09 : 0;
    
            /* compute the affine transformation */
            uint8_t xformed = q ^ ROTL8(q, 1) ^ ROTL8(q, 2) ^ ROTL8(q, 3) ^ ROTL8(q, 4);
    
            sbox[p] = xformed ^ 0x63;
        } while (p != 1);
    
        /* 0 is a special case since it has no inverse */
        sbox[0] = 0x63;
    }
    

    请注意,xformed 的值 - 这是您在自己的实现中计算的值 - 在迭代中迭代地变化(它不是您实现的 q 的 S-box 值)。在实践中,每个手动 S-box 构造都有某种类似的迭代过程 - look over at Code Golf 用于一些创造性的实现。

    【讨论】:

    • 我刚刚使用调试器跟踪了代码,并意识到这个给定代码的“p”变量值没有增加 1,但有点“随机”但覆盖了从 0 到的整个索引范围255. 我猜只是有一个预先计算好的表数组更实用?
    • 是的,它更实用:) - openssl 似乎是这样做的:github.com/openssl/openssl/blob/master/crypto/aes/…
    猜你喜欢
    • 2011-06-23
    • 2022-12-02
    • 1970-01-01
    • 2018-10-14
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    相关资源
    最近更新 更多