www.pudn.com > AES > AES.CPP


//  This is an imkplementaton of the RIJNDAEL cryptosystem for 128bit plaintext block 
//	This programme only gives the instance of 128 bit key. 
//  You can modify a little details to meet your need for 192 or 256 bit key input  
 
#include "stdio.h" 
 
 
typedef unsigned char u1byte; 
typedef unsigned long u4byte; 
 
#define LARGE_TABLES 
u1byte pow_tab[256]; 
u1byte log_tab[256]; 
u1byte sbx_tab[256]; 
u1byte isb_tab[256]; 
u4byte rco_tab[10]; 
u4byte ft_tab[4][256]; 
u4byte it_tab[4][256]; 
 
#ifdef LARGE_TABLES 
	u4byte fl_tab[4][256]; 
	u4byte il_tab[4][256]; 
#endif; 
 
	u4byte tab_gen=0; 
 
	u4byte k_len; 
	u4byte e_key[60]; 
	u4byte d_key[60]; 
 
#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a]+log_tab[b]) % 255]:0) 
#define byte(x,n)	((u1byte) ((x)>>(8 * n))) 
#define f_rn(bo,bi,n,k)		bo[n] =	ft_tab[0][byte(bi[n],0)]^ft_tab[1][byte(bi[n+1] & 3,1)]^ft_tab[2][byte(bi[n+2] & 3,2)]^ft_tab[3][byte(bi[n+3] & 3,3)]^ * (k+n)  
#define i_rn(bo,bi,n,k)	 	bo[n] =	it_tab[0][byte(bi[n],0)]^it_tab[1][byte(bi[n+3] & 3,1)]^it_tab[2][byte(bi[n+2] & 3,2)]^it_tab[3][byte(bi[n+1] & 3,3)]^ * (k+n)  
#define rotr(x,n) (((x)>>((int)(n)))|((x)<<(32-(int)(n)))) 
#define rotl(x,n) (((x)<<((int)(n)))|((x)>>(32-(int)(n)))) 
 
#ifdef LARGE_TABLES 
#define ls_box(x)			(fl_tab[0][byte(x,0)]^ fl_tab[1][byte(x,1)]	^ fl_tab[2][byte(x,2)]	^ fl_tab[3][byte(x,3)] ) 
 
#define f_rl(bo,bi,n,k)		bo[n]=	fl_tab[0][byte(bi[n],0)]^fl_tab[1][byte(bi[(n+1) & 3],1)]^fl_tab[2][byte(bi[(n+2) & 3],2)]^	fl_tab[3][byte(bi[(n+3) & 3],3)]^ *(k+n) 
#define i_rl(bo,bi,n,k)		bo[n]=	il_tab[0][byte(bi[n],0)]^il_tab[1][byte(bi[(n+1) & 3],1)]^il_tab[2][byte(bi[(n+2) & 3],2)]^	il_tab[3][byte(bi[(n+3) & 3],3)]^ *(k+n) 
 
 
#else 
#define ls_box(x)	((u4byte) sbx_tab[byte(x,0)]<<0)^((u4byte) sbx_tab[byte(x,1)]<<8)^((u4byte) sbx_tab[byte(x,2)]<<16)^((u4byte) sbx_tab[byte(x,3)]<<24) 
 
#define f_rl(bo,bi,n,k)	bo[n]=(u4byte)sbx_tab[byte(bi[n],0)]^rotl(((u4byte)sbx_tab[byte(bi[(n+1) & 3],1)]),8)^rotl(((u4byte)sbx_tab[byte(bi[(n+2) & 3],2)]),16)^rotl(((u4byte)sbx_tab[byte(bi[(n+3) & 3],3)]),24)^*(k+n) 
#define i_rl(bo,bi,n,k)	bo[n]=(u4byte)isb_tab[byte(bi[n],0)]^rotl(((u4byte)isb_tab[byte(bi[(n+3) & 3],1)]),8)^rotl(((u4byte)isb_tab[byte(bi[(n+2) & 3],2)]),16)^rotl(((u4byte)isb_tab[byte(bi[(n+3) & 1],3)]),24)^*(k+n) 
#endif 
 
void gen_tabs(void) 
{	u4byte i,t; 
	u1byte p,q; 
	// log and power tables for GF(2**8) finite with 0x11b as modular polynomail  
	//the simplest primitve root is 0x11,used here to generate the tables 
 
	for(i=0,p=1;i<256;++i) 
	{ 
		pow_tab[i]=(u1byte) p; log_tab[p]=(u1byte) i; 
		p=p^(p<<1)^(p & 0x80? 0x01b : 0); 
	} 
 
	log_tab[1]=0;p=1; 
	for(i=0;i<10;++i) 
	{ 
		rco_tab[i]=p; 
		p=(p<<1)^(p & 0x80 ? 0x1b :0); 
	} 
 
	//note that the affine byte transformation matrix in rijndael specfication is in big endian format with bit 0 
	//as the most significant bit. In the remainder of the specification the bits are numbered from the least significant end of a byte 
 
 
	for(i=0;i<256;++i) 
	{ 
		p=(i?pow_tab[255-log_tab[i]]:0);q=p; 
		q=(q>>7)|(q<<1); p^=q; 
		q=(q>>7)|(q<<1); p^=q; 
		q=(q>>7)|(q<<1); p^=q; 
		q=(q>>7)|(q<<1); p^=q^0x63; 
		sbx_tab[i]=(u1byte) p; isb_tab[p]=(u1byte) i; 
	} 
 
	for(i=0;i<256;++i) 
	{ 
		p=sbx_tab[i]; 
#ifdef  LARGE_TABLES 
		t=p;	fl_tab[0][i]=t; 
		fl_tab[1][i]=rotl(t,8); 
		fl_tab[2][i]=rotl(t,16); 
		fl_tab[3][i]=rotl(t,24); 
#endif 
 
		t=((u4byte)ff_mult(2,p))|((u4byte) p<<8)|((u4byte)p<<16)|((u4byte)ff_mult(3,p)<<24); 
 
		ft_tab[0][i]=t; 
		ft_tab[1][i]=rotl(t,8); 
		ft_tab[2][i]=rotl(t,16); 
		ft_tab[3][i]=rotl(t,24); 
 
		p=isb_tab[i]; 
 
#ifdef  LARGE_TABLES 
		t=p;	il_tab[0][i]=t; 
		il_tab[1][i]=rotl(t,8); 
		il_tab[2][i]=rotl(t,16); 
		il_tab[3][i]=rotl(t,24); 
#endif 
 
		t=((u4byte)ff_mult(14,p))|((u4byte) ff_mult(9,p)<<8)|((u4byte)ff_mult(13,p)<<16)|((u4byte)ff_mult(11,p)<<24); 
 
		it_tab[0][i]=t; 
		it_tab[1][i]=rotl(t,8); 
		it_tab[2][i]=rotl(t,16); 
		it_tab[3][i]=rotl(t,24); 
	} 
 
	tab_gen=1; 
} 
 
#define star_x(x) (((x) & 0x7f7f7f7f)<<1)^((((x) & 0x80808080)>>7) * 0x1b) 
 
#define imix_col(y,x)   u = star_x(x);v = star_x(u);w = star_x(v);t = w^(x); (y) = u ^ v ^ w;	(y)^=rotr(u^t,8)^rotr(v^t,16)^rotr(t,24) 
 
// initialise the key schedule from the user supplied key 
 
#define loop4(i)  {	t  = ls_box(rotr(t,8))^ rco_tab[i];	t ^= e_key[4*i];	e_key[4*i+4]=t;	t ^= e_key[4*i+1];  e_key[4*i+5]=t;	t ^= e_key[4*i+2];  e_key[4*i+6]=t;	t ^= e_key[4*i+3];  e_key[4*i+7]=t;} 
 
#define loop6(i)  {	t  = ls_box(rotr(t,8))^ rco_tab[i];	t ^= e_key[6*i];    e_key[6*i+6]=t;	t ^= e_key[6*i+1];  e_key[6*i+7]=t;	t ^= e_key[6*i+2];  e_key[6*i+8]=t;	t ^= e_key[6*i+3];  e_key[6*i+9]=t;	t ^= e_key[6*i+4];  e_key[6*i+10]=t;	t ^= e_key[6*i+5];  e_key[6*i+11]=t;	} 
 
#define loop8(i)  {	t  = ls_box(rotr(t,8))^ rco_tab[i];	t ^= e_key[8*i];    e_key[8*i+8]=t;	t ^= e_key[8*i+1];  e_key[8*i+9]=t;	t ^= e_key[8*i+2];  e_key[8*i+10]=t;t ^= e_key[8*i+3];  e_key[8*i+11]=t;t ^= e_key[8*i+4];  e_key[8*i+12]=t;	t ^= e_key[8*i+5];  e_key[8*i+13]=t;	t ^= e_key[8*i+6];  e_key[8*i+14]=t;	t ^= e_key[8*i+7];  e_key[8*i+15]=t;	} 
 
 
void set_key(const u4byte in_key[],const u4byte key_len) 
{ 
	u4byte i,t,u,v,w; 
 
	if(!tab_gen) gen_tabs(); 
 
	k_len = (key_len + 31)/32; 
 
	e_key[0]=in_key[0]; e_key[1] = in_key[1]; 
	e_key[2]=in_key[2]; e_key[3] = in_key[3]; 
 
	switch(k_len) 
	{ 
	case 4: t = e_key[3]; 
			for(i=0;i<10;i++) 
				loop4(i); 
			break; 
	case 6: e_key[4] = in_key[4] ; t = e_key[5] = in_key[5]; 
			for(i=0;i<8;i++) 
			loop6(i); 
			break; 
	case 8: e_key[4]=in_key[4]; e_key[5]=in_key[5]; 
			e_key[6]=in_key[6]; t=e_key[7]=in_key[7]; 
			for(i=0;i<7;++i) 
				loop8(i); 
			break; 
	} 
 
	d_key[0]=e_key[0]; d_key[1]=e_key[1]; 
	d_key[2]=e_key[2]; d_key[3]=e_key[3]; 
 
	for(i=4;i<4*k_len+24;++i) 
	{ 
		imix_col(d_key[i],e_key[i]); 
	} 
 
} 
 
//encrypt a block of test 
 
#define f_nround(bo,bi,k)	f_rn(bo,bi,0,k);	f_rn(bo,bi,1,k);	f_rn(bo,bi,2,k);	f_rn(bo,bi,3,k);	k+=4 
 
#define f_lround(bo,bi,k)	f_rl(bo,bi,0,k);	f_rl(bo,bi,1,k);	f_rl(bo,bi,2,k);	f_rl(bo,bi,3,k)	 
 
void encrypt(const u4byte in_blk[4],u4byte out_blk[4]) 
{ 
	u4byte b0[4],b1[4],*kp; 
 
	b0[0]=in_blk[0]^e_key[0]; b0[1]=in_blk[1]^e_key[1]; 
	b0[2]=in_blk[2]^e_key[2]; b0[3]=in_blk[3]^e_key[3]; 
 
	kp=e_key +4; 
	 
	if(k_len>6) 
	{ 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
	} 
 
	if(k_len>4) 
	{ 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
	} 
 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
		f_nround(b1,b0,kp); f_nround(b0,b1,kp); 
 
		out_blk[0]=b0[0]; out_blk[1]=b0[1]; 
		out_blk[2]=b0[2]; out_blk[3]=b0[3]; 
} 
 
 
//decrypt a block of text 
 
#define i_nround(bo,bi,k)	i_rn(bo,bi,0,k);	i_rn(bo,bi,1,k);	i_rn(bo,bi,2,k);	i_rn(bo,bi,3,k);	k-=4 
 
#define i_lround(bo,bi,k)	i_rl(bo,bi,0,k);	i_rl(bo,bi,1,k);	i_rl(bo,bi,2,k);	i_rl(bo,bi,3,k); 
 
void decrypt(const u4byte in_blk[4],u4byte out_blk[4]) 
{ 
	u4byte b0[4],b1[4],*kp; 
 
	b0[0]=in_blk[0]^e_key[4*k_len+24]; 
	b0[1]=in_blk[1]^e_key[4*k_len+25]; 
	b0[2]=in_blk[2]^e_key[4*k_len+26]; 
	b0[3]=in_blk[3]^e_key[4*k_len+27]; 
 
	kp=d_key+4*(k_len+5); 
 
	if(k_len>6)  
	{ 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
	} 
 
	if(k_len>4)  
	{ 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
	} 
 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
		i_nround(b1,b0,kp); i_nround(b0,b1,kp); 
 
		out_blk[0]=b0[0];out_blk[1]=b0[1]; 
		out_blk[2]=b0[2];out_blk[3]=b0[3]; 
} 
 
//use data to test programme 
 
void main() 
{ 
 
 
	int i; 
	u4byte out_block[4]; 
	const u4byte in_key[4]={0x11111111,0x22222222,0x33333333,0x44444444}; 
	const u4byte plain_block[4]={0x12121212,0x34343434,0x45454545,0x56565656}; 
	const u4byte cipher_block[4]={0x844050f7,0xe346a4ff,0x375104da,0xabb97f8b}; 
 
	printf("--------------------------------------------------\n"); 
 
	set_key(in_key,128); 
 
	encrypt(plain_block,out_block); 
	printf("\nencryption :\n"); 
	for(i=0;i<4;i++) printf("%x ",out_block[i]); 
 
	decrypt(cipher_block,out_block); 
 
	printf("\nDencryption :\n"); 
	for(i=0;i<4;i++) printf("%x ",out_block[i]); 
		printf("\n\n"); 
	printf("--------------------------------------------------\n"); 
	 
 
}