Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # https://en.wikipedia.org/wiki/Salsa20#ChaCha20_adoption
- from Crypto.Util.number import long_to_bytes, bytes_to_long
- import secrets
- def ROTL(a, b):
- return (((a) << (b)) | ((a % 2**32) >> (32 - (b)))) % 2**32
- def qr(x, a, b, c, d):
- x[a] += x[b]; x[d] ^= x[a]; x[d] = ROTL(x[d],16)
- x[c] += x[d]; x[b] ^= x[c]; x[b] = ROTL(x[b],12)
- x[a] += x[b]; x[d] ^= x[a]; x[d] = ROTL(x[d], 8)
- x[c] += x[d]; x[b] ^= x[c]; x[b] = ROTL(x[b], 7)
- ROUNDS = 20
- def chacha_block(inp):
- x = list(inp)
- for i in range(0, ROUNDS, 2):
- qr(x, 0, 4, 8, 12)
- qr(x, 1, 5, 9, 13)
- qr(x, 2, 6, 10, 14)
- qr(x, 3, 7, 11, 15)
- qr(x, 0, 5, 10, 15)
- qr(x, 1, 6, 11, 12)
- qr(x, 2, 7, 8, 13)
- qr(x, 3, 4, 9, 14)
- return [(a+b) % 2**32 for a, b in zip(x, inp)]
- def chacha_init(key, nonce, counter):
- assert len(key) == 32
- assert len(nonce) == 8
- state = [0 for _ in range(16)]
- state[0] = bytes_to_long(b"expa"[::-1])
- state[1] = bytes_to_long(b"nd 3"[::-1])
- state[2] = bytes_to_long(b"2-by"[::-1])
- state[3] = bytes_to_long(b"te k"[::-1])
- key = bytes_to_long(key)
- nonce = bytes_to_long(nonce)
- for i in range(8):
- state[i+4] = key & 0xffffffff
- key >>= 32
- state[12] = (counter >> 32) & 0xffffffff
- state[13] = counter & 0xffffffff
- state[14] = (nonce >> 32) & 0xffffffff
- state[15] = nonce & 0xffffffff
- return state
- state = chacha_init(secrets.token_bytes(32), secrets.token_bytes(8), 0)
- buffer = b""
- def encrypt(data):
- global state, buffer
- output = []
- for b in data:
- if len(buffer) == 0:
- buffer = b"".join(long_to_bytes(x).rjust(4, b"\x00") for x in state)
- state = chacha_block(state)
- output.append(b ^ buffer[0])
- buffer = buffer[1:]
- return bytes(output)
- flag = b"fake_flag{FAKE_FLAG}"
- if __name__ == "__main__":
- print("""This cipher is approved by Disk Jockey B.
- 1. Encrypt input
- 2. Encrypt flag
- """)
- while True:
- inp = input("> ")
- match inp:
- case '1':
- print(encrypt(input("? ").encode()).hex())
- case '2':
- print(encrypt(flag).hex())
- case _:
- print("Bye!")
- exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement