Exemplo n.º 1
0
def madd(p1,p2,A,B,p):
    """Adds p1 and p2 on a Montgomery curve"""
    if B*(A**2 - 4) == 0 % p: #checks Montgomery requirements
        print("Singular Curve")
        return
    if math.isinf(p1[0]) and math.isinf(p2[0]):
        return math.inf,1 #O + O = O
    if math.isinf(p1[0]): return p2 #O + p2 = p2
    if math.isinf(p2[0]): return p1 #p1 + O = p1
    else:
        x1,y1 = p1 #assigns coordinates
        x2,y2 = p2 #assigns coordinates
        if B*y1**2 % p != (x1**3 + A*x1**2 + x1) % p: #checks if point is on curve
            return False #otherwise reject
        if B*y2**2 % p != (x2**3 + A*x2**2 + x2) % p: #checks if point is on curve
            return False #otherwise reject
        if x1==x2 and -y2 % p == y1:
            return math.inf,1 #(x1,y1) + (x1,-y1) = O
        elif x1==x2:
            #point doubling
            sl = ((3 * x1**2 + 2*A*x1 + 1)*mminv(2*B*y1,p)) % p #slope
            x = (B*(sl**2) - 2*x1 - A) % p
            return x, (sl*(x1 - x) - y1) % p
        else:
            #point addition
            sl = (y2-y1)*mminv(x2-x1,p) % p #slope
            x = (B*(sl**2) - x1 - x2 - A) % p
            return x, (sl*(x1 - x) - y1) % p
def w2check(a, b, p):
    """Checks for point of order two on WNF curve"""
    """Returns x coordinate alpha if exists"""
    dis = -16 * (4 * a**3 + 27 * b**2) % p  #calculates discriminant
    ldis = legendres(dis, p)  #finds Legendre Symbol of discriminant
    if dis == 0:
        print("Discriminant = 0")  #rejects if discriminant is 0
        return
    if ldis % 2 == 1:
        #1 root if -1, 3 if 1, doing both cases here
        r = ((b**2) * mminv(4, p) +
             (a**3) * mminv(27, p)) % p  #using cubic formulae
        rt = modroot(r, p)  #sqrt of r
        if not rt:
            print(
                "No transformation")  #if sqrt does not exist, no alpha exists
            return
        else:
            rt = rt[0]  #assign one root to use in algebra
        bf = -b * mminv(2, p) % p  #cubic formulae
        alpha = (modcube(bf + rt, p) + modcube(bf - rt, p))  #cubic formulae
        if (alpha**3 + a * alpha + b) % p == 0:
            return alpha % p  #double checking value of alpha
        else:
            print("error")  #reject otherwise, output alpha for error checking
        return alpha % p
    else:
        print("No point of order two")
        return
Exemplo n.º 3
0
def wadd(p1,p2,a,b,p):
    """Adds p1 and p2 on a WNF curve"""
    if math.isinf(p1[0]) and math.isinf(p2[0]):
        return math.inf,1 #O + O = O
    if math.isinf(p1[0]): return p2 #O + p2 = p2
    if math.isinf(p2[0]): return p1 #p1 + O = p1
    else:
        x1,y1 = p1 #assigns coordinates
        x2,y2 = p2 #assigns coordinates
        if y1**2 % p != (x1**3 + a*x1 + b) % p: #checks if point is on curve
            return False #otherwise reject
        if y2**2 % p != (x2**3 + a*x2 + b) % p: #checks if point is on curve
            return False #otherwise reject
        if x1==x2 and -y2 % p == y1:
            return math.inf,1 #(x1,y1) + (x1,-y1) = O
        elif x1==x2:
            #point doubling
            sl = ((3 * x1**2 + a)*mminv(2*y1,p)) % p #slope
            x = (sl**2 - x1 - x2) % p 
            return x, -(sl * (x - x1) + y1) % p
        else:
            #point addition
            sl = (y2-y1)*mminv(x2-x1,p) % p #slope
            x = (sl**2 - x1 - x2) % p
            return x, -(sl * (x - x1) + y1) % p
def pmtoe(p1, A, B, p):
    """Transforms a Montgomery point to a twisted Edwards point"""
    start = time.process_time() * 1000
    if A < 3 % p and A > -2 % p:  #checks requirements on A for curve mapping
        print("A in {-2,2}")  #if fails, reject
        return False
    elif B == 0 % p:  #checks requirements on B for curve mapping
        print("B = 0")  #if fails, reject
        return False
    x1, y1 = p1  #assigns coordinates
    if math.isinf(x1): return 0, 1  #inf -> (0,1)
    if B * y1**2 % p != (x1**3 + A * x1**2 +
                         x1) % p:  #checks if point is on curve
        return False  #otherwise reject
    #exceptional points
    elif y1 == 0 % p:
        print(y1)
        if x1 == 0 % p: return 0, -1 % p  #(0,0) -> (0,-1)
        elif 2 * x1 % p == (-A + modroot((A + 2) * (A - 2), p)[0]) % p:
            return math.inf, 2  #point of order two on M -> inf ('positive' root)
        elif 2 * x1 % p == (-A - modroot((A + 2) * (A - 2), p)[0]) % p:
            return math.inf, -2  #point of order two on M -> inf ('negative' root)
        else:
            return
    elif x1 == -1 % p:
        if y1 == modroot((A - 2) * mminv(B, p), p):
            return math.inf, 4  #point of order four on M -> inf ('positive' root)
        elif y1 == -modroot((A - 2) * mminv(B, p), p) % p:
            return math.inf, -4  #point of order four on M -> inf ('negative' root)
    #general points
    else:
        print(time.process_time() * 1000 - start)
        return x1 * mminv(y1, p) % p, (x1 - 1) * mminv(x1 + 1, p) % p
def petow(p1, a, d, p):
    """Transforms a twisted Edwards point to a Weierstrass point"""
    if a == d:  #checks curve mapping requirements
        print("a=d")  #if fails, reject
        return
    elif a == 0 or d == 0:
        print("Must be non zero")
        return
    x1, y1 = p1  #assigns coordinates
    #exceptional points
    if math.isinf(x1):
        #computes inf seperately, since may be (inf,4) or (inf,2)
        p2 = petom(p1, a, d,
                   p)  #computes point at infinity -> point on montgomery
        A, B = (2 * (a + d) * mminv(a - d, p)) % p, (
            4 * mminv(a - d, p)) % p  #calculates A and B
        p3 = pmtow(p2, A, B, p)  #computes point on montgomery -> point on W
        return p3
    if (a * x1**2 + y1**2) % p != (1 + d * (x1**2) *
                                   (y1**2)) % p:  #checks point is on curve
        return False  #otherwise reject
    elif x1 % p == 0 and y1 % p == 1:
        return math.inf, 1  #(0,1) -> inf -> inf
    else:
        p2 = petom(p1, a, d, p)  #computes point on Montgomery
        A, B = (2 * (a + d) * mminv(a - d, p)) % p, (
            4 * mminv(a - d, p)) % p  #calculates A and B
        p3 = pmtow(p2, A, B, p)  #computes point on W
        return p3
def mtow(A, B, p):
    """Converts Montgomery curve to WNF"""
    #conversion always exists - no need to check
    start = time.process_time() * 1000
    a = ((3 - A**2) * mminv(3 * B**2, p)) % p  #calculates a
    b = ((2 * A**3 - 9 * A) * mminv(27 * B**3, p)) % p  #calculates b
    print("y**2 = x**3 + ", a, "x +", b)  #prints curve equation
    print("An Isomorphism!")  #all existing W to M mappings are isomorphisms
    print(time.process_time() * 1000 - start)
    return a, b
def pmtow(p1, A, B, p):
    """Transforms a Montgomery point to a Weierstrass point"""
    start = time.process_time() * 1000
    x1, y1 = p1  #assigns coordinates
    if B * y1**2 % p != (x1**3 + A * x1**2 +
                         x1) % p:  #checks if point is on curve
        return False  #otherwise reject
    #exceptional points
    if math.isinf(x1):
        print(time.process_time() * 1000 - start)
        return math.inf, 1  #inf -> inf
    #general points
    else:
        print(time.process_time() * 1000 - start)
        return (x1 * mminv(B, p) + A * mminv(3 * B, p)) % p, y1 * mminv(B,
                                                                        p) % p
def etom(a, d, p):
    """Converts twisted Edwards to Montgomery"""
    """Checks for conversion"""
    #start = time.process_time() *1000
    if a == d:  #checks parameters distinct
        print("a=d")  #otherwise reject
        return
    elif a == 0 or d == 0:  #checks parameters non zero
        print("Must be non zero")  #otherwise reject
        return
    A = (2 * (a + d) * mminv(a - d, p)) % p  #calculates A
    B = (4 * mminv(a - d, p)) % p  #calculates B
    print(B, "y**2 = x**3 +", A, "x**2 + x")  #prints curve equation
    if legendres(a, p) == legendres(d, p):
        print("Not an Isomorphism :("
              )  #not isomorphic if a & d both square/not square
    elif legendres(a, p) == 1:
        print("An Isomorphism!")  #isomorphic if a square, d not square
    #print(time.process_time()*1000 - start)
    return A, B
def mtoe(A, B, p):
    """Converts Montgomery curve to twisted Edwards"""
    """Checks for conversion"""
    #start = time.process_time()*1000
    if A < 3 % p and A > -2 % p:  #checks requirement of A
        print("A in {-2,2}")  #if fails, reject
        return
    elif B == 0 % p:  #checks B non zero
        print("B = 0")  #otherwise reject
        return
    a = ((A + 2) * mminv(B, p)) % p  #calculates a
    d = ((A - 2) * mminv(B, p)) % p  # calculates d
    print(a, "x**2 + y**2 = 1 + ", d, "x**2y**2")  #prints curve equation
    if legendres(a, p) == legendres(d, p):
        print("Not an Isomorphism :("
              )  #not isomorphic if a & d both square/not square
    elif legendres(a, p) == 1:
        print("An Isomorphism!")  #isomorphic if a square, d not square
    elif legendres(a, p) == -1:
        print("Not an Isomorphism :(")  #not isomorphic if a not square

# print(time.process_time()*1000 - start)
    return a, d
Exemplo n.º 10
0
def eadd(p1,p2,a,d,p):
    """
    Adds p1 and p2 on a twsited Edwards curve
    We assume that there exists a pt of order 4, so identity is (0,1)
    """
    if d*(1 - d) == 0 % p: #checks Edwards requirements
        print("Singular Curve")
        return
    x1,y1 = p1
    x2,y2 = p2 #check if in curve here
    if (a*x1**2 + y1**2) % p != (1 + d*(x1**2)*(y1**2)) % p: #checks point is on the curve
        return False #otherwise reject
    if (a*x2**2 + y2**2) % p != (1 + d*(x2**2)*(y2**2)) % p: #checks point is on the curve
        return False #otherwise reject
    if p1 == (0,1) and p2 == (0,1):
        return 0,1 #O + O = O
    if p1 == (0,1): return p2 #O + p2 = p2
    if p2 == (0,1): return p1 #p1 + O = p2
    if y1==y2 and -x2 % p == x1: #(x1, y1) + (-x1, y1) = O
        return 0,1
    else:
        #point addition
        dxy = d*x1*x2*y1*y2 % p
        return (x1*y2 + y1*x2)*mminv(1+dxy,p) % p, (y1*y2 - a*x1*x2)*mminv(1-dxy,p) % p
def petom(p1, a, d, p):
    """Transforms a twisted Edwards point to a Montgomery point"""
    if a == d:  #checks curve mapping requirements
        print("a=d")  #if fails, reject
        return False
    elif a == 0 or d == 0:
        print("Must be non zero")
        return False
    x1, y1 = p1  #assigns coordinates
    #exceptional points
    if math.isinf(x1):
        A = (2 * (a + d) * mminv(a - d, p)) % p  #calculates A
        B = (4 * mminv(a - d, p)) % p  #calculates B
        if y1 % p == 2:
            x = (-A + modroot((A + 2) * (A - 2), p)[0]) * mminv(
                2, p) % p  #point of order two on M ('positive' root)
            return x, 0
        elif y1 % p == -2 % p:
            x = (-A - modroot((A + 2) * (A - 2), p)[0]) * mminv(
                2, p) % p  #point of order two on M ('negative' root)
            return x, 0
        elif y1 % p == 4:
            y = modroot((A - 2) * mminv(B, p),
                        p)  #point of order four on M ('positive' root)
            return -1, y
        elif y1 % p == -4 % p:
            y = -modroot((A - 2) * mminv(B, p),
                         p) % p  #point of order four on M ('negative' root)
            return -1, y
        else:
            return  #no other points at infinity should exist on a twisted Edwards curve
    if (a * x1**2 + y1**2) % p != (1 + d * (x1**2) *
                                   (y1**2)) % p:  #checks point is on the curve
        return False  #otherwise reject
    elif x1 % p == 0 and y1 % p == 1:
        return math.inf, 1  #(0,1) -> inf
    elif x1 % p == 0 and y1 % p == -1 % p:
        return 0, 0  #(0,-1) -> (0,0)
        #general points
    else:
        return (1 + y1) * mminv(1 - y1, p) % p, (1 + y1) * mminv(
            x1 * (1 - y1), p) % p
def wtom(a, b, p):
    """Converts WNF curve to Montgomery"""
    """Checks for conversion"""
    start = time.process_time() * 1000
    alpha = w2check(a, b, p)  #finds point of order two on W
    if not alpha:
        print("No conversion")  #if no such point, reject
        return
    else:
        if not modroot(3 * alpha**2 + a, p):  #checks if square root exists
            print("No conversion")  #otherwise, reject
            return
        B = mminv(max(modroot(3 * alpha**2 + a, p)), p)  #calulates B
        A = 3 * alpha * B % p  #calulates A
        print(B, "y**2 = x**3 +", A, "x**2 + x")  #prints curve equation
        print(
            "An Isomorphism!")  #all existing W to M mappings are isomorphisms
        print(time.process_time() * 1000 - start)
        return A, B, alpha
def pwtom(p1, a, b, p, A, B):
    """Transforms a Weierstrass point to a Montgomery point"""
    x1, y1 = p1  #assigns coordinates
    if math.isinf(p1[0]): return math.inf, 1  #inf -> inf
    if y1**2 % p != (x1**3 + a * x1 + b) % p:  #checks if point is on curve
        return False  #otherwise reject
    if not A:  #if user does not input A, calulates it
        s, alpha = wtom(a, b, p)[1], wtom(a, b,
                                          p)[2]  #finds B, alpha from wtom
        if not alpha:  #checks if a point of order two exists
            print("No conversion")  #otherwise reject
            return
    else:
        alpha = A * mminv(3 * B,
                          p) % p  #if user inputs A,B calculate alpha from them
        s = B  #as above
    #exceptional points
    if p1 == (alpha, 0):
        return 0, 0  #if point has order two, map to 0,0
        #general points
    else:
        return s * (x1 - alpha) % p, s * y1 % p