C 语言中的 Rijndael S-box
Rijndael S-box in C
我正在尝试根据这篇维基百科文章编写一个计算 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。我怀疑问题可能是轮换工作不正常,但现在看来这不是问题...
这里有什么问题?
这是实现 AES 的 S-box 的错误方法 - 大多数实现要么是硬编码的(它们明确地将整个 S-box 写为 256 字节数组),要么是迭代 构建 S-box 的条目,如您链接的维基百科文章所示:
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 对于一些创造性的实现。
我正在尝试根据这篇维基百科文章编写一个计算 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。我怀疑问题可能是轮换工作不正常,但现在看来这不是问题...
这里有什么问题?
这是实现 AES 的 S-box 的错误方法 - 大多数实现要么是硬编码的(它们明确地将整个 S-box 写为 256 字节数组),要么是迭代 构建 S-box 的条目,如您链接的维基百科文章所示:
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 对于一些创造性的实现。