views:

200

answers:

2

Hello there,

I'm going to make a long story short. It's been a while that I want to implement my own AES encryption/decryption program. The encryption program went well and encrypting without any error or strange output (Since I have compared my program's output with a working commercial one and result was the same).

Wikipedia was (is) my guide in this implementation within which I read "A set of reverse rounds are applied to transform ciphertext back into the original plaintext using the same encryption key."

There are couple of modules that I implemented:

  1. Add round key
  2. Shift rows
  3. Sub bytes
  4. Mix Column

I also implemented couple of reverse implementation of the above modules:

  1. Reverse shift rows
  2. Reverse Sub Byte
  3. Reverse Mix Column

NOTE: I didn't implement reverse round key since, It's XOR ing the plaintext with the encryption key, and reverse of XOR is XOR itself (correct me if I am wrong)

So I putted this modules in the reverse order that I did encryption, but never I got my plain-text back:

expandkey128(key);
rev_subbytes(data);  
rev_shiftrows(data);
addroundkey(data,key,10);

for(int i = 9; i>= 1; i--) { 
    rev_subbytes(data); 
    rev_shiftrows(data);
    rev_mixColum(data);
    addroundkey(data,key,i);
}

addroundkey(data,key,0);

// Please note that I also did from 0 to 10 ,
// instead of 10 to 0 and didn't workout

And also I thought , maybe I should not implement reverse model of the modules, maybe I have to use those modules that I did encryption with, only in reverse order; well guess what? didn't work! :

expandkey128(key);
addroundkey(data,key,0);

for(int i = 1; i<= 9; i++) {
    subbytes(data); 
    shiftrows(data);
    mixColum(data);
    addroundkey(data,key,i);
}

subbytes(data);
shiftrows(data);
addroundkey(data,key,10);

So here is the question: what is wrong? || what is the correct sequence of applying these so called modules or functions if you will?

+4  A: 

Your order of operations seems wrong. I think you want this:

expandkey128(key);

addroundkey(data,key,10);
rev_shiftrows(data);
rev_subbytes(data); 

for(int i = 9; i>= 1; i--) { 
    addroundkey(data,key,i);
    rev_mixColumn(data);
    rev_shiftrows(data);
    rev_subbytes(data); 
}

addroundkey(data,key,0);

For more details, see my stick figure explanation of AES with its accompanying reference implementation.

WARNING: As mentioned in Act 3, Scene 2, there be dragons in writing your own AES implementation for production use.

Jeff Moser
I wouldn't use a own implementation for aes either. Nice Agreement ;)
evildead
Well I'm not going to use it anywhere, was just for fun!and I tried your order which didn't work, also I checked the link (http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf), says different order
Pooria Madani
It works on my machine and in my implementation :). If you have some time, download my C# implementation and step through it and compare each step to your implementation. Note that the order I gave is effectively the same as Figure 12. I just prefer it in the order I gave to make it clear that it is reversing everything. It took me a few trials comparing my output to the round-by-round output from the Rijndael book to make sure I had things right. You might simply have a small error in one of your inverse functions. I'd recommend going slowly over each round as your next step.
Jeff Moser
thx Jeff the bug was in my Inverse sBox implementation, and your order of putting statements is totally correct, appertained again
Pooria Madani
Hooray! Glad to hear you got it working
Jeff Moser
A: 

Why do you need to write own implementation?

However, there is a reference implementation, and test vectors - you can run your code and test it round-by-round to see where it goes wrong.

Nickolay O.