#include"AES.h"
static unsigned char x2xtime(unsigned char x)//x乘xtime,有限域*2
{
if(x&0x80)//b7!=0
return (((x<<1)^0x1B)&0xFF);
return x<<1;//b7=0
}
static unsigned char x3xtime(unsigned char x)//x乘xtime,有限域*3
{
return (x2xtime(x)^x);//^为按位异或,x×{03}=x*{02}+x
}
static unsigned char x4xtime(unsigned char x)//x乘xtime,有限域*4
{
return ( x2xtime(x2xtime(x)));
}
static unsigned char x8xtime(unsigned char x)//x乘xtime,有限域*8
{
return (x2xtime(x2xtime(x2xtime(x))));//8:1000
}
static unsigned char x9xtime(unsigned char x)//x乘xtime,有限域*9(逆向列混合时用到)
{
return (x8xtime(x)^x);//1001
}
static unsigned char xBxtime(unsigned char x)//x乘xtime,有限域*B
{
return (x8xtime(x)^x2xtime(x)^x);//B:1011
}
static unsigned char xDxtime(unsigned char x)//x乘xtime,有限域*D
{
return (x8xtime(x)^x4xtime(x)^x);//D:1101
}
static unsigned char xExtime(unsigned char x)//x乘xtime,有限域*E
{
return (x8xtime(x)^x4xtime(x)^x2xtime(x));//E:1110
}
static void ByteSub(unsigned char *s)//S盒变换
{
for(int i=0;i<16;i++)
{
s[i]=sBox[s[i]];
}
}
static void InvByteSub(unsigned char *s)//逆S盒变换
{
for(int i=0;i<16;i++)
s[i]=sBox_Inv[s[i]];
}
static void ShiftRows(unsigned char *raw)//行移位
{
/*
第一行左移0位 |raw[0] raw[4] raw[8] raw[12]| 0 4 8 12
第二行左移1位 |raw[1] raw[5] raw[9] raw[13]| => 5 9 13 1
第三行左移2位 |raw[2] raw[6] raw[10] raw[14]| 10 14 2 6
第四行左移3位 |raw[3] raw[7] raw[11] raw[15]| 15 3 7 11
*/
unsigned char temp;
//第一行左移0位
//第二行左移1位
temp=raw[1];raw[1]=raw[5];raw[5]=raw[9];raw[9]=raw[13];raw[13]=temp;
//第三行左移2位
temp=raw[2];raw[2]=raw[10];raw[10]=temp;
temp=raw[6];raw[6]=raw[14];raw[14]=temp;
//第四行左移3位
temp=raw[15];raw[15]=raw[11];raw[11]=raw[7];raw[7]=raw[3];raw[3]=temp;
}
static void InvShiftRows(unsigned char *raw)//逆向行移位
{
/*
第一行左移0位 |raw[0] raw[4] raw[8] raw[12]| 0 4 8 12
第二行左移3位 |raw[1] raw[5] raw[9] raw[13]| => 13 1 5 9
第三行左移2位 |raw[2] raw[6] raw[10] raw[14]| 10 14 2 6
第四行左移1位 |raw[3] raw[7] raw[11] raw[15]| 7 11 15 3
*/
unsigned char temp;
//第一行左移0位
//第二行左移3位
temp=raw[13];raw[13]=raw[9];raw[9]=raw[5];raw[5]=raw[1];raw[1]=temp;
//第三行左移2位
temp=raw[2];raw[2]=raw[10];raw[10]=temp;
temp=raw[6];raw[6]=raw[14];raw[14]=temp;
//第四行左移1位
temp=raw[3];raw[3]=raw[7];raw[7]=raw[11];raw[11]=raw[15];raw[15]=temp;
}
static void MixColumn(unsigned char *col)//列混合
{
/*
|02 03 01 01|
|01 02 03 01|
|01 01 02 03|
|03 01 01 02|
*/
unsigned char temp[4];
for(int i=0;i<4;i++,col+=4)//col为一列的基地址
{
temp[0]=x2xtime(col[0])^x3xtime(col[1])^col[2]^col[3];//s'(0,j)
temp[1]=col[0]^x2xtime(col[1])^x3xtime(col[2])^col[3];
temp[2]=col[0]^col[1]^x2xtime(col[2])^x3xtime(col[3]);
temp[3]=x3xtime(col[0])^col[1]^col[2]^x2xtime(col[3]);
col[0]=temp[0];//修改原矩阵的列
col[1]=temp[1];
col[2]=temp[2];
col[3]=temp[3];
}
}
static void InvMixColumn(unsigned char *col)//逆向列混合
{
/*
|0E 0B 0D 09|
|09 0R 0B 0D|
|0D 09 0E 0B|
|0B 0D 09 0E|
*/
unsigned char temp[4];
for(int i=0;i<4;i++,col+=4)
{
temp[0]=xExtime(col[0])^xBxtime(col[1])^xDxtime(col[2])^x9xtime(col[3]);
temp[1]=x9xtime(col[0])^xExtime(col[1])^xBxtime(col[2])^xDxtime(col[3]);
temp[2]=xDxtime(col[0])^x9xtime(col[1])^xExtime(col[2])^xBxtime(col[3]);
temp[3]=xBxtime(col[0])^xDxtime(col[1])^x9xtime(col[2])^xExtime(col[3]);
col[0]=temp[0];
col[1]=temp[1];
col[2]=temp[2];
col[3]=temp[3];
}
}
static void AddRoundKey(unsigned char *s,unsigned char *expandKey,int round)//轮密钥加
{
//初始轮密钥加(第0轮),只进行一次轮密钥加;第1-10轮,轮密钥加
for(int i=0;i<16;i++)
s[i]^=expandKey[(round<<4)+i];
}
void KeyExpansion(unsigned char *originKey,unsigned char *expandKey,int Nk,int Nr)//圈密钥生成
{
unsigned char temp[4],temp1;//temp[]代表一个字密钥,temp1=w[i-1](4字节)
for(int i=0;i<(4*Nk);i++)//Nk=4,Nr=10,第0组:[0-3]由用户密钥填充
expandKey[i]=originKey[i];
int i=Nk;
while(i<(4*(Nr+1)))//一次循环生成1个字节扩展密钥
{
for(int j=0;j<4;j++)
temp[j]=expandKey[(4*(i-1))+j];
if(i%Nk==0)//i是4的倍数的时候
{
temp1=temp[0];temp[0]=temp[1];temp[1]=temp[2];temp[2]=temp[3];temp[3]=temp1;//字循环
for(int j=0;j<4;j++)//S盒代换
{
temp[j]=sBox[temp[j]];
}
temp[0]=temp[0]^Rcon[(i/Nk)-1];
}
/*else if(Nk>6&&(i%Nk)==4)//Nk>6时
{
for(int j=0;j<4;j++)
temp[j]=sBox[temp[j]];
}*/
for(int j=0;j<4;j++)
{
expandKey[(4*i)+j]=expandKey[(4*(i-Nk))+j]^temp[j];
}
++i;
}
}
void AesEnc(unsigned char *text,unsigned char *expandKey,int Nr)//AES加密函数
{
//输入Nr=10轮
int round;
AddRoundKey(text,expandKey,0);//初始轮密钥加
for(round=1;round<=(Nr-1);round++)//第1-9轮
{
ByteSub(text);
ShiftRows(text);
MixColumn(text);
AddRoundKey(text,expandKey,round);
}
//第10轮
ByteSub(text);
ShiftRows(text);
AddRoundKey(text,expandKey,round);
}
void AesDec(unsigned char *text,unsigned char *expandKey,int Nr)//AES解密函数
{
AddRoundKey(text,expandKey,Nr);
InvShiftRows(text);
InvByteSub(text);
for(int i=(Nr-1);i>=1;i--)
{
AddRoundKey(text,expandKey,i);
InvMixColumn(text);
InvShiftRows(text);
InvByteSub(text);
}
AddRoundKey(text,expandKey,0);
}