From 49a976280259622a4955aa3e3a3e43a2442de72e Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Wed, 24 Apr 2024 09:55:49 +0200 Subject: [PATCH] documenting 2 keys outputing the same first 6 bytes --- main.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 4d0d0cd..ea31a7f 100755 --- a/main.py +++ b/main.py @@ -87,7 +87,7 @@ def css_encrypt(text, key): def test_encrypt(): print("test encryption: text 0xffffffffff, key 0x0 ∈ {0, 1}^40") - cipher = int.from_bytes(css_encrypt(0xffffffffff, [0]*40), byteorder='big') + cipher = int.from_bytes(css_encrypt(0xffffffffff, [0]*40)) print(f'cipher: {hex(cipher)}') clear = int.from_bytes(css_encrypt(cipher, [0]*40)) print(f'decrypted: {hex(clear)}') @@ -167,29 +167,89 @@ def attack(Bytes=gen_6_bytes()): for process in processes: process.join() - while not result_queue.empty(): - key = result_queue.get() - print(f'key found: \t{key}') - return [int(bit) for bit in key] + key = result_queue.get() + print(f'key found: \t{key}') + return [int(bit) for bit in key] def test_attack(n=1): success = 0 print(f'testing attack in 2^16 against CSS {n} times (keys randomly generated each time)\n') for _ in range(n): key = [randint(0, 1) for _ in range(40)] - # key = [1]*40 key_string = ''.join(str(bit) for bit in key) print(f'key generated: \t{key_string}') Bytes = gen_6_bytes(key) found_key = attack(Bytes) + failed = [] if found_key == key: success += 1 + else: + failed.append(key) print() print(f'{success}/{n} success') + if len(failed)>0: + print("fails:") + for key in failed: + print("".join(str(bit) for bit in key)) + +def test_fail(): + taps17 = [0, 14] + taps25 = [0, 3, 4, 12] + key = [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1] + key2 = [1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0] + print(f'both of these keys seem to output the same first 6 bytes, it only differs starting from byte 7:\n{"".join(str(bit) for bit in key)}\n{"".join(str(bit) for bit in key2)}\n') + lfsr17 = lfsr(key[:16]+[1], taps17) + lfsr172 = lfsr(key2[:16]+[1], taps17) + lfsr25 = lfsr(key[16:]+[1], taps25) + lfsr252 = lfsr(key2[16:]+[1], taps25) + x = [] + y = [] + x2 = [] + y2=[] + for _ in range(7): + x_bin = "" + y_bin = "" + x_bin2 = "" + y_bin2 = "" + for _ in range(8): + x_bin += str(lfsr17.shift()) + y_bin += str(lfsr25.shift()) + x_bin2 += str(lfsr172.shift()) + y_bin2 += str(lfsr252.shift()) + x.append(int(x_bin[::-1], 2)) + y.append(int(y_bin[::-1], 2)) + x2.append(int(x_bin2[::-1], 2)) + y2.append(int(y_bin2[::-1], 2)) + print(f'LFSR outputs with 1st key: lfsr17: {x} lfsr25: {y}') + print(f'LFSR outputs with 2nd key: lfsr17: {x2} lfsr25: {y2}\n') + c = 0 + c2 = 0 + for i in range(7): + s = x[i]+y[i]+c + if s>255: + c=1 + else: + c=0 + s2 = x2[i]+y2[i]+c2 + if s2>255: + c2=1 + else: + c2=0 + print(f'8bits addition at step {i} equal for both keys: {s%256}={s2%256} : {s%256==s2%256}') + + text = 0xffffffffffff + cipher = int.from_bytes(css_encrypt(text, key)) + cipher2 = int.from_bytes(css_encrypt(text, key)) + print(f'\nencrypting 0xffffffffffff (6 bytes)\nwith 1st key: {hex(cipher)}\nwith 2nd key: {hex(cipher2)}\nboth outputs are equal: {cipher==cipher2}\n') test_lfsr17() -print() +print("\n") test_encrypt() -print() -test_attack(5) +print("\n") +# time to test attack with 100 keys +# CPU: 6 cores at 3.8GHz +# ~65 seconds +test_attack(10) +print("\n") +test_fail()