Hello

Im slowly trying to write a AES program but I cant seem to get the MC part to work.

The code compiles fine, but if you apply the inverse to the function you dont get the orginal back *most* but not all of them time.

I have no idea why.

Anyone mind taking a look?
Thanks

Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

unsigned char gf_mult(unsigned char a, unsigned char b) {
	int i;
	int retval;
	
	/* If there isnt a "overflow", normal multiplication can be used */
	retval = a * b;
	if(retval < 128)
		return retval;
	else 
		retval = 0;
	
	/* GF multiplication with insane bit shifting */
	for(i = 0; i < 8; i++) {
		if((b & 1) == 1) 
			retval ^= a;
		
		if((a & 0x80) == 0x80) {
			a <<= 1;
			a  ^= 0x1b;
		} else {
			a <<= 1;
		}
		
		b >>= 1;
	}
	
	return (unsigned char)retval;
}

void print_state(unsigned char *state) {
	int i;
	int j;
	
	printf("+----+----+----+----+\n");
	
	for(i = 0; i < 4; ++i) {
		printf("|");
		
		for(j = 0; j < 4; ++j)
			printf("0x%02X|", (&state[i])[j]);
		
		printf("\n");
		printf("+----+----+----+----+\n");
	}
}

void rand_state(unsigned char *state) {
	int i;
	int j;
	
	srand ( time(NULL) );
	for(i = 0; i < 4; ++i) {
		for(j = 0; j < 4; ++j)
			(&state[i])[j] = (rand() % 256);
	}
}

void copy_state(unsigned char *src, unsigned char *dst) {
	int i;
	int j;
	
	for(i = 0; i < 4; ++i) {
		for(j = 0; j < 4; ++j)
			(&dst[i])[j] = (&src[i])[j];
	}
}

int state_equal(unsigned char *a, unsigned char *b) {
	int i;
	int j;
	
	for(i = 0; i < 4; ++i) {
		for(j = 0; j < 4; ++j) {
			if( (&a[i])[j] != (&b[i])[j] )
				return 1;
		}
	}
	
	return 0;
}

void MixColumns(unsigned char *in, unsigned char *out){
	int c = 0;
	
	for(c = 0; c < 4; ++c) {
		(&out[0])[c] = gf_mult(0x02, (&in[0])[c]) ^ gf_mult(0x03, (&in[1])[c]) 
						^ (&in[2])[c] ^ (&in[3])[c];
		(&out[1])[c] = (&in[0])[c] ^ gf_mult(0x02, (&in[1])[c]) 
						^ gf_mult(0x03, (&in[2])[c]) ^ (&in[3])[c];
		(&out[2])[c] = (&in[0])[c] ^ (&in[1])[c] ^ gf_mult(0x02, (&in[2])[c]) 
						^ gf_mult(0x03, (&in[3])[c]);
		(&out[3])[c] = gf_mult(0x03, (&in[0])[c]) ^ (&in[1])[c] ^ (&in[2])[c] 
						^ gf_mult(0x02, (&in[3])[c]);
	}
}

void InvMixColumns(unsigned char *in, unsigned char *out){
	int c = 0;
	
	for(c = 0; c < 4; ++c) {
		(&out[0])[c] = gf_mult(0x0E, (&in[0])[c]) ^ gf_mult(0x0B, (&in[1])[c]) 
					 ^ gf_mult(0x0D, (&in[2])[c]) ^ gf_mult(0x09, (&in[3])[c]);
		(&out[1])[c] = gf_mult(0x09, (&in[0])[c]) ^ gf_mult(0x0E, (&in[1])[c]) 
					 ^ gf_mult(0x0B, (&in[2])[c]) ^ gf_mult(0x0D, (&in[3])[c]);
		(&out[2])[c] = gf_mult(0x0D, (&in[0])[c]) ^ gf_mult(0x09, (&in[1])[c]) 
					 ^ gf_mult(0x0E, (&in[2])[c]) ^ gf_mult(0x0B, (&in[3])[c]);
		(&out[3])[c] = gf_mult(0x0B, (&in[0])[c]) ^ gf_mult(0x0D, (&in[1])[c]) 
					 ^ gf_mult(0x09, (&in[2])[c]) ^ gf_mult(0x0E, (&in[3])[c]);
	}
}

int TestMixColumns(unsigned char *state) {
	unsigned char mc[4][4];
	unsigned char inv_mc[4][4];
	int retval;
	
	MixColumns(state, *mc);
	InvMixColumns(*mc, *inv_mc);
	
	retval = state_equal(state, *inv_mc);
	if(retval != 0) {
		printf("in:\n");
		print_state(state);
		printf("\nout:\n");
		print_state(*inv_mc);
	}
	
	return retval;
}

int main (int argc, const char * argv[]) {
	int i;
	int count;
	unsigned char in[4][4];
	
	for(i = 0; i < 1000; ++i) {
		rand_state(*in);
		
		if(TestMixColumns(*in) != 0)
			++count;
	}
	
	printf("\n\n%i/1000 wrong\n", count);
	
    return 0;
}