1997年1月,美国标准技术协会NIST开始遴选数据加密标准(Data Encryption Standard,简称DES)替代者的工作,称为高级加密标准[1’2](Advanced Eneryption Stand-ard,简称AES)。同年9月便发布了征集算法的正式公告,用,而且要求AES能在全世界范围内免费得。次年6月提交的21个算法中,有15个满足所有的必备条件并被接纳为AEs的候选算法。经过二轮筛选后,1999年8月公布了五个人围的候选算法:IBM公司提供的 MARS算法、RSA开发的RC6算法、剑桥大学和加利弗尼亚圣地亚哥大学等共同提出的Serpent算法以及因特网安全公司、加利弗尼亚伯克利大学、普林斯顿大学等共同开发的Twofish算法和比利时的两位密码学家设计的Rijndael算法。经过第三轮筛选,Rijndael算法因在安全性、实现代价、实现特性等方面都超过其它算法而得胜。
一:Rijndael算法介绍
AES具有128比特的分组长度,三种可选密钥长度:128比特、192比特和256比特。AES是一个迭代型密码, 轮数Nr依赖于密钥长度,当密钥为128比特时,Nr=10; 当密钥为192比特时,Nr=12;当密钥为256比特时,Nr=14。AES的算法描述如下:
(1)给定一个明文z,将State初始化为x,并进行AddRound—Key操作,将Roundkey与State异或。
(2)对前Nr一1轮中的每一轮,用S盒对进行一次代换操作,称为SubBytes;对State做一置换ShiftRows;再对State做一次操作MixColumns;然后进行AddRoundKey操作。
(3)依次进行SubBytes、ShiftRows和AddRoundKey操作。
(4)将State定义为密文y。
二:Rijndael算法分析
理解AES算法的各种操作是理解AES算法的关键。在AES算法中依次用了AddRoundKey操作、SubBytes操作、ShiftRows操作、MixColumns操作,我们将对这些操作一一进行介绍。
1.AddRoundKey操作
***********************************************************
/* Round key addition function */
void KeyAdd(u8 state[4][4], u8 roundKeys[11][4][4], int round)
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] ^= roundKeys[round][i][j];
return;
}
************************************************************
2.SubBytes操作
***********************************************************
/* Byte substitution transformation */
int ByteSub(u8 state[4][4])
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] = S[state[i][j]];
return 0;
}
***********************************************************
3.ShiftRows操作
***********************************************************
/* Row shift transformation */
void ShiftRow(u8 state[4][4])
{
u8 temp;
/* left rotate row 1 by 1 */
temp = state[1][0];
state[1][0] = state[1][1];
state[1][1] = state[1][2];
state[1][2] = state[1][3];
state[1][3] = temp;
/* left rotate row 2 by 2 */
temp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = temp;
temp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = temp;
/* left rotate row 3 by 3 */
temp = state[3][0];
state[3][0] = state[3][3];
state[3][3] = state[3][2];
state[3][2] = state[3][1];
state[3][1] = temp;
return;
}
***********************************************************
4.MixColumns操作
***********************************************************
/* MixColumn transformation*/
void MixColumn(u8 state[4][4])
{
u8 temp, tmp, tmp0;
int i;
/* do one column at a time */
for (i=0; i<4;i++)
{
temp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i];
tmp0 = state[0][i];
/* Xtime array does multiply by x in GF2^8 */
tmp = Xtime[state[0][i] ^ state[1][i]];
state[0][i] ^= temp ^ tmp;
tmp = Xtime[state[1][i] ^ state[2][i]];
state[1][i] ^= temp ^ tmp;
tmp = Xtime[state[2][i] ^ state[3][i]];
state[2][i] ^= temp ^ tmp;
tmp = Xtime[state[3][i] ^ tmp0];
state[3][i] ^= temp ^ tmp;
}
return;
}
***********************************************************
参考文档:
3GPP TS 35.206