import base64
import hashlib
import os
import random
import signal


def parse_pbox(payload):
    return list(map(int, payload[1:-1].split(',')))


def permutate(payload, pbox):
    return bytes([payload[x] for x in pbox])


class Server:
    def __init__(self, password):
        assert len(password) == 16
        self.password = password

    def preauth(self):
        pbox = list(range(21))
        salt = os.urandom(4)
        random.shuffle(pbox)
        return pbox, salt

    def auth(self, pbox, salt, hashed_password):
        for pepper_int in range(256):
            pepper = bytes([pepper_int])
            permutated_password = permutate(self.password + salt + pepper, pbox)
            if hashlib.sha256(permutated_password).hexdigest() != hashed_password: continue
            return True
        return False


class Client:
    def __init__(self, password):
        self.password = password

    def spy(self, pbox, salt):
        assert set(pbox) == set(range(21))
        assert len(salt) == 4
        password = self.password
        pepper = os.urandom(1)
        permutated_password = permutate(password + salt + pepper, pbox)

        hashed_password = hashlib.sha256(permutated_password).hexdigest()
        print(f'🔑 {hashed_password}')


def work():
    challenge = os.urandom(8)
    print(f'🔧 {base64.b64encode(challenge).decode()}')
    response = base64.b64decode(input('🔩 '))
    h = hashlib.sha256(challenge + response).digest()
    return h.startswith(b'\x00\x00\x00')

def main():
    flag = os.environ.get('FLAG', 'hkcert21{***REDACTED***}')
    
    signal.alarm(60)
    password = base64.b64encode(os.urandom(12))

    s = Server(password)
    c = Client(password)

    for _ in range(50):
        command = input('🤖 ')
        try:
            if command == '🕵️':
                pbox = parse_pbox(input('😵 '))
                salt = base64.b64decode(input('🧂 '))
                c.spy(pbox, salt)
            elif command == '🖥️':
                pbox, salt = s.preauth()
                print(f'😵 {pbox}')
                print(f'🧂 {base64.b64encode(salt).decode()}')
                hashed_password = input('🔑 ')
                if not s.auth(pbox, salt, hashed_password):
                    raise Exception('No!')
                print(f'🏁 {flag}')
        except:
            print('😡')


if __name__ == '__main__':
    if work():
        main()
    else:
        print('😡')
