import random
from point import Point

'''
'secp256k1',
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
a=0,
b=7,
g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
# Subgroup order.
n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
# Subgroup cofactor.
h=1,
'''

# y2 = x3 + ax + b
class Curve:
    
    def __init__(self, p, a, b, gx, gy, n, h):
        # размер конечного поля
        self.p = p
        # коэффиценты уравнения a и b
        self.a = a
        self.b = b
        # базовая точка
        self.g = Point(
            curve = self,
            x = gx,
            y = gy
        )
        # порядок подруппы
        self.n = n
        # кофактор подгруппы
        self.h = h

    def point(self, x, y):
        return Point(
            curve = self,
            x = x,
            y = y
        )

    # Обратное деление по модулю p кривой
    def inverseMod(self, k, point):
        if k == 0:
            raise ZeroDivisionError('division by zero')
        if k < 0:
            # k ** -1 = p - (-k) ** -1  (mod p)
            return point - self.inverseMod(-k, point)
        # Расширенный алгоритм Евклида
        s, old_s = 0, 1
        t, old_t = 1, 0
        r, old_r = point, k
        while r != 0:
            quotient = old_r // r
            old_r, r = r, old_r - quotient * r
            old_s, s = s, old_s - quotient * s
            old_t, t = t, old_t - quotient * t
        gcd, x, y = old_r, old_s, old_t
        #assert gcd == 1
        #assert (k * x) % p == 1
        return x % point

    def randomKeypair(self):
        keyPriv = random.randrange(1, self.n)
        keyPub = self.g * keyPriv
        return keyPriv, keyPub

    def keyPub(self, keyPriv):
        return self.g * keyPriv

#################################

c = Curve(
    p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
    a = 0,
    b = 7,
    gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
    gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
    n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
    h = 1
)

# 0x774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb, 
# 0xd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b
#pub = c.keyPub(11)

#print(pub.show())

#exit(0)

aPriv, aPub = c.randomKeypair()
bPriv, bPub = c.randomKeypair()

print(hex(aPriv))
print(aPub.show())

#aS = scalar_mult(alice_private_key, bob_public_key)
aS = bPub * aPriv
bS = aPub * bPriv

print(aS.show())
print(bS.show())