Skip to content

Commit d3409e1

Browse files
authored
Add aes 192 256 support (#16)
* added support for 192 and 256 bit keys. added nist tests. did not add aes core tests * adeed core specic tests
1 parent f39edf0 commit d3409e1

6 files changed

Lines changed: 82 additions & 19 deletions

File tree

src/python/aes_decrypt.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
logger = logging.getLogger(__name__)
44

5-
# AES128 Constants
6-
Nr = 10
5+
# AES Constants
76
Nb = 4
8-
Nk = 4
97

108
s_box = [[0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76],
119
[0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0],
@@ -149,14 +147,28 @@ def InvCipher(text_in, w):
149147
if isinstance(text_in_hex, str):
150148
text_in_hex = bytes.fromhex(text_in)
151149
state = []
150+
151+
key_len = len(w) * 4
152+
if key_len == 128:
153+
Nk = 4
154+
Nr = 10
155+
elif key_len == 192:
156+
Nk = 6
157+
Nr = 12
158+
elif key_len == 256:
159+
Nk = 8
160+
Nr = 14
161+
else:
162+
assert(0)
163+
152164
# s[r,c]=in[r+4c] for0≤r<4 and 0≤c<Nb, (3.3)
153165
for r in range(0,4):
154166
row = []
155167
for c in range(0,Nb):
156168
row.append(text_in_hex[r+4*c])
157169
state.append(row)
158170

159-
w = KeyExpansion(w, Nk)
171+
w = KeyExpansion(w, Nk, Nr)
160172

161173
logger.debug("\nRound: 0")
162174
logger.debug("iinput")
@@ -181,7 +193,7 @@ def InvCipher(text_in, w):
181193
logger.debug(f'out: {out}')
182194
return out
183195

184-
def KeyExpansion(key, Nk):
196+
def KeyExpansion(key, Nk, Nr):
185197
temp = None
186198
w = []
187199
key_hex = bytes.fromhex(key)
@@ -201,8 +213,10 @@ def KeyExpansion(key, Nk):
201213

202214
for i in range(Nk, Nb * (Nr+1)):
203215
temp = w[i-1]
204-
if (i%Nk ==0):
216+
if (i%Nk==0):
205217
temp = SubWord(RotWord(temp)) ^ rcon_arr[i//Nk]
218+
elif (Nk > 6 and (i % Nk) == 4):
219+
temp = SubWord(temp)
206220
w.append( w[i-Nk] ^ temp )
207221
logger.debug(f'{i//4}: {hex(w[i])}')
208222

src/python/aes_encrypt.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22

33
logger = logging.getLogger(__name__)
44

5-
# AES128 Constants
6-
Nr = 10
5+
# AES Constants
76
Nb = 4
8-
Nk = 4
97

108
s_box = [[0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76],
119
[0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0],
@@ -134,6 +132,20 @@ def Cipher(text_in, w):
134132
logger.info("input was string not binary")
135133
text_in_hex = bytes.fromhex(text_in)
136134
state = []
135+
136+
key_len = len(w) * 4
137+
if key_len == 128:
138+
Nk = 4
139+
Nr = 10
140+
elif key_len == 192:
141+
Nk = 6
142+
Nr = 12
143+
elif key_len == 256:
144+
Nk = 8
145+
Nr = 14
146+
else:
147+
assert(0)
148+
137149
# s[r,c]=in[r+4c] for0≤r<4 and 0≤c<Nb, (3.3)
138150
for r in range(0,4):
139151
row = []
@@ -142,7 +154,7 @@ def Cipher(text_in, w):
142154
state.append(row)
143155
print_state(state)
144156

145-
w = KeyExpansion(w, Nk)
157+
w = KeyExpansion(w, Nk, Nr)
146158

147159
logger.debug("\nRound: 0")
148160
logger.debug("input")
@@ -168,7 +180,7 @@ def Cipher(text_in, w):
168180
logger.debug(f'out: {out}')
169181
return out
170182

171-
def KeyExpansion(key, Nk):
183+
def KeyExpansion(key, Nk, Nr):
172184
temp = None
173185
w = []
174186
key_hex = bytes.fromhex(key)
@@ -187,8 +199,10 @@ def KeyExpansion(key, Nk):
187199

188200
for i in range(Nk, Nb * (Nr+1)):
189201
temp = w[i-1]
190-
if (i%Nk ==0):
202+
if (i%Nk == 0):
191203
temp = SubWord(RotWord(temp)) ^ rcon_arr[i//Nk]
204+
elif (Nk > 6 and (i % Nk) == 4):
205+
temp = SubWord(temp)
192206
w.append( w[i-Nk] ^ temp )
193207
logger.debug(f'{i//4}: {hex(w[i])}')
194208

test/nist/aesmmt/test_aes_cbc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
from src.python.aes_modes import aes_cbc
55
from scripts.rsp_parser import parse_kat_file
66

7-
# TODO: Support 192 and 256
87
def get_mmt_cbc_files():
9-
return list(Path("nist/aesmmt").glob("CBC*128.rsp"))
8+
return list(Path("nist/aesmmt").glob("CBC*.rsp"))
109

1110
@pytest.mark.parametrize("mmt_files", get_mmt_cbc_files(), ids=lambda p: p.name)
1211
def test_mmt_aes_cbc_encrypt(mmt_files):

test/nist/aesmmt/test_aes_ecb.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
from src.python.aes_modes import aes_ecb
55
from scripts.rsp_parser import parse_kat_file
66

7-
# TODO: Support 192 and 256
87
def get_mmt_ecb_files():
9-
return list(Path("nist/aesmmt").glob("ECB*128.rsp"))
8+
return list(Path("nist/aesmmt").glob("ECB*.rsp"))
109

1110
@pytest.mark.parametrize("mmt_files", get_mmt_ecb_files(), ids=lambda p: p.name)
1211
def test_mmt_aes_ecb_encrypt(mmt_files):
1312
mmt_list = parse_kat_file(mmt_files)
1413
for (op, count), value in mmt_list.items():
1514
if op == "ENCRYPT":
15+
print(f"ENCRYPT: {count}")
1616
ct = aes_ecb(value.plaintext, value.key, op)
1717
assert(ct == value.ciphertext)
1818

@@ -21,5 +21,6 @@ def test_mmt_aes_ecb_decrypt(mmt_files):
2121
mmt_list = parse_kat_file(mmt_files)
2222
for (op, count), value in mmt_list.items():
2323
if op == "DECRYPT":
24+
print(f"DECRYPT: {count}")
2425
pt = aes_ecb(value.ciphertext, value.key, op)
2526
assert(pt == value.plaintext)

test/python/test_aes_decrypt.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ def test_decrypt_cipher():
77
out1 = "00112233445566778899aabbccddeeff"
88
assert(InvCipher(input1, key1) == out1)
99

10+
input_192 = "dda97ca4864cdfe06eaf70a0ec0d7191"
11+
key_192 = "000102030405060708090a0b0c0d0e0f1011121314151617"
12+
output_192 = "00112233445566778899aabbccddeeff"
13+
assert(InvCipher(input_192, key_192) == output_192)
14+
15+
input_256 = "8ea2b7ca516745bfeafc49904b496089"
16+
key_256 = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
17+
output_256 = "00112233445566778899aabbccddeeff"
18+
assert(InvCipher(input_256, key_256) == output_256)
19+
1020
if __name__ == "__main__":
1121
logging.basicConfig(
1222
level=logging.DEBUG,

test/python/test_aes_encrypt.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import logging
2-
from src.python.aes_encrypt import Cipher, KeyExpansion, Nk
2+
from src.python.aes_encrypt import Cipher, KeyExpansion
33

44
def test_cipher():
5-
key = "2b7e151628aed2a6abf7158809cf4f3c"
6-
KeyExpansion(key, Nk)
5+
keys = ["2b7e151628aed2a6abf7158809cf4f3c",
6+
"8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
7+
"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"]
8+
for key in keys:
9+
key_len = len(key) * 4
10+
if key_len == 128:
11+
Nk = 4
12+
Nr = 10
13+
elif key_len == 192:
14+
Nk = 6
15+
Nr = 12
16+
elif key_len == 256:
17+
Nk = 8
18+
Nr = 14
19+
else:
20+
assert(0)
21+
KeyExpansion(key, Nk, Nr)
722

823
# Input = 32 43 f6 a8 88 5a 30 8d 31 31 98 a2 e0 37 07 34
924
# Cipher Key = 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c
@@ -17,6 +32,16 @@ def test_cipher():
1732
out2 = "69c4e0d86a7b0430d8cdb78070b4c55a" # Appendix C
1833
assert(Cipher(input2, key2) == out2)
1934

35+
input_192 = "00112233445566778899aabbccddeeff"
36+
key_192 = "000102030405060708090a0b0c0d0e0f1011121314151617"
37+
output_192 = "dda97ca4864cdfe06eaf70a0ec0d7191"
38+
assert(Cipher(input_192, key_192) == output_192)
39+
40+
input_256 = "00112233445566778899aabbccddeeff"
41+
key_256 = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
42+
output_256 = "8ea2b7ca516745bfeafc49904b496089"
43+
assert(Cipher(input_256, key_256) == output_256)
44+
2045
if __name__ == "__main__":
2146
logging.basicConfig(
2247
level=logging.DEBUG,

0 commit comments

Comments
 (0)