Advertisement
fooker

chacha20

Jan 5th, 2024
840
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.32 KB | None | 0 0
  1. # https://en.wikipedia.org/wiki/Salsa20#ChaCha20_adoption
  2.  
  3. from Crypto.Util.number import long_to_bytes, bytes_to_long
  4. import secrets
  5.  
  6. def ROTL(a, b):
  7.     return (((a) << (b)) | ((a % 2**32) >> (32 - (b)))) % 2**32
  8.  
  9. def qr(x, a, b, c, d):
  10.     x[a] += x[b]; x[d] ^= x[a]; x[d] = ROTL(x[d],16)
  11.     x[c] += x[d]; x[b] ^= x[c]; x[b] = ROTL(x[b],12)
  12.     x[a] += x[b]; x[d] ^= x[a]; x[d] = ROTL(x[d], 8)
  13.     x[c] += x[d]; x[b] ^= x[c]; x[b] = ROTL(x[b], 7)
  14.  
  15. ROUNDS = 20
  16.  
  17. def chacha_block(inp):
  18.     x = list(inp)
  19.     for i in range(0, ROUNDS, 2):
  20.         qr(x, 0, 4, 8, 12)
  21.         qr(x, 1, 5, 9, 13)
  22.         qr(x, 2, 6, 10, 14)
  23.         qr(x, 3, 7, 11, 15)
  24.  
  25.         qr(x, 0, 5, 10, 15)
  26.         qr(x, 1, 6, 11, 12)
  27.         qr(x, 2, 7, 8, 13)
  28.         qr(x, 3, 4, 9, 14)
  29.  
  30.     return [(a+b) % 2**32 for a, b in zip(x, inp)]
  31.  
  32. def chacha_init(key, nonce, counter):
  33.     assert len(key) == 32
  34.     assert len(nonce) == 8
  35.  
  36.     state = [0 for _ in range(16)]
  37.     state[0] = bytes_to_long(b"expa"[::-1])
  38.     state[1] = bytes_to_long(b"nd 3"[::-1])
  39.     state[2] = bytes_to_long(b"2-by"[::-1])
  40.     state[3] = bytes_to_long(b"te k"[::-1])
  41.  
  42.     key = bytes_to_long(key)
  43.     nonce = bytes_to_long(nonce)
  44.  
  45.     for i in range(8):
  46.         state[i+4] = key & 0xffffffff
  47.         key >>= 32
  48.  
  49.     state[12] = (counter >> 32) & 0xffffffff
  50.     state[13] = counter & 0xffffffff
  51.     state[14] = (nonce >> 32) & 0xffffffff
  52.     state[15] = nonce & 0xffffffff
  53.  
  54.     return state
  55.  
  56. state = chacha_init(secrets.token_bytes(32), secrets.token_bytes(8), 0)
  57. buffer = b""
  58. def encrypt(data):
  59.     global state, buffer
  60.  
  61.     output = []
  62.     for b in data:
  63.         if len(buffer) == 0:
  64.             buffer = b"".join(long_to_bytes(x).rjust(4, b"\x00") for x in state)
  65.             state = chacha_block(state)
  66.         output.append(b ^ buffer[0])
  67.         buffer = buffer[1:]
  68.     return bytes(output)
  69.  
  70. flag = b"fake_flag{FAKE_FLAG}"
  71.  
  72. if __name__ == "__main__":
  73.     print("""This cipher is approved by Disk Jockey B.
  74.  
  75. 1. Encrypt input
  76. 2. Encrypt flag
  77. """)
  78.  
  79.     while True:
  80.         inp = input("> ")
  81.  
  82.         match inp:
  83.             case '1':
  84.                 print(encrypt(input("? ").encode()).hex())
  85.             case '2':
  86.                 print(encrypt(flag).hex())
  87.             case _:
  88.                 print("Bye!")
  89.                 exit()
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement