changeset 1072:c503c9b40df0

AES KeyExpansion and AddRoundKey implemented.
author Marcel Keller <mkeller@cs.au.dk>
date Fri, 09 Jan 2009 14:22:58 +0100
parents f9fb8c387f8f
children 936ce049980f
files viff/aes.py viff/test/test_aes.py
diffstat 2 files changed, 71 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/viff/aes.py	Tue Dec 23 16:28:37 2008 +0100
+++ b/viff/aes.py	Fri Jan 09 14:22:58 2009 +0100
@@ -71,11 +71,7 @@
         """ByteSub operation of Rijndael.
 
         The first argument should be a matrix consisting of elements
-        of GF(2^8) or shares thereof with 4 rows and block_size / 32
-        elements."""
-
-        assert len(state) == 4, "State must have 4 rows."
-        assert len(state[0]) == self.n_b, "State must have block_size / 32 columns"
+        of GF(2^8)."""
 
         for h in range(len(state)):
             row = state[h]
@@ -142,3 +138,42 @@
     def mix_column(self, state):
         state[:] = (AES.C * Matrix(state)).rows
 
+    def add_round_key(self, state, round_key):
+        """Rijndael AddRoundKey.
+
+        State should be a list of 4 rows and round_key a list of
+        4-byte columns (words)."""
+
+        assert len(round_key) == self.n_k, "Wrong key size."
+        assert len(round_key[0]) == 4, "Key must consist of 4-byte words."
+
+        state[:] = (Matrix(state) + Matrix(zip(*round_key))).rows
+
+    def key_expansion(self, key):
+        """Rijndael key expansion.
+
+        Input and output are lists of 4-byte columns (words)."""
+
+        assert len(key) == self.n_k, "Wrong key size."
+        assert len(key[0]) == 4, "Key must consist of 4-byte words."
+
+        expanded_key = list(key)
+
+        for i in xrange(self.n_k, self.n_b * (self.rounds + 1)):
+            temp = list(expanded_key[i - 1])
+
+            if (i % self.n_k == 0):
+                temp.append(temp.pop(0))
+                self.byte_sub([temp])
+                temp[0] += GF256(2) ** (i / self.n_k - 1)
+            elif (self.n_k > 6 and i % self.n_k == 4):
+                self.byte_sub([temp])
+
+            new_word = []
+
+            for j in xrange(4):
+                new_word.append(expanded_key[i - self.n_k][j] + temp[j])
+
+            expanded_key.append(new_word)
+
+        return expanded_key
--- a/viff/test/test_aes.py	Tue Dec 23 16:28:37 2008 +0100
+++ b/viff/test/test_aes.py	Fri Jan 09 14:22:58 2009 +0100
@@ -24,7 +24,7 @@
 from viff.runtime import gather_shares, Share
 from viff.aes import bit_decompose, AES
 
-from viff.test.rijndael import S
+from viff.test.rijndael import S, rijndael
 
 
 __doctest__ = ["viff.aes"]
@@ -86,3 +86,33 @@
 
         aes.byte_sub(results)
         self.verify(runtime, results, expected_results)
+
+    @protocol
+    def test_key_expansion(self, runtime):
+        aes = AES(runtime, 256)
+        key = []
+        ascii_key = []
+
+        for i in xrange(8):
+            key.append([])
+
+            for j in xrange(4):
+                b = 15 * i + j
+                key[i].append(Share(runtime, GF256, GF256(b)))
+                ascii_key.append(chr(b))
+
+        result = aes.key_expansion(key)
+
+        r = rijndael(ascii_key)
+        expected_result = []
+
+        for round_key in r.Ke:
+            for word in round_key:
+                split_word = []
+                expected_result.append(split_word)
+
+                for j in xrange(4):
+                    split_word.insert(0, word % 256)
+                    word /= 256
+
+        self.verify(runtime, result, expected_result)