AES算法汇总.docx
- 文档编号:27134066
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:39
- 大小:197.89KB
AES算法汇总.docx
《AES算法汇总.docx》由会员分享,可在线阅读,更多相关《AES算法汇总.docx(39页珍藏版)》请在冰豆网上搜索。
AES算法汇总
AES算法
AES算法关键模块设计:
1、自定义函数库
2、秘钥扩展模块
3、轮函数模块
对着三个模块进行分析:
1、自定义函数库
(1)、Xtime、X2time、X3time函数设计
在AES算法中,需要用到乘法运算Xtime、X2time、X3time分别为GF(
)上的乘02、04、08运算,可以将其设计成函数,写入自定义库中,在需要时直接进行调用。
(2)、S盒设计
在AES算法的秘钥扩展和加密过程中用到了字节代替变换,即S盒,在解密时,用到了字节代替变换求逆S盒。
2、秘钥扩展
AES秘钥长度分别为128,192,256位,每一轮都需要一个与输入分组具有相同长度的扩展密钥。
扩展密钥包括三个步骤:
(1)、位置变换(rotword):
接受一个4字节的数组并将它们向左旋转一个位置
(2)、S盒变换(subword):
用替换表S盒对给定的一行密钥调度表w[](扩展后的秘钥)进行逐字节代换
(3)、变换Rcon[i]:
轮常数表的数组Rcon[i],这些常数都是4个字节,每个常数与秘钥调度表的某一行相匹配,AES的秘钥扩展例程需要11个轮常数。
3、轮函数
AES算法的加密和解密轮函数并不一致,加密过程轮函数包括字节代换(ByteSubstitute)、行位移(ShiftRow)、列混合(MixColumn)和轮密钥加(RoundKey),解密过程包括行位移(ShiftRow)求逆、字节代换(ByteSubstitute)求逆、轮密钥加(RoundKey)和列混合(MixColumn)求逆,因此需要设计不同的轮函数。
同时,在加密过程中第10轮没有列混合操作,解密过程中第10轮没有列混合求逆操作。
C语言代码:
#include
#include
#include
#include
unsignedcharexpandedkey[176],state[4][4],temp[4][4],decexpandedkey[176],key[4][4];//将状态矩阵与轮密钥设置为全局变量
unsignedcharcipherkey[16]={43,126,21,22,40,174,210,166,171,247,21,136,9,207,79,60};
unsignedcharsbox[256];
unsignedchartemp1,temp2,temp3,temp4,temp5;
unsignedcharM[8][8]={{1,0,0,0,1,1,1,1},{1,1,0,0,0,1,1,1},{1,1,1,0,0,0,1,1},{1,1,1,1,0,0,0,1},
{1,1,1,1,1,0,0,0},{0,1,1,1,1,1,0,0},{0,0,1,1,1,1,1,0},{0,0,0,1,1,1,1,1}};
unsignedcharP[8][8]={{0,0,1,0,0,1,0,1},{1,0,0,1,0,0,1,0},{0,1,0,0,1,0,0,1},{1,0,1,0,0,1,0,0},
{0,1,0,1,0,0,1,0},{0,0,1,0,1,0,0,1},{1,0,0,1,0,1,0,0},{0,1,0,0,1,0,1,0}};
/********************加密部分所用到的函数***********************/
voidKeyExpansion(unsignedcharcipherkey[16],unsignedcharenpandedkey[176]);
voidRoundKeyAddition(unsignedchar[4][4],unsignedchar[4][4]);
voidByteSub(unsignedcharstate[4][4]),ShiftRow(unsignedcharstate[4][4]);
voidSbox(constunsignedchar);
voidRotSub(unsignedchartemp[4]);
voidMixColumn(unsignedcharstate[4][4]);
unsignedcharXtime(unsignedchar,unsignedchar);
voidTransPose(unsignedcharstate[4][4]);
/*******************解密部分所用到的函数**********************/
voidinvsubyte(unsignedcharstate[4][4]);
voidInvShiftRow(unsignedchar[4][4]);
voidInvMixColumn(unsignedcharstate[4][4]);
unsignedcharXtime1(unsignedchar,unsignedchar);
voidXtime2(unsignedchar);
voidmain()
{
inti,j,k,l;
unsignedcharb;
unsignedcharexpandedkey1[16],temp[4][4];
constunsignedchara=3;//定义有限域[2^8]的字符型常量生成元
unsignedcharstate[4][4]={{50,67,246,168},{136,90,48,141},{49,49,152,162},{224,55,7,52}};
FILE*fp1;
TransPose(state);
printf("ThematrixofInitialstateis:
\n");
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(state[i][j]<16)
printf("0%x",state[i][j]);//以十六进制形式输出字符型数据
else
printf("%x",state[i][j]);
}
printf("\n");
}
printf("\n");
Sbox(a);//调用Sbox函数来获取S盒表
printf("TheelementsofS-boxthatweobtainedis:
\n");
for(i=0;i<256;i++)
{
if(sbox[i]<16)
printf("0%x",sbox[i]);
else
printf("%x",sbox[i]);
if(((i+1)%16==0)&&(i!
=0))
printf("\n");
}
printf("\n");
KeyExpansion(cipherkey,expandedkey);//通过函数调用,密钥扩展获取扩展密钥
/**********输出密钥扩展后的扩展密钥***************/
printf("Thesequenceofexpandedkeyis:
\n");
for(i=0;i<176;i++)
{
if(expandedkey[i]<16)
printf("0%x",expandedkey[i]);
else
printf("%x",expandedkey[i]);
}
printf("\n\n");
/************取出expandedkey[176]的前16个元素****************/
for(i=0;i<16;i++)
expandedkey1[i]=expandedkey[i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
temp[i][j]=expandedkey1[i+4*j];
RoundKeyAddition(state,temp);//函数调用,第一轮的初始轮密钥加
printf("Thematrixofstateafterroundkeyadditionis:
\n");
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(state[i][j]<16)
printf("0%x",state[i][j]);
else
printf("%x",state[i][j]);
}
printf("\n");
}
/***********进行轮变换**************/
for(i=1;i<10;i++)
{
ByteSub(state);
ShiftRow(state);
MixColumn(state);
for(j=0;j<16;j++)
expandedkey1[j]=expandedkey[16*i+j];
for(j=0;j<4;j++)
for(k=0;k<4;k++)
temp[j][k]=expandedkey[j+4*k];
fp1=fopen("Temporary.txt","w");
for(j=0;j<16;j++)
{
if(expandedkey1[j]<16)
fprintf(fp1,"0%x",expandedkey1[j]);
else
fprintf(fp1,"%x",expandedkey1[j]);
}
fclose(fp1);
fp1=fopen("Temporary.txt","r");
for(k=0;k<4;k++)
for(l=0;l<4;l++)
if(fscanf(fp1,"%x",&b)!
='\n')
temp[k][l]=b;
fclose(fp1);
TransPose(temp);
RoundKeyAddition(state,temp);
printf("Thematrixofstateafterroundkeyadditionis:
\n");
for(j=0;j<4;j++)
{
for(k=0;k<4;k++)
{
if(state[j][k]<16)
printf("0%x",state[j][k]);
else
printf("%x",state[j][k]);
}
printf("\n");
}
}
printf("\n");
/**********最后一轮的轮运算***********/
ByteSub(state);
ShiftRow(state);
for(i=0;i<16;i++)
expandedkey1[i]=expandedkey[160+i];
fp1=fopen("Temporary.txt","w");
for(i=0;i<16;i++)
{
if(expandedkey1[i]<16)
fprintf(fp1,"0%x",expandedkey1[i]);
else
fprintf(fp1,"%x",expandedkey1[i]);
}
fclose(fp1);
fp1=fopen("Temporary.txt","r");
for(j=0;j<4;j++)
for(k=0;k<4;k++)
if(fscanf(fp1,"%x",&b)!
='\n')
temp[j][k]=b;
fclose(fp1);
TransPose(temp);
RoundKeyAddition(state,temp);
printf("ThematrixofstateafterEncryptionis:
\n");
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(state[i][j]<16)
printf("0%x",state[i][j]);
else
printf("%x",state[i][j]);
}
printf("\n");
}
printf("\n");
/**********************Rijndael算法解密部分********************/
for(i=0;i<16;i++)
expandedkey1[i]=expandedkey[160+i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
temp[i][j]=expandedkey1[i+4*j];//将一维数组转换成矩阵的形式
RoundKeyAddition(state,temp);//初始轮密钥加函数调用
for(i=9;i>0;i--)
{
InvShiftRow(state);
invsubyte(state);
for(j=0;j<16;j++)
expandedkey1[j]=expandedkey[16*i+j];
for(j=0;j<4;j++)
for(k=0;k<4;k++)
temp[j][k]=expandedkey1[j+4*k];
RoundKeyAddition(state,temp);
InvMixColumn(state);
}
InvShiftRow(state);
invsubyte(state);
for(i=0;i<16;i++)
expandedkey1[i]=expandedkey[i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
temp[i][j]=expandedkey1[i+4*j];
RoundKeyAddition(state,temp);
printf("ThematrixofstateafterDecryptionis:
\n");
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(state[i][j]<16)
printf("0%x",state[i][j]);
else
printf("%x",state[i][j]);
}
printf("\n");
}
}
/**************矩阵转置***************/
voidTransPose(unsignedchartemp[4][4])
{
inti,j;
unsignedchartemp1[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
temp1[i][j]=temp[j][i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
temp[i][j]=temp1[i][j];
}
/**************构造S盒*********************/
voidSbox(constunsignedchara)
{
inti;
sbox[0]=1;
for(i=1;i<256;i++)
{
inttemp=0;
sbox[i]=sbox[i-1]*1;
if(sbox[i-1]<128)
{
temp=sbox[i];
sbox[i]^=(temp<<1);
}
elseif(sbox[i-1]>=128&&sbox[i-1]<256)
{
temp=sbox[i];
sbox[i]^=(temp<<1);
temp=sbox[i]+256;
}
if(temp>=256)
sbox[i]=temp^283;
}
}
/**************密钥扩展功能模块*************/
voidKeyExpansion(unsignedcharcipherkey[16],unsignedcharexpandedkey[176])
{
inti,j,k,l;
staticunsignedchartemp[4];
unsignedcharRcon[4]={1,0,0,0};
for(i=0;i<16;i++)
expandedkey[i]=cipherkey[i];
for(i=16;i<176;i+=16)
{
for(l=0;l<4;l++)
temp[l]=expandedkey[i-4+l];//四个字节一组进行移位字节替换运算
RotSub(temp);//函数调用,进行循环左移然后字节替换
for(l=0;l<4;l++)
temp[l]^=expandedkey[i-16+l];//与前一块的首字的四个字节进行异或运算
/**********将与前一块首字异或的结果与每一轮轮常数进行异或*************/
Rcon[0]<<=((i/16)-1);//对每一次循环的Rcon[0]进行重新计算
if((i/16)>8)
Rcon[0]=27<<((i/16)-9);//对于i/16大于8之后的数用x^4+x^3+x+1来代替x^8
for(l=1;l<4;l++)
Rcon[l]=0;
for(l=0;l<4;l++)
temp[l]^=Rcon[l];
Rcon[0]=1;
for(j=0;j<4;j++)
expandedkey[i+j]=temp[j];//获取4个字为一块的首字
for(l=0;l<4;l++)
temp[l]=0;//对暂存字节的临时数组重新置零
for(k=i+4;k<(i+16);k++)
expandedkey[k]=expandedkey[k-4]^expandedkey[k-16];
}
}
/************循环左移字节替换模块**************/
voidRotSub(unsignedchartemp[4])
{
inti,j,k;
unsignedchara=0;
unsignedcharc=0;
staticunsignedchartemp1[8],temp5[4];
unsignedchartemp2[4][8],temp3[8][4],temp4[8][4];
unsignedcharN[8][4]={{1,1,1,1},{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,1,1,1},{1,1,1,1},{0,0,0,0}};
FILE*fp4;
fp4=fopen("d.txt","w");
/***********左循环一个字节***************/
unsignedcharb=temp[0];
for(i=0;i<3;i++)
temp[i]=temp[(i+1)%4];//一个字中的四个字节进行循环左移
temp[3]=b;
for(i=0;i<4;i++)
for(j=0;j<256;j++)
if(temp[i]==sbox[j])
{
temp[i]=sbox[255-j];//将循环移位之后的一个字中的四个字节进行取逆运算
break;
}
/***********仿射运算*************/
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
temp1[j]=temp[i]%2;//将状态矩阵中的逆元素转换成二进制形式
temp[i]/=2;
if(temp[i]==0)
{
k=j;
break;
}
}
for(k=j+1;k<8;k++)
temp1[k]=0;
for(j=0;j<8;j++)
fprintf(fp4,"%d",temp1[j]);
fprintf(fp4,"\n");
}
fclose(fp4);
fp4=fopen("d.txt","r");
for(i=0;i<4;i++)
for(j=0;j<8;j++)
if(fscanf(fp4,"%d",&a)!
='\n')
temp2[i][j]=a;
fclose(fp4);
for(i=0;i<8;i++)
for(j=0;j<4;j++)
temp3[i][j]=temp2[j][i];
for(i=0;i<8;i++)
for(j=0;j<4;j++)
{
for(k=0;k<8;k++)
{
c+=M[i][k]*temp3[k][j];
}
temp4[i][j]=c%2;
c=0;
}
for(i=0;i<8;i++)
for(j=0;j<4;j++)
temp4[i][j]^=N[i][j];
for(i=0;i<4;i++)
for(j=0;j<8;j++)
temp2[i][j]=temp4[j][i];
for(i=0;i<4;i++)
for(j=0;j<8;j++)
temp5[i]+=temp2[i][j]< for(i=0;i<4;i++) temp[i]=temp5[i]; for(i=0;i<4;i++) temp5[i]=0; } /********************************************字节替换***********************************/ voidByteSub(unsignedcharstate[4][4]) { inti,j,k,l; staticunsignedchartemp[8],temp6[16];//temp[8]是用来存放将十六进制数转换成二进制数的二进制序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AES 算法 汇总