ECDSA


from ECurve import *


class ECDSA(object):

    def __init__(self, ECurve, P):
        self.ECurve = ECurve
        self.P = P
        self.n = P.order()
        self.h = len(self.ECurve) // self.n

    def GenKey(self, a=0):
        if a == 0:
            a = randrange(1, self.n - 1)
        return [a, P**a]

    def Sign(self, m, a):
        import EuclideanGCD
        import hashlib

        def randK():
            kinv = 0
            while(kinv == 0):
                k = randrange(1, self.n - 1)
                U = XEuclidean(k, self.n)
                if (U[2] > 1):
                    kinv = 0
                else:
                    kinv = int(U[0])
            return [k, kinv]
        H = hashlib.sha256()
        H.update(repr(m).encode('utf-8'))
        e = int(H.hexdigest(), 16)
        r = 0
        s = 0
        while ((r == 0) | (s == 0)):
            [k, kInv] = randK()
            kP = P**k
            r = int(kP[0]) % self.n
            s = (kInv * (e + r * a)) % self.n
            if (XEuclidean(s, self.n)[2] > 1):
                s = 0
        return [r, s]

    def Verify(self, m, sig, A):
        import hashlib
        import EuclideanGCD
        [r, s] = sig
        H = hashlib.sha256()
        H.update(repr(m).encode('utf-8'))
        e = int(H.hexdigest(), 16)
        w = int(XEuclidean(s, self.n)[0])
        print(w)
        u1 = (e * w) % self.n
        u2 = (r * w) % self.n
        Pt = (self.P)**u1 + A**u2
        return r == (int(Pt[0]) % self.n)

# Example

# SETUP
Ec = ECurve(2, [1, 0, 1, 0, 0, 1])
Ec.EquSSing([1, 1], [0, 1], [1, 1])
P = Ec.random()

Protocol = ECDSA(Ec, P)

[SK_Alice, PK_Alice] = Protocol.GenKey()
m = "Hello"
signature = Protocol.Sign(m, SK_Alice)
check = Protocol.Verify(m, signature, PK_Alice)