documenting 2 keys outputing the same first 6 bytes
This commit is contained in:
parent
a7ea96648d
commit
49a9762802
78
main.py
78
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user