plexcryptool/src/trash-hash.py

101 lines
3.0 KiB
Python
Raw Normal View History

2023-04-21 22:54:21 +02:00
#!/usr/bin/env python3
"""
Dirty hash we were covered in an excercise for Week 16 of 2023 in cryptography
"""
import math
import random
2023-04-22 00:48:06 +02:00
DEFINED_INITIAL = bytearray(b'\xa5\xa5\xa5\xa5\x5a\x5a\x5a\x5a\x55\x55\x55\x55\xaa\xaa\xaa\xaa')
# the hash we want to find in the preimage attacks
# comes from 'AAAA'
THE_HASH = bytearray(b'\xe4\xe4\xe4\xe4\xa5\xa5\xa5\xa5\xaa\xaa\xaa\xaa\x55\x55\x55\x55')
2023-04-21 22:54:21 +02:00
def trash_hash(input: bytearray) -> bytearray:
2023-04-21 23:48:36 +02:00
#print("original len is %s" % len(input))
2023-04-21 22:54:21 +02:00
# extend with 0xff if length is not multiple of 16
while len(input) % 16 != 0:
input.append(0xff)
# set n
n: int = math.ceil(len(input)/16)
2023-04-21 23:48:36 +02:00
#print("len is %s" % len(input))
#print("n is %s" % n)
2023-04-21 22:54:21 +02:00
# cut input into blocks with size 16
blocks = [bytearray(16)] * n # initializes with 0x00s
# print the empty blocks
#for block in blocks:
# print("block: %s" % block.hex())
#print('='*80)
for i in range(0, n):
blocks[i] = input[i*16:i*16 + 16]
# print the filled blocks
#for block in blocks:
# print("block: %s" % block.hex())
# initilaize accumulator A_0 with the following constant values:
2023-04-21 23:13:04 +02:00
A = DEFINED_INITIAL
2023-04-21 22:54:21 +02:00
# iterate over blocks
for index, block in enumerate(blocks):
if index == 0:
pass
2023-04-21 23:13:04 +02:00
thing = bytes(by0 ^ by1 for by0, by1 in zip(A, block))
A = bytearray(thing)
2023-04-21 22:54:21 +02:00
2023-04-21 23:13:04 +02:00
return A
2023-04-21 22:54:21 +02:00
2023-04-21 23:13:04 +02:00
def use():
payload_a = bytearray(b"AAAA")
2023-04-21 23:48:36 +02:00
# works, but is too cheap
#payload_b = bytearray(b"AAAA\xff\xff")
payload_b = bytearray(b'\xb2\xef\x82t<~<\xbe\x8d\xca\xe2\t\xdc7E\x10')
print("a: %s\nb: %s" % (trash_hash(payload_a).hex(), trash_hash(payload_b).hex()))
print("identical: %s" % test_collision(payload_a, payload_b))
2023-04-22 00:48:06 +02:00
def test_collision(a: bytearray, b: bytearray) -> bool:
return trash_hash(a) == trash_hash(b)
def test_against_hash(input: bytearray, target_hash: bytearray) -> bool:
hashed = trash_hash(input)
print("hashed variant:\t%s" % hashed.hex())
print("should be:\t%s" % THE_HASH.hex())
return trash_hash(input) == target_hash
def first_preimage():
print("Trying to find a message that produces %s" % THE_HASH.hex())
# a xor b = c
# c xor b = a
target = bytearray(b'\ff' * 16)
input = bytearray(b'\00' * 16)
between = bytearray(16)
# this is an arbituary target
# should work for anything
target[0] = ord('A')
for i in range(0, 16):
between[i] = target[i] ^ THE_HASH[i]
input[i] = between[i] ^ THE_HASH[i]
print(test_against_hash(input, THE_HASH))
def main():
first_preimage()
2023-04-21 23:48:36 +02:00
def bruteForce() -> bool:
payload_a = bytearray(b"AAAA")
foundCollision = False
while not foundCollision:
current = bytearray(random.randbytes(16))
foundCollision = test_collision(payload_a, current)
if random.randint(1, 65535) % 65535 == 0:
print(current)
print("found one!")
print(current)
return True
2023-04-21 23:13:04 +02:00
2023-04-21 22:54:21 +02:00
if __name__ == "__main__":
main()