kryptools 1.9.4__tar.gz → 1.9.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kryptools-1.9.4 → kryptools-1.9.6}/PKG-INFO +1 -1
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/Zmod.py +16 -2
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/__init__.py +1 -1
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/blockcipher.py +65 -30
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/dlp_rho.py +5 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_rho.py +1 -1
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/poly.py +6 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools.egg-info/PKG-INFO +1 -1
- {kryptools-1.9.4 → kryptools-1.9.6}/pyproject.toml +1 -1
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_aes.py +13 -8
- {kryptools-1.9.4 → kryptools-1.9.6}/LICENSE +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/README.md +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/GF2.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/aes.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/code.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/conway_polynomials.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/des.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/dlp.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/dlp_bsgs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/dlp_ic.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/dlp_qs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/ec.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_dix.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_ecm.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_fmt.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_pm1.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/factor_qs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/intfuncs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/keccak.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/la.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/lat.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/lat2.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/nt.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/primes.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools/sha1.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools.egg-info/SOURCES.txt +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools.egg-info/dependency_links.txt +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/kryptools.egg-info/top_level.txt +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/setup.cfg +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_GF2.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_Zmod.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_code.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_des.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_dlog.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_ec.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_factor.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_factor_fmt.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_factor_pm1.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_factor_qs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_intfuncs.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_keccak.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_la.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_lat.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_nt.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_poly.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_primes.py +0 -0
- {kryptools-1.9.4 → kryptools-1.9.6}/tests/test_sha1.py +0 -0
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
Ring of intergers modulo `n`.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from math import gcd
|
|
5
|
+
from math import gcd, floor
|
|
6
6
|
from random import randint
|
|
7
|
+
from fractions import Fraction
|
|
7
8
|
from .factor import factorint
|
|
8
9
|
from .primes import is_prime
|
|
9
10
|
from .nt import sqrt_mod, crt
|
|
@@ -60,6 +61,13 @@ class Zmod:
|
|
|
60
61
|
def __contains__(self, other: "ZmodPoint") -> bool:
|
|
61
62
|
return isinstance(other, ZmodPoint) and self.n == other.ring.n
|
|
62
63
|
|
|
64
|
+
def decompress(self, x: int, d: int) -> "ZmodPoint":
|
|
65
|
+
"Decompress an integer `x` with at most `d` bits to Z_n."
|
|
66
|
+
if not isinstance(d, int) or d <= 0 or d >= self.n.bit_length():
|
|
67
|
+
raise ValueError("The number of bits must be between 1 and the bit length of the modulus.")
|
|
68
|
+
x %= 2**d
|
|
69
|
+
return ZmodPoint( floor(Fraction(x * self.n, 2**d) + Fraction(1, 2) ), self)
|
|
70
|
+
|
|
63
71
|
def random(self, num: int = 0) -> "ZmodPoint":
|
|
64
72
|
"Return a single random point or a list of random points."
|
|
65
73
|
if num:
|
|
@@ -255,8 +263,14 @@ class ZmodPoint:
|
|
|
255
263
|
return self.x
|
|
256
264
|
return self.ring.n - self.x
|
|
257
265
|
|
|
266
|
+
def compress(self, d: int) -> list:
|
|
267
|
+
"Returns the value compressed to `d` bits."
|
|
268
|
+
if not isinstance(d, int) or d <= 0 or d > self.ring.n.bit_length():
|
|
269
|
+
raise ValueError("The number of bits must be between 1 and the bit length of the modulus.")
|
|
270
|
+
return floor(Fraction(self.x * 2**d, self.ring.n) + Fraction(1, 2) ) % 2**d
|
|
271
|
+
|
|
258
272
|
def bits(self) -> list:
|
|
259
|
-
"
|
|
273
|
+
"Returns a list of bits."
|
|
260
274
|
return [int(d) for d in str(format(self.x, "0" + str(int.bit_length(self.ring.n - 1)) + "b"))]
|
|
261
275
|
|
|
262
276
|
def sharp(self):
|
|
@@ -5,7 +5,7 @@ Implemenation of same basic algorithms used in cryptography.
|
|
|
5
5
|
__author__ = "Gerald Teschl"
|
|
6
6
|
__copyright__ = "Copyright 2024-2026, Gerald Teschl"
|
|
7
7
|
__license__ = "MIT License"
|
|
8
|
-
__version__ = "1.9.
|
|
8
|
+
__version__ = "1.9.6"
|
|
9
9
|
__email__ = "Gerald.Teschl@univie.ac.at"
|
|
10
10
|
|
|
11
11
|
from .nt import egcd, cf, convergents, legendre_symbol, jacobi_symbol, sqrt_mod, euler_phi, carmichael_lambda, moebius_mu, is_carmichael_number, order, crt
|
|
@@ -13,10 +13,11 @@ class BlockCipher:
|
|
|
13
13
|
|
|
14
14
|
blocksize: int = 1 # blocksize in bytes
|
|
15
15
|
|
|
16
|
-
def __init__(self, key: bytes|int = None, mode: str|None = None):
|
|
16
|
+
def __init__(self, key: bytes|int = None, mode: str|None = None, ctrlen: int | None = None):
|
|
17
17
|
self.key = None # here we store the key (if any)
|
|
18
18
|
self.cipher = None # here we can store an instance of the cipher initialized with the key
|
|
19
19
|
self.mode = mode # here we store the default en/decryption mode
|
|
20
|
+
self.ctrlen = ctrlen # default counter length for CTR mode
|
|
20
21
|
if key:
|
|
21
22
|
self.set_key(key)
|
|
22
23
|
|
|
@@ -142,6 +143,7 @@ class BlockCipher:
|
|
|
142
143
|
if iv is None:
|
|
143
144
|
z = randbytes(self.__class__.blocksize) # iv
|
|
144
145
|
else:
|
|
146
|
+
assert len(iv) == self.__class__.blocksize, "Length of IV must be equal to the block length."
|
|
145
147
|
z = iv
|
|
146
148
|
ctext.extend(z) # add iv as first block of the cipher text
|
|
147
149
|
for b in self.blocksplit(text, False):
|
|
@@ -159,40 +161,73 @@ class BlockCipher:
|
|
|
159
161
|
text.extend(bytexor(b, z))
|
|
160
162
|
return bytes(text)
|
|
161
163
|
|
|
162
|
-
def adv_ctr(self, z:
|
|
164
|
+
def adv_ctr(self, z: bytearray, ctrlen: int) -> bytes:
|
|
163
165
|
"Advance the counter."
|
|
164
|
-
|
|
165
|
-
for i in range(self.__class__.blocksize-1, self.__class__.blocksize-s-1, -1):
|
|
166
|
+
for i in range(self.__class__.blocksize-1, self.__class__.blocksize-ctrlen-1, -1):
|
|
166
167
|
c = z[i]+1
|
|
167
168
|
if c < 256:
|
|
168
|
-
|
|
169
|
+
z[i] = c
|
|
169
170
|
break
|
|
170
|
-
|
|
171
|
-
return
|
|
171
|
+
z[i] = 0
|
|
172
|
+
return z
|
|
172
173
|
|
|
173
|
-
def encrypt_ctr(self, text: bytes, iv: bytes | None = None) -> bytes:
|
|
174
|
+
def encrypt_ctr(self, text: bytes, ctrlen: int | None = None, nonce: bytes = b'', iv: bytes | None = None) -> bytes:
|
|
174
175
|
"Encrypt using CTR mode."
|
|
175
|
-
|
|
176
|
+
if ctrlen is None:
|
|
177
|
+
ctrlen = self.ctrlen
|
|
178
|
+
if ctrlen is None:
|
|
179
|
+
if self.blocksize >= 8:
|
|
180
|
+
ctrlen = 4
|
|
181
|
+
else:
|
|
182
|
+
ctrlen = 0 # use the entire iv as counter
|
|
183
|
+
assert 0 <= ctrlen <= self.__class__.blocksize, "Counter too long."
|
|
184
|
+
assert len(nonce) + ctrlen <= self.__class__.blocksize, "Nonce too long."
|
|
176
185
|
if iv is None:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
iv = randbytes(self.__class__.blocksize - ctrlen - len(nonce))# iv
|
|
187
|
+
iv = nonce + iv
|
|
188
|
+
assert len(iv) + ctrlen <= self.__class__.blocksize, "IV too long."
|
|
189
|
+
if ctrlen == 0 and len(iv) < self.__class__.blocksize:
|
|
190
|
+
ctrlen = self.__class__.blocksize - len(iv)
|
|
191
|
+
assert len(iv) + ctrlen == self.__class__.blocksize, "Length of nonce + iv + ctr do not match the blocksize."
|
|
192
|
+
ctr = bytearray(iv + b"\x00" * ctrlen)
|
|
193
|
+
if ctrlen == 0:
|
|
194
|
+
ctrlen = self.__class__.blocksize
|
|
195
|
+
|
|
196
|
+
ctext = bytearray(iv) # add nonce+iv as first block of the cipher text
|
|
181
197
|
for b in self.blocksplit(text, False):
|
|
198
|
+
ctr = self.adv_ctr(ctr, ctrlen)
|
|
182
199
|
z = self.encrypt_block(ctr)
|
|
183
200
|
ctext.extend(bytexor(b, z))
|
|
184
|
-
ctr = self.adv_ctr(ctr, self.__class__.blocksize)
|
|
185
201
|
return bytes(ctext)
|
|
186
202
|
|
|
187
|
-
def decrypt_ctr(self, ctext: bytes) -> bytes:
|
|
203
|
+
def decrypt_ctr(self, ctext: bytes, ctrlen: int | None = None, nonce: bytes = b'', iv: bytes | None = None) -> bytes:
|
|
188
204
|
"Decrypt using CTR mode."
|
|
205
|
+
if ctrlen is None:
|
|
206
|
+
ctrlen = self.ctrlen
|
|
207
|
+
if ctrlen is None:
|
|
208
|
+
if self.blocksize >= 8:
|
|
209
|
+
ctrlen = 4
|
|
210
|
+
else:
|
|
211
|
+
ctrlen = 0 # use the entire iv as counter
|
|
212
|
+
assert 0 <= ctrlen <= self.__class__.blocksize, "Counter too long."
|
|
213
|
+
assert len(nonce) + ctrlen <= self.__class__.blocksize, "Nonce too long."
|
|
214
|
+
if iv is None:
|
|
215
|
+
iv = ctext[:self.__class__.blocksize - ctrlen - len(nonce)]
|
|
216
|
+
ctext = ctext[self.__class__.blocksize - ctrlen - len(nonce):] # remove iv
|
|
217
|
+
iv = nonce + iv
|
|
218
|
+
assert len(iv) +ctrlen <= self.__class__.blocksize, "IV too long."
|
|
219
|
+
if ctrlen == 0 and len(iv) < self.__class__.blocksize:
|
|
220
|
+
ctrlen = self.__class__.blocksize - len(iv)
|
|
221
|
+
assert len(iv) + ctrlen == self.__class__.blocksize, "Length of nonce + iv + ctr do not match the blocksize."
|
|
222
|
+
ctr = bytearray(iv + b"\x00" * ctrlen)
|
|
223
|
+
if ctrlen == 0:
|
|
224
|
+
ctrlen = self.__class__.blocksize
|
|
225
|
+
|
|
189
226
|
text = bytearray(b'')
|
|
190
|
-
ctr = ctext[:self.__class__.blocksize] # iv
|
|
191
|
-
ctext = ctext[self.__class__.blocksize:] # remove iv
|
|
192
227
|
for b in self.blocksplit(ctext, False):
|
|
228
|
+
ctr = self.adv_ctr(ctr, ctrlen)
|
|
193
229
|
z = self.encrypt_block(ctr)
|
|
194
230
|
text.extend(bytexor(b, z))
|
|
195
|
-
ctr = self.adv_ctr(ctr, self.__class__.blocksize)
|
|
196
231
|
return bytes(text)
|
|
197
232
|
|
|
198
233
|
def mac_cbc(self, text: bytes, padding: bool = True) -> bytes:
|
|
@@ -286,21 +321,21 @@ class BlockCipher:
|
|
|
286
321
|
"Encrypt using Galois CTR mode."
|
|
287
322
|
assert self.__class__.blocksize == 16, "GHASH requires a blocksize of 16 bytes."
|
|
288
323
|
ctext = bytearray(b'')
|
|
289
|
-
|
|
324
|
+
ctrlen = self.__class__.blocksize // 4
|
|
290
325
|
if iv is None:
|
|
291
|
-
iv = randbytes(self.__class__.blocksize -
|
|
326
|
+
iv = randbytes(self.__class__.blocksize - ctrlen)
|
|
292
327
|
else:
|
|
293
328
|
assert len(iv) + \
|
|
294
|
-
|
|
295
|
-
ctr = iv + (
|
|
296
|
-
ctr0 = ctr
|
|
329
|
+
ctrlen == self.__class__.blocksize, "IV has inappropriate length!"
|
|
330
|
+
ctr = bytearray(iv + (ctrlen - 1) * b'\x00' + b'\x01')
|
|
331
|
+
ctr0 = bytes(ctr)
|
|
297
332
|
ctext.extend(iv)
|
|
298
333
|
h, len_block, tag = self._aad_helper(len(text), aad)
|
|
299
334
|
for b in self.blocksplit(text, 0):
|
|
300
|
-
ctr = self.adv_ctr(ctr,
|
|
335
|
+
ctr = self.adv_ctr(ctr, ctrlen)
|
|
301
336
|
z = self.encrypt_block(ctr)
|
|
302
337
|
ctext.extend(bytexor(b, z))
|
|
303
|
-
tag = self.ghash(ctext[self.__class__.blocksize -
|
|
338
|
+
tag = self.ghash(ctext[self.__class__.blocksize - ctrlen:], h, init=tag)
|
|
304
339
|
tag = self.ghash(len_block, h, init=tag).to_bytes(
|
|
305
340
|
self.__class__.blocksize, byteorder="big")
|
|
306
341
|
z = self.encrypt_block(ctr0)
|
|
@@ -311,11 +346,11 @@ class BlockCipher:
|
|
|
311
346
|
"Decrypt using Galois CTR mode."
|
|
312
347
|
assert self.__class__.blocksize == 16, "GHASH requires a blocksize of 16 bytes."
|
|
313
348
|
text = bytearray(b'')
|
|
314
|
-
|
|
315
|
-
iv = ctext[:self.__class__.blocksize -
|
|
316
|
-
ctr = iv + (
|
|
349
|
+
ctrlen = self.__class__.blocksize // 4
|
|
350
|
+
iv = ctext[:self.__class__.blocksize - ctrlen] # iv
|
|
351
|
+
ctr = bytearray(iv + (ctrlen - 1) * b'\x00' + b'\x01')
|
|
317
352
|
mac = ctext[-self.__class__.blocksize:] # mac
|
|
318
|
-
ctext = ctext[self.__class__.blocksize -
|
|
353
|
+
ctext = ctext[self.__class__.blocksize - ctrlen:-self.__class__.blocksize]
|
|
319
354
|
h, len_block, tag = self._aad_helper(len(ctext), aad)
|
|
320
355
|
tag = self.ghash(ctext, h, init=tag)
|
|
321
356
|
tag = self.ghash(len_block, h, init=tag).to_bytes(
|
|
@@ -324,7 +359,7 @@ class BlockCipher:
|
|
|
324
359
|
tag = bytexor(tag, z)
|
|
325
360
|
assert tag == mac, "Incorrect MAC!"
|
|
326
361
|
for b in self.blocksplit(ctext, 0):
|
|
327
|
-
ctr = self.adv_ctr(ctr,
|
|
362
|
+
ctr = self.adv_ctr(ctr, ctrlen)
|
|
328
363
|
z = self.encrypt_block(ctr)
|
|
329
364
|
text.extend(bytexor(b, z))
|
|
330
365
|
return bytes(text)
|
|
@@ -12,6 +12,11 @@ def dlog_rho(a: int, b: int, n: int, m: int = None, brent=0) -> int:
|
|
|
12
12
|
b %= n
|
|
13
13
|
if not m:
|
|
14
14
|
m = n - 1
|
|
15
|
+
else:
|
|
16
|
+
if pow(a, m, n) != 1:
|
|
17
|
+
raise ValueError("Incorrect order.")
|
|
18
|
+
if pow(b, m, n) != 1:
|
|
19
|
+
raise ValueError("DLP not solvable.")
|
|
15
20
|
trys = 10
|
|
16
21
|
max_iter = 10 * isqrt(m) # stop iterating and try a different start value
|
|
17
22
|
|
|
@@ -9,7 +9,7 @@ from random import randint
|
|
|
9
9
|
def factor_rho(n: int, x: int = 2, maxinit: int = 10, maxiter: int = 1000, brent: bool = True, verbose: int = 0) -> int | None:
|
|
10
10
|
"""Factor `n` using the Pollard's rho method with start value `x`."""
|
|
11
11
|
if not maxiter:
|
|
12
|
-
maxiter =
|
|
12
|
+
maxiter = 3 * isqrt(isqrt(n)) # stop iterating and try a different start value
|
|
13
13
|
|
|
14
14
|
def f(x: int) -> int:
|
|
15
15
|
return (pow(x, 2, n) + 2) % n
|
|
@@ -220,6 +220,12 @@ class Poly:
|
|
|
220
220
|
return self.__class__(list(map(func, self.coeff)), modulus = list(map(func, self.modulus)))
|
|
221
221
|
return self.__class__(list(map(func, self.coeff)), modulus = self.modulus, cyclic = self.cyclic)
|
|
222
222
|
|
|
223
|
+
def compress(self, d: int) -> list:
|
|
224
|
+
"Retun a list of compressed coefficients."
|
|
225
|
+
if not hasattr(self.coeff[0], "compress"):
|
|
226
|
+
raise ValueError("The unerlying ring does not seem to support compression.")
|
|
227
|
+
return [ c.compress(d) for c in self.coeff ]
|
|
228
|
+
|
|
223
229
|
def _check_type(self, other):
|
|
224
230
|
"Check if self and other can be added/multiplied."
|
|
225
231
|
return isinstance(other, int) or (isinstance(other, Number) and isinstance(self.coeff[0], Number)) or type(other) == type(self.coeff[0]) # pylint: disable=C0123
|
|
@@ -46,26 +46,28 @@ def test_AES():
|
|
|
46
46
|
|
|
47
47
|
# AES-128-CTR
|
|
48
48
|
k = bytes.fromhex('AE6852F8121067CC4BF7A5765577F39E')
|
|
49
|
-
|
|
49
|
+
nonce = bytes.fromhex("00000030")
|
|
50
|
+
iv = bytes.fromhex('0000000000000000')
|
|
50
51
|
m = bytes.fromhex('53696E676C6520626C6F636B206D7367')
|
|
51
52
|
c = bytes.fromhex('E4095D4FB7A7B3792D6175A3261311B8')
|
|
52
53
|
|
|
53
54
|
aes.set_key(k)
|
|
54
|
-
res = aes.encrypt_ctr(m, iv=iv)
|
|
55
|
-
assert res[
|
|
56
|
-
assert aes.decrypt_ctr(res) == m
|
|
55
|
+
res = aes.encrypt_ctr(m, nonce=nonce, iv=iv)
|
|
56
|
+
assert res[len(nonce) + len(iv):] == c
|
|
57
|
+
assert aes.decrypt_ctr(res, aes.blocksize - len(nonce) - len(iv)) == m
|
|
57
58
|
|
|
58
59
|
k = bytes.fromhex('7691BE035E5020A8AC6E618529F9A0DC')
|
|
59
|
-
|
|
60
|
+
nonce = bytes.fromhex("00E0017B")
|
|
61
|
+
iv = bytes.fromhex('27777F3F4A1786F0')
|
|
60
62
|
m = bytes.fromhex(
|
|
61
63
|
'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223')
|
|
62
64
|
c = bytes.fromhex(
|
|
63
65
|
'C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F')
|
|
64
66
|
|
|
65
67
|
aes.set_key(k)
|
|
66
|
-
res = aes.encrypt_ctr(m, iv=iv)
|
|
67
|
-
assert res[
|
|
68
|
-
assert aes.decrypt_ctr(res) == m
|
|
68
|
+
res = aes.encrypt_ctr(m, nonce=nonce, iv=iv)
|
|
69
|
+
assert res[len(nonce) + len(iv):] == c
|
|
70
|
+
assert aes.decrypt_ctr(res,aes.blocksize - len(nonce) - len(iv)) == m
|
|
69
71
|
|
|
70
72
|
# AES-128-GCM
|
|
71
73
|
k = bytes.fromhex('00000000000000000000000000000000')
|
|
@@ -79,6 +81,9 @@ def test_AES():
|
|
|
79
81
|
res = aes.encrypt_gcm(m, aad=aad, iv=iv)
|
|
80
82
|
assert res[12:-16] == c and res[-16:] == mac
|
|
81
83
|
assert aes.decrypt_gcm(res, aad=aad) == m
|
|
84
|
+
with pytest.raises(AssertionError):
|
|
85
|
+
assert aes.decrypt_gcm(res, aad= b'\x00') == m
|
|
86
|
+
|
|
82
87
|
|
|
83
88
|
k = bytes.fromhex('00000000000000000000000000000000')
|
|
84
89
|
iv = bytes.fromhex('000000000000000000000000')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|