0%

AES加密算法1-轮常量计算

AES中的加密过程用到了一个轮常量的计算过程,之前对有限域的理解不是很深,也是经过长时间的积累以后,重新又对近世代数的东西有新的理解,特别是这个有限域的乘法,根据资料和笔记整理一下,以备后续参考.

1. 有限域的乘法

这里专门讨论的有限域为 $ GF(2^8)$ 域 ;而$GF(2^8)$的乘法,简单来讲就是$2^8$的乘法的结果求模,求模以后的结果是在$(1,2^8-1)$这个区间内的,这里的操作是二进制的乘法,抽象代数里比较抽象的就是这个操作,乘法不是日常你见到的乘法,他只是代表一个集合的操作规则,具体可以参考这篇文章的说明;这里有一个问题是取模的多项式的定义,这个推导过程放在日后再来推导,定义在这里; 在 $GF(2^8)$中的取模多项式是 $x^8+x^4+x^3+x^2+1$;

2. 有限域乘法(c++实现)

代码之前需要注意的是二进制的加法就是异或(XOR),乘法就是(AND).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* Multiplication in GF(2^8)
* http://en.wikipedia.org/wiki/Finite_field_arithmetic
* Irreducible polynomial m(x) = x8 + x4 + x3 + x + 1
*/
uint8_t gmult(uint8_t a, uint8_t b) {
uint8_t p = 0, i = 0, hbs = 0;
// 8位比特位计算
for (i = 0; i < 8; i++) {
// 当前位位1时加上一个a(异或)
if (b & 1) {
p ^= a;
}
// a的值是否超过[1,2^8]这个范围
hbs = a & 0x80;
// 被乘数右移一位,用来上面相加使用.
a <<= 1;
// 如果值超过2^8时,进行多项式取模,参见上面的取模多项式
if (hbs) a ^= 0x1b; // 0000 0001 0001 1011
b >>= 1;
}

return (uint8_t)p;
}

3. 轮常量计算

先附一张图关于如何计算轮常量的,截图来自《密码编码学第七版》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
* Generates the round constant Rcon[i]
*/
uint8_t Rcon(uint8_t i) {
uint8_t R = 0;
if (i == 1) {
R = 0x01; // x^(1-1) = x^0 = 1
} else if (i > 1) {
R = 0x02;
i--;
while (i-1 > 0) {
R = gmult(R, 0x02);
i--;
}
}

return R;
}

备注:在AES中这些值是固定的可以直接用,但至少需要知道这些值是怎么来的.本篇的代码aes_1.c 点击下载