import hashlib, random, secrets

# https://std.neuromancer.sk/nist/P-256
p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
G = (0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)
n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551

# flag
FLAG = 'sctf{????????????????????????????????????????????}'

def point_add(P1, P2):
    if P1 is None: return P2
    if P2 is None: return P1

    x1, y1 = P1
    x2, y2 = P2
    
    if x1 == x2 and (y1 + y2) % p == 0:
        return None
    
    if x1 == x2 and y1 == y2:
        m = (3 * x1 * x1 + a) * pow(2 * y1, -1, p)
    else:
        m = (y2 - y1) * pow(x2 - x1, -1, p)
        
    x3 = (m * m - x1 - x2) % p
    y3 = (m * (x1 - x3) - y1) % p
    return (x3, y3)

def point_mul(P1, k):
    result = None
    addend = P1
    while k:
        if k & 1:
            result = point_add(result, addend)
        addend = point_add(addend, addend)
        k >>= 1
    return result

def sign(priv, m):
    H = int(hashlib.sha256(m.encode()).hexdigest(), 16)
    while True:
        k = random.randint(1, n - 1)
        R = point_mul(G, k)
        r = R[0] % n
        if r == 0:
            continue
        break
    k_inv = pow(k, -1, n)
    s = (k_inv * (H + r * priv)) % n
    h = R[1] > (p//2)
    return r * (-1)**h, s

def start():
    global a

    maxturns = 128
    priv = secrets.randbelow(n)
    pub = point_mul(G, priv)
    print(f'{pub = }')

    for _ in range(maxturns):
        print('[Avernus]')
        print('1. Sign')
        print('2. shh..')
        
        i = int(input('> '))

        if i == 1:
            r, s = sign(priv, "ECDSA IS SUPER SECURE!!!")
            print(f'{r = }')
            print(f'{s = }')
            
        elif i == 2:
            a ^= 2**random.randint(1, 255)
        elif i == 1337:
            print('???')
            k = int(input('> '))
            if k == priv:
                print(FLAG)

if __name__ == '__main__':
    start()

