CSCI 6454 - Advanced Algorithms - Spring 2014

Homework #4

Due: Apr 14th, 2014



1. Consider the finite field GF(16) with irreducible polynomial m(x) = x4 + x3 + 1. (You'll have to trust me that m(x) is irreducible over Z2 here.) We will, as usual, represent group elements as either polynomials in x, or a hex number, or binary strings, with the usual mapping between these representations.
(a) What polynomial corresponds to the hex number 'a'?
(b) What is 'a' + '7' in this field?
(c) What is 'a' * '7' in this field?
(d) What is the additive inverse of 'e' in this field?
(e) What is the multiplicative inverse of 'e' in this field? (Try elements exhaustively using the xtime() method and show your work. You can use Euclid's algorithm if you know it.)

2. We said in class that MixColumn on a column with exactly one active cell, and the rest constant, converts to all cells active. Prove this.

In order to have a convincing proof, first write down carefully what it is we are claiming here. Then do the algebra in the proper ring or field to show that the claim must be true.

3. Please implement the 4-round attack against Rijndael.

First, download the Rijndael source to your computer and unzip it and build it (for Unix, just run make; you might have to add the line CC=gcc if the cc compiler does not exist on your machine). Then download a program I wrote 4rnds.c and build it. For unix

  % gcc rijndael-alg-fst.o 4rnds.c -o 4rnds
If you examine the source to 4rnds.c, you'll see that I have the number of rounds (AES_ROUNDS) set to 4, and the key is set to all 0's. Run 4rnds and make sure you get the same output as what I got.

Ok, now here's your goal: I ran this same program, 4rnds.c, with a different key which I'm not telling you, but the same plaintexts (which happen to be very nice for the Square attack, as you can see from the source code). Under this secret key, I got 256 ciphertexts which you now will use to mount the attack.

The answer to this problem is the value of that secret key. This means you'll have to study the key schedule, but that's not too hard. Along with your answer, please provide the well-documented source code you used to crack this cipher.

You probably will get several candidate keys. You can narrow these down by trying each of them on the following plaintext/ciphertext pair (which uses the same secret key you are looking for). If there is still more than one candidate key which works, please hand in all that you found.

pt: 0102030405060708090a0b0c0d0e0f00
ct: 71fae486fafc990d4a44a21a7fac6b75

4. Define blockcipher X as follows: X has a 128-bit blocksize and a 12800-bit key K. K is broken into 100 chunks of 128-bits each, K1 through K100. Blockcipher X(K, P) is like this: C0=P and Ci=S(Ci-1 ⊕ Ki), where S(⋅) is inversion in GF(2128) (where 0 goes to 0 as usual). The output of the blockcipher is C100. Break this thing.

Details: Our irreducible polynomial of degree 128 will be x128+x7+x2+x+1. This is irreducible over GF(2). I have taken a publicly-available library ffield.py and added this modulus to it so we can compute easily in python in this field. Instructions are contained in the source code.

Now it's quite easy to implement cipher X as described above:

import ffield
import keylist

F = ffield.FField(128)

def encipher(x):
    for i in range(100):
        x = F.Inverse(F.Add(x, keylist.key[i]))
    return x

def decipher(x):
    for i in reversed(range(100)):
        x = F.Add(F.Inverse(x), keylist.key[i])
    return x
where keylist.py is a file just listing the 100 round keys. If you want a random 12,800 bit master key, you can use this python code to generate one and then save its output to keylist.py (which will make the above code work):
import random

print "keys = ["
for i in range(99):
    k = random.getrandbits(128)
    print k, ','
print random.getrandbits(128), ']'
Using these techniques, I have created my own 12,800 bit random key and enciphered the three plaintexts 0L, 1L, and 2L. Their corresponding ciphertexts in decimal are
131561246017920334936828440555437427465L
248729583318336296365530932515022212932L
248633568239107965830560009361047375509L
After you have broken this thing, you won't have the key I used, but you will be able to decipher any ciphertext I give you. Please hand in the decipherment of the ciphertext 330927140779763012830194718016277696816L along with your source code. Note this can be done in 5 lines of python. Finding the right 5 lines should, however, be fairly challenging.