import sys
import os

sys.path.append(os.pardir)

from ch01.FieldElement import FieldElement
from ch02.Point import Point


# Prime constant
P = 2 ** 256 - 2 ** 32 - 977


class S256Field(FieldElement):
    def __init__(self, num, prime=None):
        super().__init__(num=num, prime=P)

    def __repr__(self):
        return "{:x}".format(self.num).zfill(64)


# Curve parameters
A = 0
B = 7

gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

# Order of subgroup generated by G
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141


class S256Point(Point):
    def __init__(self, x, y, a=None, b=None):
        a, b = S256Field(A), S256Field(B)
        if type(x) == int:
            super().__init__(x=S256Field(x), y=S256Field(y), a=a, b=b)
        else:
            super().__init__(x=x, y=y, a=a, b=b)

    def __rmul__(self, r):
        r = r % N
        return super().__rmul__(r)

    def __repr__(self):
        return 'S256Point({}, {})'.format(self.x, self.y)

G = S256Point(gx, gy)

# print(N * G)