summaryrefslogtreecommitdiff
path: root/aesgcmanalysis.py
diff options
context:
space:
mode:
Diffstat (limited to 'aesgcmanalysis.py')
-rw-r--r--aesgcmanalysis.py40
1 files changed, 28 insertions, 12 deletions
diff --git a/aesgcmanalysis.py b/aesgcmanalysis.py
index abdfdb3..9e0d5b6 100644
--- a/aesgcmanalysis.py
+++ b/aesgcmanalysis.py
@@ -686,7 +686,8 @@ def find_b(n, basis, ct, mac, nonce, aad, oracle):
base[j*16:(j+1)*16] = xor(base[j*16:(j+1)*16], block)
idx += 1
-def compute_auth_key(ct, mac, nonce, mac_bytes, aad, oracle):
+def nonce_truncation_recover_secrets(ct, mac, nonce, mac_bytes, aad, oracle):
+ orig_ct = ct
ct = aad + ct
n = compute_n(ct)
assert n > (mac_bytes*8//2)
@@ -716,11 +717,23 @@ def compute_auth_key(ct, mac, nonce, mac_bytes, aad, oracle):
K = np.concatenate([K, incrK])
_, _, basisKerK = kernel(K, rref_mod_2)
X = np.array(basisKerK).transpose()
- print(len(basisKerK))
_, _, kerK = kernel(K, rref_mod_2)
assert len(kerK) == 1
h = kerK[0]
- return gf128_to_bytes(vec_to_gf128(h))
+
+ zero_tag = gf128_to_vec(bytes_to_gf128(gmac(vec_to_gf128(h), 0, aad, orig_ct)))[:mac_bytes*8]
+ gf128_mac = 0
+ i = 0
+ for b in mac:
+ for j in range(8):
+ if b & (1 << (7-j)):
+ gf128_mac += (1<<i)
+ i += 1
+ def small_gf128_to_vec(x):
+ return [int(n) for n in bin(x)[2:].zfill(mac_bytes*8)[::-1]]
+ mac_vec = small_gf128_to_vec(gf128_mac)
+ s = (np.array(zero_tag) - np.array(mac_vec)) % 2
+ return vec_to_gf128(h), vec_to_gf128(s)
# Demos
@@ -757,20 +770,23 @@ def forbidden_attack_demo():
assert succeeded
def nonce_truncation_demo():
- k = b'YELLOW_SUBMARINE'
+ # Should work with non-block size multiples.
+ # Need to modify to consider padding, but we can't mess with the bits in the padding,
+ # nor can we extend ad/ct unless we also change length block.
+ k = b'YELLOGIOJEWARINE'
aad = b'YELLOW_SUBMAFINERELLOWPUBMARINF_'
MACBYTES=1
- pt = b'CELERYPATCHWORKS'*(2**9)
+ pt = b'CELERYPATCHWORKS'*(2**5)
nonce = b'JORGELBORGES'
- ct, mac = gcm_encrypt(k, nonce, aad, pt, mac_bytes=MACBYTES)
+ ct, mac = gcm_encrypt(k, nonce, aad, pt)
+ # ct, mac = gcm_encrypt(k, nonce, aad, pt, mac_bytes=MACBYTES)
+ mac = mac[:1]
def oracle(base, aad, mac, nonce):
cipher = AES.new(k, mode=AES.MODE_GCM, nonce=nonce, mac_len=MACBYTES)
cipher.update(aad)
pt = cipher.decrypt_and_verify(base, mac)
- h = compute_auth_key(ct, mac, nonce, MACBYTES, aad, oracle)
- assert h == gf128_to_bytes(authentication_key(k))
-nonce_truncation_demo()
+ h, s = nonce_truncation_recover_secrets(ct, mac, nonce, MACBYTES, aad, oracle)
+ assert h == authentication_key(k)
+ return h, s
-# Try with different lengths
-# Make it so we chosoe to generate gen_t on the fly if needed
-# PRofiling
+nonce_truncation_demo()