第3章分组密码体制 3.1概述 设明文消息编码表示后的二元数字序列为M={x0,x1,…,xk,…}。分组密码首先将M划分成长为m的组块Bi=(xi×m,xi×m+1,…,xi×m+m-1)(长为m的向量)的集合,然后各组分别在密钥K的控制下变换成长度为n的组块Ci=(yi×n,yi×n+1,…,yi×n+n-1)(长为n的向量)。若n>m,则为有数据扩展的分组密码; 若n0; round--) { InvShiftRows(state); InvSubBytes(state); AddRoundKey(state, w[4*round, 4*round+3]); InvMixColumns(state); } //最后一轮解密 InvShiftRows(state); InvSubBytes(state); AddRoundKey(state, w[0, 3]); } 容易看出,AES的解密过程使用了四种逆变换,即InvSubBytes(·)、InShiftRows(·)、InvMixColumns(·)和AddRoundKey(·)(AddRoundKey的逆变换是它自身),以相反的顺序对由密文映射得到的状态矩阵进行变换。另外,AES的解密过程使用的子密钥与加密过程相同,但使用的顺序相反。下面介绍算法中的基本变换。 3.5.3算法的基本变换 1. 字节替换变换(SubBytes) 字节替换操作使用一个S盒对State的每字节都进行独立的替换。表3.10给出了AES的S盒。 表3.10AES的S盒 Y X 0123456789abcdef 0637c777bf26b6fc53001672bfed7ab76 1ca82c97dfa5947f0add4a2af9ca472c0 2b7fd9326363ff7cc34a5e5f171d83115 304c723c31896059a071280e2eb27b275 409832c1a1b6e5aa0523bd6b329e32f84 553d100ed20fcb15b6acbbe394a4c58cf 6d0efaafb434d338545f9027f503c9fa8 751a3408f929d38f5bcb6da2110fff3d2 8cd0c13ec5f974417c4a77e3d645d1973 960814fdc222a908846eeb814de5e0bdb ae0323a0a4906245cc2d3ac629195e479 be7c8376d8dd54ea96c56f4ea657aae08 cba78252e1ca6b4c6e8dd741f4bbd8b8a d703eb5664803f60e613557b986c11d9e ee1f8981169d98e949b1e87e9ce5528df f8ca1890dbfe6426841992d0fb054bb16 与DES的S盒相比,AES的S盒能进行代数上的定义,而且不是像DES的S盒那样比较明显的“随机”代换。 S盒按如下方式构造: (1) 行x、列y的字节值初始化为十六进制的{xy}; (2) 把S盒中的每字节映射为在有限域GF(28)中的逆,{00}不变; (3) 把S盒中的每字节转换为二进制表示(b7,b6,b5,b4,b3,b2,b1,b0),然后进行如下的仿射变换: b′0b′1b′2b′3b′4b′5b′6b′7=10001111 11000111 11100011 11110001 11111000 01111100 00111110 00011111b0b1b2b3b4b5b6b7+11000110 【例3.2】这里用一个小例子来说明S盒的构造算法。以十六进制的{53}开始,二进制表示为01010011,它表示有限域GF(28)中的元素为 x6+x4+x+1 它在有限域GF(28)中的乘法逆元素为 x7+x6+x3+x 因此,在二进制下有 (b7,b6,b5,b4,b3,b2,b1,b0)=(1,1,0,0,1,0,1,0) 下面计算 b′0=(b0+b4+b5+b6+b7+1) mod 2 =(0+0+0+1+1+1) mod 2 =1 同理,可计算其他位,结果为 (b′0,b′1,b′2,b′3,b′4,b′5,b′6,b′7)=(1,1,1,0,1,1,0,1) 以十六进制表示就是{ED},故S盒中的第5行、第3列中的元素为{ED},即SubBytes({53})={ED}。 2. 行移位变换(ShiftRows) State的第一行保持不变,第二行循环左移1字节,第三行循环左移2字节,第四行移行循环左移3字节,如图3.13所示。 图3.13行移位变换 3. 列混合变换(MixColumns) 列混合变换对State中的每列进行独立的操作,它把每列都看成GF(28)中的一个四项多项式s(x),再与GF(28)上的固定多项式 a(x)={03}x3+{01}x2+{01}x+{02}进行模x4+1的乘法运算。如对第c列(0≤c≤3),其对应的GF(28)中的多项式为sc(x)=s0,c+s1,cx+s2,cx2+s3,cx3,则列混合变换后为s′c(x)=sc(x)a(x)。其矩阵乘法表示如下: s′0,c s′1,c s′2,c s′3,c=02030101 01020301 01010203 03010102s0,c s1,c s2,c s3,c 其中0≤c≤3。 解密变换中涉及的三种基本变换如下。 4. InvSubBytes变换 InvSubBytes变换是字节替换变换(SubBytes)的逆变换,即先用到了仿射变换的逆变换,再计算GF(28)中的乘法逆。逆S盒对状态矩阵中的每字节进行逆变换。InvSubBytes变换可以通过如表3.11所示的逆S盒实现。 表3.11AES解密过程中的逆S盒 Y X 0123456789abcdef 052096ad53036a538bf40a39e81f3d7fb 17ce339829b2fff87348e4344c4dee9cb 续表 Y X 0123456789abcdef 2547b9432a6c2233dee4c950b42fac34e 3082ea16628d924b2765ba2496d8bd125 472f8f66486689816d4a45ccc5d65b692 56c704850fdedb9da5e154657a78d9d84 690d8ab008cbcd30af7e45805b8b34506 7d02c1e8fca3f0f02c1afbd0301138a6b 83a9111414f67dcea97f2cfcef0b4e673 996ac7422e7ad3585e2f937e81c75df6e a47f11a711d29c5896fb7620eaa18be1b bfc563e4bc6d279209adbc0fe78cd5af4 c1fdda8338807c731b11210592780ec5f d60517fa919b54a0d2de57aaf93c99cef ea0e03b4dae2af5b0c8ebbb3c83539961 f172b047eba77d626e169146355210c7d 5. InvShiftRows变换 InvShiftRows变换是行移位变换(ShiftRows)的逆变换,即对状态矩阵的各行按相反的方向进行循环移位操作。因此,状态矩阵各行的移位情况如下: 第一行保持不变; 第二行循环右移1字节; 第三行循环右移2字节; 第四行循环右移3字节。 6. InvMixColumns变换 InvMixColumns变换是列混合变换(MixColumns)的逆变换。InvMixColumns同样逐列处理状态矩阵,它把每一列都当作系数GF(28)有限域上的四项多项式。 与MixColumns变换对应,InvMixColumns变换把列多项式与多项式a(x)相对于模多项式x4+1的逆a-1(x)相乘,即 a-1(x)={0b}·x3+{0d}·x2+{09}·x+{0e} 设列多项式为sc(x)=s0,c+s1,cx+s2,cx2+s3,cx3,0≤c≤3,InvMixColumns变换可改写为如下的矩阵形式: s′0,cs′1,cs′2,cs′3,c=0e0b0d09090e0b0d0d090e0b0b0d090es0,cs1,cs2,cs3,c,0≤c≤3 3.5.4密钥扩展算法 轮密钥是由密钥经过一个扩展算法产生的,其长度由加解密轮数决定,具体地说,轮密钥有(分组长度)×(Nr+1)位。例如,AES128的加解密轮数为10,则轮密钥共有128×(10+1)=1408 位。 密钥扩展算法以一个字(即4字节)为基本单位,其伪代码描述如下: KeyExpansion(byte key[4*Nk], word w[4*(Nr+1)], Nk) // key[]表示初始密钥,w[]表示扩展后的密钥,Nk为密钥长度(以字为单位) { word temp; //扩展密钥的前Nk个字是初始密钥 for (i=0;i< Nk;i++) //把四个单字节按照从高位到低位的顺序表示为一个字 w[i] = (key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]); for(i = Nk; i<4*( Nr+1); i++) { temp = w[i-1]; if (i % Nk == 0) temp = SubWord(RotWord(temp)) ^ Rcon[i/ Nk]; else if(Nk ==8 && (i % Nk == 4)) temp = SubWord(temp); w[i] = w[i - Nk] ^ temp; } } 密钥扩展算法中包括两个函数RotWord和SubWord。RotWord(B0,B1,B2,B3)对输入的4字节进行循环左移操作,即 RotWord(B0,B1,B2,B3)=(B1,B2,B3,B0) SubWord(B0,B1,B2,B3)对输入的4字节分别使用S盒的替换操作SubBytes。Rcon[i]=(RC[i],'00','00','00'),RC[i]的所有可能值(用十六进制表示)如表3.12所示。实际上,RC[i]的值为有限域GF(28)中的多项式xi-1的十六进制表示。 表3.12RC[·] i1234567891011 RC[i]01020408102040801B366c 可以看到,扩展密钥的最前面Nk个字是直接由输入的密钥填充的,而后面的每个字w[i]则主要由前面的字w[i-1]与Nk个位置之前的字w[i- Nk]进行异或运算得到。 3.6国密分组密码算法SM4 3.6.1算法的总体描述 SM4分组密码算法[5]是我国无线局域网标准WAPI中所使用的密码标准,该算法采用非平衡Feistel 结构(一种基本Feistel结构的变种),分组长度为128位,密钥长度为128位。加密算法与密钥扩展算法均采用非线性迭代结构。加密运算和解密运算的算法结构相同,解密运算的轮密钥使用顺序与加密运算相反。 SM4分组密码算法的加密密钥长度为128位,表示为MK=(MK0,MK1,MK2,MK3),其中MKi(i=0,1,2,3)为32位。轮密钥表示为(rk0,rk1,…,rk31),其中rki(i=0,1,…,31)为32位。轮密钥由加密密钥生成。FK=(FK0,FK1,FK2,FK3)为系统参数,CK=(CK0,CK1,…,CK31)为固定参数,用于密钥扩展算法,其中FKi(i=0,1,…,3),CKi(i=0,1,…,31)均为32位。 SM4加密算法由32次迭代运算和1次反序变换R组成。设明文输入为(X0,X1,X2,X3)∈(Z322)4,密文输出为(Y0,Y1,Y2,Y3)∈(Z322)4,轮密钥为rki∈Z322,i=0,1,…,31。加密算法的运算过程如下: (1) 首先执行32次迭代运算: Xi+4=F(Xi,Xi+1,Xi+2,Xi+3,rki),i=0,1,…,31 其中F为轮函数。 (2) 对最后一轮数据进行反序变换如下: (Y0,Y1,Y2,Y3)=R(X32,X33,X34,X35)=(X35,X34,X33,X32) SM4的加密和解密算法的变换结构相同,不同的只有轮密钥的使用顺序,解密时反序使用轮密钥。 轮函数F的细节如下。 设输入为(X0,X1,X2,X3)∈(Z322)4,轮密钥为rk∈Z322,则轮函数F为 F(X0,X1,X2,X3,rk)=X0T(X1X2X3rk) 其中,T: Z322→Z322是一个可逆变换,由非线性变换τ和线性变换L复合而成,即T(·)=L(τ(·))。 非线性变换τ由4 个并行的S盒(见表3.13)构成,设输入为A=(a0,a1,a2,a3)∈(Z82)4,非线性变换τ的输出为B=(b0,b1,b2,b3)∈(Z82)4,即 (b0,b1,b2,b3)=τ(A)=(Sbox(a0),Sbox(a1),Sbox(a2),Sbox(a3)) 表3.13SM4加密过程的S盒 0123456789ABCDEF 0D690E9FECCE13DB716B614C228FB2C05 12B679A762ABE04C3A44132649860699 29C4250F491EF987A33540B43ECFAC62 3E4B31CA9C908E89580DF94F758F3FA6 44707A7FCF37317BA83593C19E6854FA8 5686B81B27164DA8BF8EB0F4B70569D35 61E240E5E6358D1A225227C3B01217887 7D40046579FD327524C3602E7A0C4C89E 8EBF8AD240C738B5A3F7F2CEF96115A1 9E0AE5DA49B341A55A933230F58CB1E3 A1DF6E22E8266CA60C02923AB0534E6F BD5DB3745DEFD8E2F03FF6A7266C5B51 C8D1BA92BBDDBC7F11D95C411F105AD8 D0AC13188A5CD7BBD2D74D012B8E5B4B0 E8969974A0C96777E65B9F109C56EC684 F18F07DEC3ADC4D2079EE5F3EDCB3948 设S盒的输入为EF,则经S盒运算的输出结果为第E行、第F列的值,即Sbox(EF)=0x84。 L是线性变换,非线性变换τ的输出是线性变换L的输入。设输入为B∈Z322,则: C=L(B)=B(B<<<2)(B<<<10)(B<<<18)(B<<<24) 其中,<<