Facebook
From Astrageldon, 2 Weeks ago, written in Python.
Embed
Download Paste or View Raw
Hits: 200
  1. import re, random, functools, base64, os, itertools
  2. from say_my_name import HeisenbergMatrix, HeisenbergGroup
  3. from __params import N, M, L
  4.  
  5. from Crypto.Util.number import *
  6. from Crypto.Cipher import AES
  7. from random import randint as ri
  8.  
  9. pad = lambda s, l: s + bytes([ri(0,31) * bool(i) for i in range(l - len(s))])
  10. unpad = lambda s: s[:s.index(b'\x00')] if b'\x00' in s else s
  11. prod = lambda arr: functools.reduce(lambda a, b: a * b, arr)
  12.  
  13.  
  14. def conjugate(w1, w2):
  15.     return w2.inverse() * w1 * w2
  16.  
  17. def commutator(w1, w2):
  18.     return w1.inverse() * w2.inverse() * w1 * w2
  19.  
  20. def encode(s):
  21.     return base64.b64encode(s.encode()).decode()
  22.  
  23. def decode(s):
  24.     return base64.b64decode(s.encode()).decode()
  25.  
  26. def parsearr(s):
  27.     return [HeisenbergMatrix.fromstr(x) for x in decode(s).split('|')]
  28.  
  29. def parse(s):
  30.     return HeisenbergMatrix.fromstr(decode(s))
  31.  
  32. def group(s):
  33.     return encode('|'.join(map(repr, s)))
  34.  
  35.  
  36. def load_data():
  37.     global set_A, set_B, pub_A, pub_B, enc
  38.     directory = os.path.join(".", "intercepted_data")
  39.     with open(os.path.join(directory, "set_A.txt"), 'r') as f:
  40.         set_A = parsearr(f.read())
  41.     with open(os.path.join(directory, "set_B.txt"), 'r') as f:
  42.         set_B= parsearr(f.read())
  43.     with open(os.path.join(directory, "pub_A.txt"), 'r') as f:
  44.         pub_A = parsearr(f.read())
  45.     with open(os.path.join(directory, "pub_B.txt"), 'r') as f:
  46.         pub_B = parsearr(f.read())
  47.     with open(os.path.join(".", "encrypted"), 'rb') as f:
  48.         enc = f.read()
  49.  
  50. def oracle(key):
  51.     key = key.c&(2**128 - 1)
  52.     aes = AES.new(long_to_bytes(key, 16), AES.MODE_ECB)
  53.     dec = unpad(aes.decrypt(enc))
  54.     return b'Dear Bob,' in dec, dec
  55.  
  56. def test(priv_set_A, k_A):
  57.     L_A = []
  58.     priv_A = prod([word ** k for word, k in zip(priv_set_A, k_A)])
  59.     for word, k in zip(priv_set_A, k_A):
  60.         i = set_A.index(word)
  61.         w = pub_B[i] ** k
  62.         L_A.append(w)
  63.     K_A = priv_A * prod(L_A).inverse()
  64.     return K_A, oracle(K_A)
  65.  
  66. def bruteforce():
  67.     for idx_A in itertools.permutations(range(M), L):
  68.         for k_A in itertools.product([1, -1], repeat = L):
  69.             print('\rProgress: %s %s' % (idx_A, k_A), end = '')
  70.             priv_set_A = list(map(set_A.__getitem__, idx_A))
  71.             result, (succ, dec) = test(priv_set_A, k_A)
  72.             if succ:
  73.                 return result, dec
  74.  
  75. load_data()
  76.  
  77. key, dec = bruteforce()
  78. print('\n\n')
  79. if key:
  80.     print("Common Key Found: \033[32m%s\033[0m" % key)
  81.     print()
  82.     print("Message:\n\033[32m%s\033[0m" % dec.decode(encoding = 'utf-8', errors = 'ignore'))
  83. else:
  84.     print("\033[31mFailed\033[0m")