Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/python-wasm
Path: blob/main/python/pylang/test/aes_vectors.py
1396 views
1
# vim:fileencoding=utf-8
2
# License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
4
from aes import CBC, CTR, GCM, generate_tag, as_hex, AES, string_to_bytes, random_bytes
5
6
def from_hex(text):
7
text = str.replace(text, ' ', '')
8
ans = Uint8Array(text.length // 2)
9
for i in range(ans.length):
10
ans[i] = int(text[2*i:2*i+2], 16)
11
return ans
12
13
def from32(ints):
14
ans = Uint8Array(ints.length * 4)
15
for i, num in enumerate(ints):
16
off = i*4
17
ans[off] = (num & 0xff000000) >> 24
18
ans[off+1] = (num & 0x00ff0000) >> 16
19
ans[off+2] = (num & 0x0000ff00) >> 8
20
ans[off+3] = num & 0x000000ff
21
return ans
22
23
def rungcm(keys, ivs, inputs, adatas, outputs, tags):
24
for i in range(keys.length):
25
iv = from_hex(ivs[i])
26
gcm = GCM(from_hex(keys[i]))
27
inputbytes = from_hex(inputs[i])
28
outputbytes = from_hex(outputs[i])
29
adata = from_hex(adatas[i])
30
ans = gcm._crypt(iv, inputbytes, adata, False)
31
assrt.equal(as_hex(ans.cipherbytes), outputs[i])
32
assrt.equal(as_hex(ans.tag), tags[i])
33
ans = gcm._crypt(iv, outputbytes, adata, True)
34
assrt.equal(as_hex(ans.cipherbytes), inputs[i])
35
assrt.equal(as_hex(ans.tag), tags[i])
36
37
def run_tests():
38
# Test basic AES {{{
39
k1 = '000102030405060708090a0b0c0d0e0f'
40
k2 = k1 + '1011121314151617'
41
k3 = k2 + '18191a1b1c1d1e1f'
42
b = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
43
44
for data in [
45
(b, k1, '69c4e0d86a7b0430d8cdb78070b4c55a', False),
46
([0x69c4e0d8, 0x6a7b0430, 0xd8cdb780, 0x70b4c55a], k1, '00112233445566778899aabbccddeeff', True),
47
(b, k2, 'dda97ca4864cdfe06eaf70a0ec0d7191', False),
48
([0xdda97ca4, 0x864cdfe0, 0x6eaf70a0, 0xec0d7191], k2, '00112233445566778899aabbccddeeff', True),
49
(b, k3, '8ea2b7ca516745bfeafc49904b496089', False),
50
([0x8ea2b7ca, 0x516745bf, 0xeafc4990, 0x4b496089], k3, '00112233445566778899aabbccddeeff', True),
51
]:
52
block, key, expected, decrypt = data
53
aes = AES(from_hex(key))
54
output = Uint8Array(block.length * 4)
55
aes.decrypt32(block, output, 0) if decrypt else aes.encrypt32(block, output, 0)
56
assrt.equal(expected, as_hex(output))
57
58
# Test AES-CBC
59
keys = [
60
'06a9214036b8a15b512e03d534120006',
61
'c286696d887c9aa0611bbb3e2025a45a',
62
'6c3ea0477630ce21a2ce334aa746c2cd',
63
'56e47a38c5598974bc46903dba290349'
64
]
65
66
ivs = [
67
'3dafba429d9eb430b422da802c9fac41',
68
'562e17996d093d28ddb3ba695a2e6f58',
69
'c782dc4c098c66cbd9cd27d825682c81',
70
'8ce82eefbea0da3c44699ed7db51b7d9'
71
]
72
73
inputs = [
74
'Single block msg',
75
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
76
'This is a 48-byte message (exactly 3 AES blocks)',
77
'a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf'
78
]
79
80
outputs = [
81
'e353779c1079aeb82708942dbe77181a',
82
'd296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1',
83
'd0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684',
84
'c30e32ffedc0774e6aff6af0869f71aa0f3af07a9a31a9c684db207eb0ef8e4e35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55'
85
]
86
for i in range(keys.length):
87
cbc = CBC(from_hex(keys[i]))
88
x = inputs[i]
89
inputbytes = string_to_bytes(x) if ' ' in x else from_hex(x)
90
x = outputs[i]
91
outputbytes = string_to_bytes(x) if ' ' in x else from_hex(x)
92
iv = from_hex(ivs[i])
93
ans = cbc.encrypt_bytes(inputbytes, [], iv)
94
assrt.equal(as_hex(ans.cipherbytes), outputs[i])
95
ans = cbc.decrypt_bytes(outputbytes, [], iv)
96
assrt.equal(as_hex(ans), as_hex(inputbytes))
97
# }}}
98
99
# Test AES-CTR {{{
100
keys = [
101
'00000000000000000000000000000000',
102
'2b7e151628aed2a6abf7158809cf4f3c'
103
]
104
105
ivs = [
106
'650cdb80ff9fc758342d2bd99ee2abcf',
107
'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff'
108
]
109
110
inputs = [
111
'This is a 48-byte message (exactly 3 AES blocks)',
112
'6bc1bee22e409f96e93d7e117393172a' 'ae2d8a571e03ac9c9eb76fac45af8e51' '30c81c46a35ce411e5fbc1191a0a52ef' 'f69f2445df4f9b17ad2b417be66c3710'
113
]
114
115
outputs = [
116
'5ede11d00e9a76ec1d5e7e811ea3dd1c' 'e09ee941210f825d35718d3282796f1c' '07c3f1cb424f2b365766ab5229f5b5a4',
117
'874d6191b620e3261bef6864990db6ce' '9806f66b7970fdff8617187bb9fffdff' '5ae4df3edbd5d35e5b4f09020db03eab' '1e031dda2fbe03d1792170a0f3009cee'
118
]
119
120
for i in range(keys.length):
121
iv = from_hex(ivs[i])
122
ctr = CTR(from_hex(keys[i]), iv)
123
x = inputs[i]
124
inputbytes = string_to_bytes(x) if ' ' in x else from_hex(x)
125
x = outputs[i]
126
outputbytes = string_to_bytes(x) if ' ' in x else from_hex(x)
127
temp = Uint8Array(inputbytes)
128
ctr._crypt(temp)
129
assrt.equal(as_hex(temp), outputs[i])
130
# }}}
131
132
# Test AES-GCM {{{
133
keys = [
134
'00000000000000000000000000000000',
135
'00000000000000000000000000000000',
136
'feffe9928665731c6d6a8f9467308308',
137
'feffe9928665731c6d6a8f9467308308',
138
'feffe9928665731c6d6a8f9467308308',
139
'feffe9928665731c6d6a8f9467308308',
140
'00000000000000000000000000000000'
141
]
142
143
ivs = [
144
'000000000000000000000000',
145
'000000000000000000000000',
146
'cafebabefacedbaddecaf888',
147
'cafebabefacedbaddecaf888',
148
'cafebabefacedbad',
149
'9313225df88406e555909c5aff5269aa' + '6a7a9538534f7da1e4c303d2a318a728' + 'c3c0c95156809539fcf0e2429a6b5254' + '16aedbf5a0de6a57a637b39b',
150
'000000000000000000000000'
151
]
152
153
adatas = [
154
'',
155
'',
156
'',
157
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
158
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
159
'feedfacedeadbeeffeedfacedeadbeef' + 'abaddad2',
160
''
161
]
162
163
inputs = [
164
'',
165
'00000000000000000000000000000000',
166
'd9313225f88406e5a55909c5aff5269a' + '86a7a9531534f7da2e4c303d8a318a72' + '1c3c0c95956809532fcf0e2449a6b525' + 'b16aedf5aa0de657ba637b391aafd255',
167
'd9313225f88406e5a55909c5aff5269a' + '86a7a9531534f7da2e4c303d8a318a72' + '1c3c0c95956809532fcf0e2449a6b525' + 'b16aedf5aa0de657ba637b39',
168
'd9313225f88406e5a55909c5aff5269a' + '86a7a9531534f7da2e4c303d8a318a72' + '1c3c0c95956809532fcf0e2449a6b525' + 'b16aedf5aa0de657ba637b39',
169
'd9313225f88406e5a55909c5aff5269a' + '86a7a9531534f7da2e4c303d8a318a72' + '1c3c0c95956809532fcf0e2449a6b525' + 'b16aedf5aa0de657ba637b39',
170
'0000'
171
]
172
173
outputs = [
174
'',
175
'0388dace60b6a392f328c2b971b2fe78',
176
'42831ec2217774244b7221b784d0d49c' + 'e3aa212f2c02a4e035c17e2329aca12e' + '21d514b25466931c7d8f6a5aac84aa05' + '1ba30b396a0aac973d58e091473f5985',
177
'42831ec2217774244b7221b784d0d49c' + 'e3aa212f2c02a4e035c17e2329aca12e' + '21d514b25466931c7d8f6a5aac84aa05' + '1ba30b396a0aac973d58e091',
178
'61353b4c2806934a777ff51fa22a4755' + '699b2a714fcdc6f83766e5f97b6c7423' + '73806900e49f24b22b097544d4896b42' + '4989b5e1ebac0f07c23f4598',
179
'8ce24998625615b603a033aca13fb894' + 'be9112a5c3a211a8ba262a3cca7e2ca7' + '01e4a9a4fba43c90ccdcb281d48c7c6f' + 'd62875d2aca417034c34aee5',
180
'0388'
181
]
182
183
tags = [
184
'58e2fccefa7e3061367f1d57a4e7455a',
185
'ab6e47d42cec13bdf53a67b21257bddf',
186
'4d5c2af327cd64a62cf35abd2ba6fab4',
187
'5bc94fbc3221a5db94fae95ae7121a47',
188
'3612d2e79e3b0785561be14aaca2fccb',
189
'619cc5aefffe0bfa462af43c1699d050',
190
'93dcdd26f79ec1dd9bff57204d9b33f5'
191
]
192
rungcm(keys, ivs, inputs, adatas, outputs, tags)
193
194
keys = [
195
'00000000000000000000000000000000' +
196
'0000000000000000',
197
'00000000000000000000000000000000' +
198
'0000000000000000',
199
'feffe9928665731c6d6a8f9467308308' +
200
'feffe9928665731c',
201
'feffe9928665731c6d6a8f9467308308' +
202
'feffe9928665731c',
203
'feffe9928665731c6d6a8f9467308308' +
204
'feffe9928665731c',
205
'feffe9928665731c6d6a8f9467308308' +
206
'feffe9928665731c'
207
]
208
209
ivs = [
210
'000000000000000000000000',
211
'000000000000000000000000',
212
'cafebabefacedbaddecaf888',
213
'cafebabefacedbaddecaf888',
214
'cafebabefacedbad',
215
'9313225df88406e555909c5aff5269aa' +
216
'6a7a9538534f7da1e4c303d2a318a728' +
217
'c3c0c95156809539fcf0e2429a6b5254' +
218
'16aedbf5a0de6a57a637b39b'
219
]
220
221
adatas = [
222
'',
223
'',
224
'',
225
'feedfacedeadbeeffeedfacedeadbeef' +
226
'abaddad2',
227
'feedfacedeadbeeffeedfacedeadbeef' +
228
'abaddad2',
229
'feedfacedeadbeeffeedfacedeadbeef' +
230
'abaddad2'
231
]
232
233
inputs = [
234
'',
235
'00000000000000000000000000000000',
236
'd9313225f88406e5a55909c5aff5269a' +
237
'86a7a9531534f7da2e4c303d8a318a72' +
238
'1c3c0c95956809532fcf0e2449a6b525' +
239
'b16aedf5aa0de657ba637b391aafd255',
240
'd9313225f88406e5a55909c5aff5269a' +
241
'86a7a9531534f7da2e4c303d8a318a72' +
242
'1c3c0c95956809532fcf0e2449a6b525' +
243
'b16aedf5aa0de657ba637b39',
244
'd9313225f88406e5a55909c5aff5269a' +
245
'86a7a9531534f7da2e4c303d8a318a72' +
246
'1c3c0c95956809532fcf0e2449a6b525' +
247
'b16aedf5aa0de657ba637b39',
248
'd9313225f88406e5a55909c5aff5269a' +
249
'86a7a9531534f7da2e4c303d8a318a72' +
250
'1c3c0c95956809532fcf0e2449a6b525' +
251
'b16aedf5aa0de657ba637b39'
252
]
253
254
outputs = [
255
'',
256
'98e7247c07f0fe411c267e4384b0f600',
257
'3980ca0b3c00e841eb06fac4872a2757' +
258
'859e1ceaa6efd984628593b40ca1e19c' +
259
'7d773d00c144c525ac619d18c84a3f47' +
260
'18e2448b2fe324d9ccda2710acade256',
261
'3980ca0b3c00e841eb06fac4872a2757' +
262
'859e1ceaa6efd984628593b40ca1e19c' +
263
'7d773d00c144c525ac619d18c84a3f47' +
264
'18e2448b2fe324d9ccda2710',
265
'0f10f599ae14a154ed24b36e25324db8' +
266
'c566632ef2bbb34f8347280fc4507057' +
267
'fddc29df9a471f75c66541d4d4dad1c9' +
268
'e93a19a58e8b473fa0f062f7',
269
'd27e88681ce3243c4830165a8fdcf9ff' +
270
'1de9a1d8e6b447ef6ef7b79828666e45' +
271
'81e79012af34ddd9e2f037589b292db3' +
272
'e67c036745fa22e7e9b7373b'
273
]
274
275
tags = [
276
'cd33b28ac773f74ba00ed1f312572435',
277
'2ff58d80033927ab8ef4d4587514f0fb',
278
'9924a7c8587336bfb118024db8674a14',
279
'2519498e80f1478f37ba55bd6d27618c',
280
'65dcc57fcf623a24094fcca40d3533f8',
281
'dcf566ff291c25bbb8568fc3d376a6d9'
282
]
283
rungcm(keys, ivs, inputs, adatas, outputs, tags)
284
285
keys = [
286
'00000000000000000000000000000000' +
287
'00000000000000000000000000000000',
288
'00000000000000000000000000000000' +
289
'00000000000000000000000000000000',
290
'feffe9928665731c6d6a8f9467308308' +
291
'feffe9928665731c6d6a8f9467308308',
292
'feffe9928665731c6d6a8f9467308308' +
293
'feffe9928665731c6d6a8f9467308308',
294
'feffe9928665731c6d6a8f9467308308' +
295
'feffe9928665731c6d6a8f9467308308',
296
'feffe9928665731c6d6a8f9467308308' +
297
'feffe9928665731c6d6a8f9467308308'
298
]
299
300
ivs = [
301
'000000000000000000000000',
302
'000000000000000000000000',
303
'cafebabefacedbaddecaf888',
304
'cafebabefacedbaddecaf888',
305
'cafebabefacedbad',
306
'9313225df88406e555909c5aff5269aa' +
307
'6a7a9538534f7da1e4c303d2a318a728' +
308
'c3c0c95156809539fcf0e2429a6b5254' +
309
'16aedbf5a0de6a57a637b39b'
310
]
311
312
adatas = [
313
'',
314
'',
315
'',
316
'feedfacedeadbeeffeedfacedeadbeef' +
317
'abaddad2',
318
'feedfacedeadbeeffeedfacedeadbeef' +
319
'abaddad2',
320
'feedfacedeadbeeffeedfacedeadbeef' +
321
'abaddad2'
322
]
323
324
inputs = [
325
'',
326
'00000000000000000000000000000000',
327
'd9313225f88406e5a55909c5aff5269a' +
328
'86a7a9531534f7da2e4c303d8a318a72' +
329
'1c3c0c95956809532fcf0e2449a6b525' +
330
'b16aedf5aa0de657ba637b391aafd255',
331
'd9313225f88406e5a55909c5aff5269a' +
332
'86a7a9531534f7da2e4c303d8a318a72' +
333
'1c3c0c95956809532fcf0e2449a6b525' +
334
'b16aedf5aa0de657ba637b39',
335
'd9313225f88406e5a55909c5aff5269a' +
336
'86a7a9531534f7da2e4c303d8a318a72' +
337
'1c3c0c95956809532fcf0e2449a6b525' +
338
'b16aedf5aa0de657ba637b39',
339
'd9313225f88406e5a55909c5aff5269a' +
340
'86a7a9531534f7da2e4c303d8a318a72' +
341
'1c3c0c95956809532fcf0e2449a6b525' +
342
'b16aedf5aa0de657ba637b39'
343
]
344
345
outputs = [
346
'',
347
'cea7403d4d606b6e074ec5d3baf39d18',
348
'522dc1f099567d07f47f37a32a84427d' +
349
'643a8cdcbfe5c0c97598a2bd2555d1aa' +
350
'8cb08e48590dbb3da7b08b1056828838' +
351
'c5f61e6393ba7a0abcc9f662898015ad',
352
'522dc1f099567d07f47f37a32a84427d' +
353
'643a8cdcbfe5c0c97598a2bd2555d1aa' +
354
'8cb08e48590dbb3da7b08b1056828838' +
355
'c5f61e6393ba7a0abcc9f662',
356
'c3762df1ca787d32ae47c13bf19844cb' +
357
'af1ae14d0b976afac52ff7d79bba9de0' +
358
'feb582d33934a4f0954cc2363bc73f78' +
359
'62ac430e64abe499f47c9b1f',
360
'5a8def2f0c9e53f1f75d7853659e2a20' +
361
'eeb2b22aafde6419a058ab4f6f746bf4' +
362
'0fc0c3b780f244452da3ebf1c5d82cde' +
363
'a2418997200ef82e44ae7e3f'
364
]
365
366
tags = [
367
'530f8afbc74536b9a963b4f1c4cb738b',
368
'd0d1c8a799996bf0265b98b5d48ab919',
369
'b094dac5d93471bdec1a502270e3cc6c',
370
'76fc6ece0f4e1768cddf8853bb2d551b',
371
'3a337dbf46a792c45e454913fe2ea8f2',
372
'a44a8266ee1c8eb0c8b5d4cf5ae9f19a'
373
]
374
rungcm(keys, ivs, inputs, adatas, outputs, tags)
375
376
# Test that IVs do not repeat (they are incrementing)
377
gcm = GCM(random_bytes(16))
378
for i in range(5):
379
iv = gcm.encrypt(str(i)).iv
380
assrt.equal(iv[11], i+1)
381
for j in range(10):
382
assrt.equal(iv[j], 0)
383
# Test that iv rollover is not allowed
384
gcm.current_iv.fill(255)
385
assrt.throws(def(): gcm.encrypt('iv over');)
386
387
# }}}
388
389
# Test roundtripping {{{
390
391
text = 'testing a basic roundtrip ø̄ū'
392
393
cbc = CBC()
394
crypted = cbc.encrypt(text)
395
decrypted = cbc.decrypt(crypted)
396
assrt.equal(text, decrypted)
397
secret_tag = generate_tag()
398
crypted = cbc.encrypt(text, secret_tag)
399
decrypted = cbc.decrypt(crypted, secret_tag)
400
assrt.equal(text, decrypted)
401
402
ctr = CTR()
403
crypted = ctr.encrypt(text)
404
decrypted = ctr.decrypt(crypted)
405
assrt.equal(text, decrypted)
406
crypted = ctr.encrypt(text, secret_tag)
407
decrypted = ctr.decrypt(crypted, secret_tag)
408
assrt.equal(text, decrypted)
409
410
gcm = GCM()
411
crypted = gcm.encrypt(text)
412
decrypted = gcm.decrypt(crypted)
413
assrt.equal(text, decrypted)
414
crypted = gcm.encrypt(text, secret_tag)
415
decrypted = gcm.decrypt(crypted, secret_tag)
416
assrt.equal(text, decrypted)
417
418
assrt.ok(equals(from_hex('69c4e0d86a7b0430d8cdb78070b4c55a'), from32([0x69c4e0d8, 0x6a7b0430, 0xd8cdb780, 0x70b4c55a])))
419
# }}}
420
421
run_tests()
422
423