#!/usr/bin/env python3
import argparse
import re
import socket

MASK = 0xffffffff

def response(x, round_number):
    if round_number == 1:
        return ((x * 0x1337) ^ 0xdeadbeef) & MASK
    if round_number == 2:
        return (((x << 5) | (x >> 27)) + 0xcafebabe) & MASK
    if round_number == 3:
        x ^= 0x31337
        for i in range(16):
            x = ((x << 1) ^ (x >> 31) ^ (i * 0xa5a5a5a5)) & MASK
        return x
    raise ValueError('unexpected round')

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('host')
    parser.add_argument('port', type=int)
    args = parser.parse_args()
    with socket.create_connection((args.host, args.port), timeout=10) as sock:
        stream = sock.makefile('rb')
        for rnd in range(1, 4):
            line = stream.readline()
            match = re.fullmatch(rb'CHALLENGE_(\d+): (\d+)\s*', line)
            if not match or int(match[1]) != rnd:
                raise ValueError(f'unexpected challenge: {line!r}')
            answer = response(int(match[2]), rnd)
            sock.sendall(f'RESPONSE_{rnd}: {answer}\n'.encode())
        print(stream.read().decode(), end='')

if __name__ == '__main__':
    main()
