from math import gcd from random import randint, randbytes H = 18446744073709551614 K = 59275109328752 M = 2**64 def Rjb(j: int, b: int) -> int: return b << j**2 def Rb(b: int) -> int: Rb = 0 for j in range(8): Rb ^= Rjb(j, b) return Rb ''' Returns a hashmap (python dictionary) of b -> R(b) for all b such that: min < b < max ''' def precompute_R(min: int, max: int) -> dict[int, int]: b = min R_table = {} while b <= max: R_table[b] = Rb(b) b += 1 return R_table def hashfn(x: bytes, R_table: dict[int, int]) -> int: h = -2 for i in range(len((x))): b = x[i] h = h**2 * (b+1) + ((K * (i+1)) ^ R_table[b]) h %= M return h % M def bcrypt(x: bytes) -> int: h = 18446744073709551614 for (i, b) in enumerate(x): h *= h * (b + 1) k = 59275109328752 * (i + 1) for j in range(8): k ^= b << (j * j) h += k h %= (2 ** 64) return h def debug_hashes_eq(x: bytes, R_table: dict[int, int]) -> bool: return hashfn(x, R_table) == bcrypt(x) def debug_test_random_hashes(trials: int, max_bytes: int = 16, quiet: bool = False) -> bytes | None: R_table = precompute_R(0, 255) for i in range(trials): # generate random bytes num_bytes = randint(0, max_bytes) x = randbytes(num_bytes) # test the modified bcrypt with the original hash_test = hashfn(x, R_table) hash_bcrypt = bcrypt(x) if hash_test != hash_bcrypt: if not quiet: print(f'Your hashfn sucks, big mistake bucko!! (iter: {i})') print(hash_test) print(hash_bcrypt) print([str(b) for b in x]) return x if not quiet: print('Impeccable hashfn holy moly!!') return None def main() -> None: print(f'gcd(H,K): {gcd(H,K)}') print(f'gcd(H,M): {gcd(H,M)}') print(f'gcd(K,M): {gcd(K,M)}') if debug_test_random_hashes(10000) != None: R_table = precompute_R(0, 255) x = bytes(input('x: '), 'utf-8') hash_test = hashfn(x, R_table) hash_bcrypt = bcrypt(x) print(f'hashfn: {hash_test}') print(f'bcrypt: {hash_bcrypt}') # a = bytes(input("A: "), 'utf-8') # b = bytes(input("B: "), 'utf-8') # if a != b and hashfn(a) == hashfn(b): # print('*** YOU WIN ***') # elif a == b: # print('Idiot those are the same') # else: # print("Trivially false!") if __name__ == '__main__': try: main() except KeyboardInterrupt: print('\n[!] Received SIGINT') except EOFError: print('\n[!] Reached EOF')