#include "AES.H"
#include <stdio.h>
int BC,KC,ROUNDS;
word32 Rc[30]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36,0x6C,0xD8,0xAB,0x4D,0x9A,0x2F,
0x5E,0xBC,0x63,0xC6,0x97,0x35,0x6A,0xD4,0xB3,0x7D,0xFA,0xEF,0xC5};
word8 mul(word8 a,word8 b)
{
if (a && b)
return Alogtable[(Logtable[a]+Logtable[b])%255];
else
return 0;
}
void AddRoundKey (word8 a[4][MAXBC],word8 rk[4][MAXBC])
{
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<BC;j++)
{
a[i][j]^=rk[i][j];
}
}
}
void SubBytes(word8 a[4][MAXBC],word8 box[256])
{
int i,j;
for(i=0;i<4;i++)
{
for(j=0;j<BC;j++)
{
a[i][j]=box[a[i][j]];
}
}
}
void ShiftRows(word8 a[4][MAXBC],word8 d)
{
word8 tmp[MAXBC];
int i,j;
if (d==0)
{
for(i=1;i<4;i++)
{
for(j=0;j<BC;j++)
tmp[j]=a[i][(j+shifts[BC-4][i])%BC];
for(j=0;j<BC;j++)
a[i][j]=tmp[j];
}
}
else
{
for(i=1;i<4;i++)
{
for(j=0;j<BC;j++)
tmp[j]=a[i][(BC+j-shifts[BC-4][i])%BC];
for(j=0;j<BC;j++)
a[i][j]=tmp[j];
}
}
}
void MixColumns(word8 a[4][MAXBC])
{
word8 b[4][MAXBC];
int i,j;
for (j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
b[i][j]=mul(2,a[i][j])^mul(3,a[(i+1)%4][j])^a[(i+2)%4][j]^a[(i+3)%4][j];
}
}
for(i=0;i<4;i++)
{
for(j=0;j<BC;j++)
{
a[i][j]=b[i][j];
}
}
}
void InvMixCoIumns(word8 a[4][MAXBC])
{
word8 b[4][MAXBC];
int i,j;
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
b[i][j]=mul(0xe,a[i][j])^mul(0xb,a[(i+1)%4][j])^mul(0xd,a[(i+2)%4][j])^mul(0x9,a[(i+3)%4][j]);
}
}
for(i=0;i<4;i++)
{
for(j=0;j<BC;j++)
{
a[i][j]=b[i][j];
}
}
}
int KeyExpansion(word8 k[4][MAXKC],word8 W[MAXROUNDS+1][4][MAXBC])
{
int i,j,t,RCpointer=1;
word8 tk[4][MAXKC];
for(j=0;j<KC;j++)
{
for(i=0;i<4;i++)
{
tk[i][j]=k[i][j];
}
}
t=0;
for(j=0;(j<KC)&&(t<(ROUNDS+1)*BC);j++,t++)
{
for(i=0;i<4;i++)
{
W[t/BC][i][t%BC]=tk[i][j];
}
}
while (t<(ROUNDS+1)*BC)
{
for(i=0;i<4;i++)
{
tk[i][0]^=S[tk[(i+1)%4][KC-1]];
}
tk[0][0]^=Rc[RCpointer++];
if(KC<=6)
for(j=1;j<KC;j++)
{
for(i=0;i<4;i++)
{
tk[i][j]^=tk[i][j-1];
}
}
else
{
for(j=1;j<4;j++)
{
for(i=0;i<4;i++)
{
tk[i][j]^=tk[i][j-1];
}
}
for(i=0;i<4;i++)
tk[i][4]^=S[tk[i][3]];
for(j=5;j<KC;j++)
{
for(i=0;i<4;i++)
{
tk[i][j]^=tk[i][j-1];
}
}
}
for(j=0;(j<KC)&&(t<(ROUNDS+1)*BC);j++,t++)
{
for(i=0;i<4;i++)
{
W[t/BC][i][t%BC]=tk[i][j];
}
}
}
return 0;
}
int Encrypt(word8 a[4][MAXBC],word8 rk[MAXROUNDS+1][4][MAXBC])
{
int r;
AddRoundKey(a,rk[0]);
for(r=1;r<ROUNDS;r++)
{
SubBytes(a,S);
ShiftRows(a,0);
MixColumns(a);
AddRoundKey(a,rk[r]);
}
SubBytes(a,S);
ShiftRows(a,0);
AddRoundKey(a,rk[ROUNDS]);
return 0;
}
int Decrypt(word8 a[4][MAXBC],word8 rk[MAXROUNDS+1][4][MAXBC])
{
int r;
AddRoundKey(a,rk[ROUNDS]);
SubBytes(a,Si);
ShiftRows(a,1);
for(r=ROUNDS-1;r>0;r--)
{
AddRoundKey(a,rk[r]);
InvMixCoIumns(a);
SubBytes(a,Si);
ShiftRows(a,1);
}
AddRoundKey(a,rk[0]);
return 0;
}
int TestEncrypt(word8 a[4][MAXBC],word8 rk[MAXROUNDS+1][4][MAXBC])
{
int r;
int i, j;
AddRoundKey(a,rk[0]);
printf(" ARK-0: ");
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
for(r=1;r<ROUNDS;r++)
{
SubBytes(a,S);
printf(" SB-%d: ",r);
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
ShiftRows(a,0);
printf(" SR-%d: ",r);
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
MixColumns(a);
printf(" MC-%d: ",r);
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
AddRoundKey(a,rk[r]);
printf(" ARK-%d: ",r);
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
}
SubBytes(a,S);
printf(" SB-10: ");
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
ShiftRows(a,0);
printf(" SR-10: ");
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
AddRoundKey(a,rk[ROUNDS]);
printf(" ARK-10: ");
for(j=0;j<BC;j++)
{
for(i=0;i<4;i++)
{
printf("%02X",a[i][j]);
}
}
printf("\n");
return 0;
}