@@ -49,7 +49,7 @@ const unsigned int rCon[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
4949
5050// GF(2^8) multiplication constants to do mix columns
5151const unsigned int mCon [4 ][4 ] = {
52- { 0x02 , 0x02 , 0x01 , 0x01 },
52+ { 0x02 , 0x03 , 0x01 , 0x01 },
5353 { 0x01 , 0x02 , 0x03 , 0x01 },
5454 { 0x01 , 0x01 , 0x02 , 0x03 },
5555 { 0x03 , 0x01 , 0x01 , 0x02 }
@@ -68,16 +68,19 @@ void key_schedule(unsigned int [], unsigned int [][4]);
6868void add_roundkey (unsigned int [][4 ], unsigned int [][4 ], unsigned int [][4 ]);
6969unsigned int sub_byte (unsigned int , unsigned int );
7070void shift_rows (unsigned int [][4 ]);
71-
71+ void mix_columns (unsigned int [][4 ], unsigned int [][4 ]);
72+
7273// secondary functions
7374int hexCharToDec (char );
7475void get2Bytes (unsigned int , unsigned int * , unsigned int * );
7576void getRoundKey (unsigned int [], unsigned int [][4 ], int );
77+ unsigned int gfMul (unsigned int , unsigned int );
7678
7779void printArray (unsigned int [][4 ]);
7880
7981int main (){
8082 /* temporary array values to test functions */
83+
8184 unsigned int state [4 ][4 ] = { // state array
8285 { 0x54 , 0x4f , 0x4e , 0x20 },
8386 { 0x77 , 0x6e , 0x69 , 0x54 },
@@ -100,12 +103,17 @@ int main(){
100103
101104 unsigned int row , column ; // row and column for lookup
102105
103- int i , j ; // counters for loops
106+ int i , j ; // counters for the loops
104107
105108 // we calculate all round keys 1-10
106109 key_schedule (w , roundKey );
107110
108111 /*
112+ // mix columns test
113+ printf("mix columns:\n");
114+ mix_columns(table, state);
115+ printArray(table);
116+
109117 // get round key test
110118 printf("get round key:\n");
111119 for(i = 0; i < 11; i++)
@@ -135,11 +143,11 @@ int main(){
135143return 0 ;
136144}
137145
146+ // this function produces all round keys
138147void key_schedule (unsigned int w [], unsigned int key [][4 ]){
139- int i , j , k ; // counters for loops and used as array "pointers"
140-
141148 unsigned int row , column ; // row and column for lookup
142149 unsigned int temp [4 ]; // temporary holds the results
150+ int i , j , k ; // counters for the loops and used as array "pointers"
143151
144152 // the first round key is the given key
145153 // we store it to the first 4 words
@@ -211,7 +219,7 @@ return;
211219
212220// this function do result = a XOR b
213221void add_roundkey (unsigned int result [][4 ], unsigned int a [][4 ], unsigned int b [][4 ]){
214- int i , j ;
222+ int i , j ; // counters for the loops
215223
216224 for (i = 0 ; i < 4 ; i ++ )
217225 for (j = 0 ; j < 4 ; j ++ )
@@ -261,6 +269,28 @@ void shift_rows(unsigned int state[][4]){
261269return ;
262270}
263271
272+ // this function mix the columns
273+ // state column multiplied with mCon row
274+ // instead of normal multiplication here we do GF(2^8) multiply
275+ // and instead of addition here we do XOR operation
276+ void mix_columns (unsigned int result [][4 ], unsigned int state [][4 ]){
277+ unsigned int sum = 0 ; // we hold the sum here
278+ int i , j , k ; // counters for the loops
279+
280+ for (i = 0 ; i < 4 ; i ++ ){
281+ for (j = 0 ; j < 4 ; j ++ ){
282+ for (k = 0 ; k < 4 ; k ++ ){
283+ sum ^= gfMul (state [k ][i ], mCon [j ][k ]);
284+ }
285+ result [j ][i ] = sum ;
286+ sum = 0 ;
287+ }
288+ }
289+
290+ return ;
291+ }
292+
293+ // this function converts hexadecimal character to integer
264294int hexCharToDec (char hex ){
265295 if (hex >= 48 && hex <= 57 ){ // ascii code for character 1-9
266296 return (hex - '0' ); // as it happens, the ascii value of the characters 1-9 is greater than the value of '0'
@@ -287,6 +317,8 @@ int hexCharToDec(char hex){
287317 }
288318}
289319
320+ // this function returns the integer value of the 2 bytes hex input
321+ // input: xy || row = x and column = y
290322void get2Bytes (unsigned int a , unsigned int * row , unsigned int * column ){
291323 // we need 2 bytes for the hexadecimal value and 1 more for '\0' character
292324 unsigned char temp [3 ];
@@ -322,8 +354,9 @@ void get2Bytes(unsigned int a, unsigned int *row, unsigned int *column){
322354return ;
323355}
324356
357+ // this function return the 16bytes round key
325358void getRoundKey (unsigned int w [], unsigned int roundKey [][4 ], int round ){
326- int i , j ;
359+ int i , j ; // counters for the loops
327360
328361 printf ("Round key %d: " , round );
329362 for (i = (round * 4 ); i < ((round * 4 ) + 4 ); i ++ ){
@@ -342,8 +375,39 @@ void getRoundKey(unsigned int w[], unsigned int roundKey[][4], int round){
342375return ;
343376}
344377
378+ // multiply two numbers in the GF(2^8)
379+ // polynomial: x^8 + x^4 + x^3 + x + 1
380+ // binary: 00011011 || hex: 0x1b
381+ unsigned int gfMul (unsigned int a , unsigned int b ){
382+ unsigned int r = 0 ; // result
383+ unsigned int hi_bit_set ; // high bit
384+ int i ; // counter for the loop
385+
386+ for (i = 0 ; i < 8 ; i ++ ) {
387+ if (b & 1 )
388+ r ^= a ;
389+ hi_bit_set = (a & 0x80 );
390+ a <<= 1 ;
391+
392+ if (hi_bit_set )
393+ a ^= 0x1b ; // x^8 + x^4 + x^3 + x + 1
394+ b >>= 1 ;
395+ }
396+
397+ // if result legnth is more than 8 bits
398+ if (r > 255 && r < 512 )
399+ return r - 256 ;
400+
401+ if (r > 511 )
402+ return r - 512 ;
403+
404+ // if result is max 8 bits
405+ return r ;
406+ }
407+
408+ // this function prints the array
345409void printArray (unsigned int array [][4 ]){
346- int i , j ;
410+ int i , j ; // counters for the loops
347411
348412 for (i = 0 ; i < 4 ; i ++ ){
349413 for (j = 0 ; j < 4 ; j ++ ){
@@ -355,5 +419,3 @@ void printArray(unsigned int array[][4]){
355419
356420return ;
357421}
358-
359-
0 commit comments