#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3 python3Packages.pwntools

from pwn import *
from pathlib import Path

addr, port, *_ = "mercury.picoctf.net 36449".split(" ")

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]

def unhex(hex: str) -> list[int]:
    return [int(x, 16) for x in chunks(hex, 2)]

def xor_bytes(a: bytes, b: bytes) -> bytes:
    assert len(a) == len(b)
    return bytes(x ^ y for x, y in zip(a, b))

KEYLEN = 50000

def conn():
    if args.REMOTE:
        return remote(addr, int(port))
    else:
        return process([str(Path(__file__).parent / "otp.py")])

def main():
    r = conn()
    r.recvuntil(b'This is the encrypted flag!\n')
    enc_flag = r.recvline().strip()
    print(f"{enc_flag=}")

    flag_len = len(enc_flag) // 2
    assert flag_len % 2 == 0

    remaining_bytes_until_key_reset = KEYLEN - flag_len

    r.recvuntil(b'What data would you like to encrypt? ')
    r.sendline(b'A'*remaining_bytes_until_key_reset)

    # Ignore output, we're only trying to make the program
    # reset the key offset

    r.recvuntil(b'What data would you like to encrypt? ')
    payload = b"A" * flag_len
    r.sendline(payload)
    r.recvuntil(b'Here ya go!\n')
    response = r.recvline().strip()

    key = xor_bytes(payload, unhex(response))
    print(f"{key=}")

    flag = xor_bytes(unhex(enc_flag), key).decode().strip()
    print(f"picoCTF{{{flag}}}")

if __name__ == "__main__":
    main()
