0%

AES加密算法4-S盒构造实现

这里使用乘法逆元构造AES加密使用的S盒,S盒的安全强度直接关系到AES的强度;这里只用代码实现,实际的加密过程中,S盒和逆S盒可以直接给出.

1. S盒基本构造步骤

第三步中使用的矩阵为X,逆S盒的第三步的矩阵为Y,第三步最后相加的向量C,逆S盒中最后相加的向量为D.他们的关系是 YX = 1,D = YC;向量C相加是为了消除S盒的不动点.
具体的算法步骤参见下图:

2. S盒代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//S盒产生,参考上面的结构图
void s_box_gen(void) {
uint8_t i,j;
uint8_t s_box_ary[16][16] = {0};

//初始化S盒
for(i=0;i<0x10;i++) {
for(j=0;j<0x10;j++) {
s_box_ary[i][j] = ((i<<4)&0xF0) + (j&(0xF));
}
}

//求在GF(2^8)域上的逆,0映射到自身
for(i=0;i<0x10;i++) {
for(j=0;j<0x10;j++) {
if(s_box_ary[i][j] != 0) {
s_box_ary[i][j] = gmult_inverse(s_box_ary[i][j],0x11B);
}
}
}

//对每个字节做变换
//左乘偏移矩阵在异或C向量(0x63)
for(i=0;i<0x10;i++) {
for(j=0;j<0x10;j++) {
s_box_ary[i][j] = byteTransformation(s_box_ary[i][j], 0x63);
}
}
}

//S盒字节变换
//这是S盒生成的第三步,C为0x63
uint8_t byteTransformation(uint8_t a, uint8_t c) {
uint8_t tmp[8]={0};
for(uint8_t i=0;i<8;i++) {
tmp[i]= (((a>>i)&0x1)^((a>>((i+4)%8))&0x1)^((a>>((i+5)%8))&0x1)^((a>>((i+6)%8))&0x1)^((a>>((i+7)%8))&0x1)^((c>>i)&0x1)) << i;
}
tmp[0] = tmp[0]+tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7];
return tmp[0];
}

3. 构造结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
0 63 7c 77 7b f2 6b 6f c5 30 1 67 2b fe d7 ab 76
1 ca 82 c9 7d fa 59 47 f0 ad d4 a2 af 9c a4 72 c0
2 b7 fd 93 26 36 3f f7 cc 34 a5 e5 f1 71 d8 31 15
3 4 c7 23 c3 18 96 5 9a 7 12 80 e2 eb 27 b2 75
4 9 83 2c 1a 1b 6e 5a a0 52 3b d6 b3 29 e3 2f 84
5 53 d1 0 ed 20 fc b1 5b 6a cb be 39 4a 4c 58 cf
6 d0 ef aa fb 43 4d 33 85 45 f9 2 7f 50 3c 9f a8
7 51 a3 40 8f 92 9d 38 f5 bc b6 da 21 10 ff f3 d2
8 cd c 13 ec 5f 97 44 17 c4 a7 7e 3d 64 5d 19 73
9 60 81 4f dc 22 2a 90 88 46 ee b8 14 de 5e b db
a e0 32 3a a 49 6 24 5c c2 d3 ac 62 91 95 e4 79
b e7 c8 37 6d 8d d5 4e a9 6c 56 f4 ea 65 7a ae 8
c ba 78 25 2e 1c a6 b4 c6 e8 dd 74 1f 4b bd 8b 8a
d 70 3e b5 66 48 3 f6 e 61 35 57 b9 86 c1 1d 9e
e e1 f8 98 11 69 d9 8e 94 9b 1e 87 e9 ce 55 28 df
f 8c a1 89 d bf e6 42 68 41 99 2d f b0 54 bb 16

总结:为什么使用乘法逆元的原因基本就是为了是一个可变的仿射变换,但是对偏移矩阵和异或0x63的设计原理不是很清楚,后续学习后再补充;本篇代码点击另存