//AES解密程序,将code得到的加密矩阵进行解密,得到原始矩阵
#include<stdio.h>
#include<math.h>
//#include<conio.h>
#define A 10
#define B 11
#define C 12
#define D 13
#define E 14
#define F 15
#define N 10
#define Nb 4
#define Nk 4
int SearchSbox(int info);
void InvByteSub(int (*pinfo)[Nb]);
void InvShiftRow(int (*pinfo)[Nb]);
void InvMixColumn(int (*pinfo)[Nb]);
void InvAddRoundKey(int (*pinfo)[Nb],int (*pRoundKey)[N*Nb+Nb],int round);
void KeyExpansion(int (*Key_Original)[Nk],int (*RoundKey)[N*Nb+Nb]);
int SearchInvSbox(int info);
int upper_sbox[16][16]={{6,7,7,7,F,6,6,C,3,0,6,2,F,D,A,7},
{C,8,C,7,F,5,4,F,A,D,A,A,9,A,7,C},
{B,F,9,2,3,3,F,C,3,A,E,F,7,D,3,1},
{0,C,2,C,1,9,0,9,0,1,8,E,E,2,B,7},
{0,8,2,1,1,6,5,A,5,3,D,B,2,E,2,8},
{5,D,0,E,2,F,B,5,6,C,B,3,4,4,5,C},
{D,E,A,F,4,4,3,8,4,F,0,7,5,3,9,A},
{5,A,4,8,9,9,3,F,B,B,D,2,1,F,F,D},
{C,0,1,E,5,9,4,1,C,A,7,3,6,5,1,7},
{6,8,4,D,2,2,9,8,4,E,B,1,D,5,0,D},
{E,3,3,0,4,0,2,5,C,D,A,6,9,9,E,7},
{E,C,3,6,8,D,4,A,6,5,F,E,6,7,A,0},
{B,7,2,2,1,A,B,C,E,D,7,1,4,B,8,8},
{7,3,B,6,4,0,F,0,6,3,5,B,8,C,1,9},
{E,C,3,6,8,D,4,A,6,5,F,E,6,7,A,0},
{8,A,8,0,B,E,4,6,4,9,2,0,B,5,B,1}};
int lower_sbox[16][16]={{3,C,7,B,2,B,F,5,0,1,7,B,E,7,B,6},
{A,2,9,D,A,9,7,0,D,4,2,F,C,4,2,0},
{7,D,3,6,6,F,7,C,4,5,5,1,1,8,1,5},
{4,7,3,3,8,6,5,A,7,2,0,2,E,7,2,5},
{9,3,C,A,B,E,A,0,2,B,6,3,9,3,F,4},
{3,1,0,D,0,C,1,B,A,B,E,9,A,C,8,F},
{0,F,A,B,3,D,3,5,5,9,2,F,0,C,F,8},
{1,3,0,F,2,D,8,5,C,6,A,1,0,F,3,2},
{D,C,3,C,F,7,4,7,4,7,E,D,4,D,9,3},
{0,1,F,C,2,A,0,8,6,E,8,4,E,E,B,B},
{0,2,A,A,9,6,4,C,2,3,C,2,1,5,4,9},
{7,8,7,D,D,5,E,9,C,6,4,A,5,A,E,8},
{A,8,5,E,C,6,4,6,8,D,4,F,B,D,B,A},
{0,E,5,6,8,3,6,E,1,5,7,9,6,1,D,E},
{1,8,8,1,9,9,E,4,B,E,7,9,E,5,8,F},
{C,1,9,D,B,6,2,8,1,9,D,F,0,4,B,6}};
int Invupper_sbox[16][16]={{5,0,6,D,3,3,A,3,B,4,A,9,8,F,D,F},
{7,E,3,8,9,2,F,8,3,8,4,4,C,D,E,C},
{5,7,9,3,A,C,2,3,E,4,9,0,4,F,C,4},
{0,2,A,6,2,D,2,B,7,5,A,4,6,8,D,2},
{7,F,F,6,8,6,9,1,D,A,5,C,5,6,B,9},
{6,7,4,5,F,E,B,D,5,1,4,5,A,8,9,8},
{9,D,A,0,8,B,D,0,F,E,5,0,B,B,4,0},
{D,2,1,8,C,3,0,0,C,A,B,0,0,1,8,6},
{3,9,1,4,4,6,D,E,9,F,C,C,F,B,E,7},
{9,A,7,2,E,A,3,8,E,F,3,E,1,7,D,6},
{4,F,1,7,1,2,C,8,6,B,6,0,A,1,B,1},
{F,5,3,4,C,D,7,2,9,D,C,F,7,C,5,F},
{1,D,A,3,8,0,C,3,B,1,1,5,2,8,E,5},
{6,5,7,A,1,B,4,0,2,E,7,9,9,C,9,E},
{A,E,3,4,A,2,F,B,C,E,B,3,8,5,9,6},
{1,2,0,7,B,7,D,2,E,6,1,6,5,2,0,7}};
int Invlower_sbox[16][16]={{2,9,A,5,0,6,5,8,F,0,3,E,1,3,7,B},
{C,3,9,2,B,F,F,7,4,E,3,4,4,E,9,B},
{4,B,4,2,6,2,3,D,E,C,5,B,2,A,3,E},
{8,E,1,6,8,9,4,2,6,B,2,9,D,B,1,5},
{2,8,6,4,6,8,8,6,4,4,C,C,D,5,6,2},
{C,0,8,0,D,D,9,A,E,5,6,7,7,D,D,4},
{0,8,B,0,C,C,3,A,7,4,8,5,8,3,5,6},
{0,C,E,F,A,F,F,2,1,F,D,3,1,3,A,B},
{A,1,1,1,F,7,C,A,7,2,F,E,0,4,6,3},
{6,C,4,2,7,D,5,5,2,9,7,8,C,5,F,E},
{7,1,A,1,D,9,5,9,F,7,2,E,A,8,E,B},
{C,6,E,B,6,2,9,0,A,B,0,E,8,D,A,4},
{F,D,8,3,8,7,7,1,1,2,0,9,7,0,C,F},
{0,1,F,9,9,5,A,D,D,5,A,F,3,9,C,F},
{0,0,B,D,E,A,5,0,8,B,B,C,3,3,9,1},
{7,B,4,E,A,7,6,6,1,9,4,3,5,1,C,D}};
void main()
{int info[4][Nb]={{10,65,241,198},
{148,110,195,83},
{11,240,148,234},
{181,69,88,90}};
int round=N;
int Key_Original[4][Nk]={{0,4,8,12},
{1,5,9,13},
{2,6,10,14},
{3,7,11,15}};
int RoundKey[4][N*Nb+Nb];
int i,j;
KeyExpansion(Key_Original,RoundKey);
InvAddRoundKey(info,RoundKey,round);
InvShiftRow(info);
InvByteSub(info);
for(round=N-1;round>0;round--)
{InvAddRoundKey(info,RoundKey,round);
InvMixColumn(info);
InvShiftRow(info);
InvByteSub(info);
}
InvAddRoundKey(info,RoundKey,round);
for(i=0;i<4;i++)
{for(j=0;j<Nb;j++)
printf(" %d ",info[i][j]);
printf("\n");
}
// getch();
}
void InvByteSub(int (*pinfo)[Nb])
{int i,j;
for(i=0;i<4;i++)
for(j=0;j<Nb;j++)
*(*(pinfo+i)+j)=SearchInvSbox(*(*(pinfo+i)+j));
}
int SearchInvSbox(int info)
{int tens,ones,temp_tens,temp_ones;
tens=info/16;
ones=info%16;
temp_tens=Invupper_sbox[tens][ones];
temp_ones=Invlower_sbox[tens][ones];
info=temp_tens*16+temp_ones;
return (info);
}
void InvShiftRow(int (*pinfo)[Nb])
{int temp;
int i,j,k;
for(i=0;i<4;i++)
for(j=0;j<i;j++)
{temp=*(*(pinfo+i)+Nb-1);
for(k=Nb-1;k>0;k--)
*(*(pinfo+i)+k)=*(*(pinfo+i)+k-1);
*(*(pinfo+i)+0)=temp;
}
}
void InvMixColumn(int (*pinfo)[Nb])
{int j,k;
int sum=0;
int a0[8],a1[8],a2[8],a3[8];
int b0[8],b1[8],b2[8],b3[8];
for(j=0;j<Nb;j++)
{for(k=0;k<8;k++)
{a0[k]=(*(*(pinfo+0)+j)/(int)pow(2,7-k))%2;
a1[k]=(*(*(pinfo+1)+j)/(int)pow(2,7-k))%2;
a2[k]=(*(*(pinfo+2)+j)/(int)pow(2,7-k))%2;
a3[k]=(*(*(pinfo+3)+j)/(int)pow(2,7-k))%2;
}
b0[0]=a0[1]+a0[2]+a0[3]+a1[0]+a1[1]+a1[3]+a2[0]+a2[2]+a2[3]+a3[0]+a3[3];
b0[1]=a0[0]+a0[2]+a0[3]+a0[4]+a1[0]+a1[1]+a1[2]+a1[4]+a2[0]+a2[1]+a2[3]+a2[4]
+a3[0]+a3[1]+a3[4];
b0[2]=a0[1]+a0[3]+a0[4]+a0[5]+a1[0]+a1[1]+a1[2]+a1[3]+a1[5]+a2[1]+a2[2]+a2[4]
+a2[5]+a3[0]+a3[1]+a3[2]+a3[5];
b0[3]=a0[2]+a0[4]+a0[5]+a0[6]+a1[0]+a1[1]+a1[2]+a1[3]+a1[4]+a1[6]+a2[0]+a2[2]
+a2[3]+a2[5]+a2[6]+a3[1]+a3[2]+a3[3]+a3[6];
b0[4]=a0[1]+a0[2]+a0[5]+a0[6]+a0[7]+a1[2]+a1[4]+a1[5]+a1[7]+a2[0]+a2[1]+a2[2]
+a2[4]+a2[6]+a2[7]+a3[0]+a3[2]+a3[4]+a3[7];
b0[5]=a0[1]+a0[6]+a0[7]+a1[0]+a1[1]+a1[5]+a1[6]+a2[1]+a2[5]+a2[7]+a3[0]+a3[1]
+a3[5];
b0[6]=a0[2]+a0[7]+a1[0]+a1[1]+a1[2]+a1[6]+a1[7]+a2[0]+a2[2]+a2[6]+a3[1]+a3[2]
+a3[6];
b0[7]=a0[0]+a0[1]+a0[2]+a1[0]+a1[2]+a1[7]+a2[1]+a2[2]+a2[7]+a3[2]+a3[7];
b1[0]=a1[1]+a1[2]+a1[3]+a2[0]+a2[1]+a2[3]+a3[0]+a3[2]+a3[3]+a0[0]+a0[3];
b1[1]=a1[0]+a1[2]+a1[3]+a1[4]+a2[0]+a2[1]+a2[2]+a2[4]+a3[0]+a3[1]+a3[3]+a3[4]
+a0[0]+a0[1]+a0[4];
b1[2]=a1[1]+a1[3]+a1[4]+a1[5]+a2[0]+a2[1]+a2[2]+a2[3]+a2[5]+a3[1]+a3[2]+a3[4]
+a3[5]+a0[0]+a0[1]+a0[2]+a0[5];
b1[3]=a1[2]+a1[4]+a1[5]+a1[6]+a2[0]+a2[1]+a2[2]+a2[3]+a2[4]+a2[6]+a3[0]+a3[2]
+a3[3]+a3[5]+a3[6]+a0[1]+a0[2]+a0[3]+a0[6];
b1[4]=a1[1]+a1[2]+a1[5]+a1[6]+a1[7]+a2[2]+a2[4]+a2[5]+a2[7]+a3[0]+a3[1]+a3[2]
+a3[4]+a3[6]+a3[7]+a0[0]+a0[2]+a0[4]+a0[7];
b1[5]=a1[1]+a1[6]+a1[7]+a2[0]+a2[1]+a2[5]+a2[6]+a3[1]+a3[5]+a3[7]+a0[0]+a0[1]
+a0[5];
b1[6]=a1[2]+a1[7]+a2[0]+a2[1]+a2[2]+a2[6]+a2[7]+a3[0]+a3[2]+a3[6]+a0[1]+a0[2]
+a0[6];
b1[7]=a1[0]+