2. 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 F2 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.)
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 4rndsIf 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.
As has been pointed out, 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 as we discussed in class.
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 xwhere 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 248633568239107965830560009361047375509LAfter 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.