示例#1
0
 def __init__(self,
              A=1,
              C=1):  #, Ap24 = None, Am24 = None, C24 = None, ap24 = None
     if isinstance(A, GFp2element):
         self.A = A
     else:
         self.A = GFp2element(A, 0)
     if isinstance(C, GFp2element):
         self.C = C
     else:
         self.C = GFp2element(C, 0)
     self.Ap24 = self.A + self.C * 2
     self.Am24 = self.A - self.C * 2
     self.C24 = self.C * 4
     self.ap24 = self.Ap24 // self.C
示例#2
0
 def seta(self, p, q, d):
     """
     Recover Montgomery curve coefficient A as well as aux curve constants from P, Q, P-Q x-coordinates
     Alg. 10 in [SIKE]
     :param p:
     :param q:
     :param d:
     :return: None
     """
     t1 = p + q
     t0 = p * q
     A = d * t1
     A = A + t0
     t0 = t0 * d
     A = A - 1
     t0 = t0 + t0
     t1 = t1 + d
     t0 = t0 + t0
     A = A * A
     t0 = t0.modinv()
     A = A * t0
     A = A - t1
     self.A = A
     self.C = GFp2element(1)
     self.Ap24 = self.A + self.C * 2
     self.Am24 = self.A - self.C * 2
     self.C24 = self.C * 4
     self.ap24 = self.Ap24 // self.C
示例#3
0
 def __init__(self, X, Z, parent):
     self.parent = parent
     assert (isinstance(X, GFp2element))
     self.X = X
     #        self.Y = Y
     if not Z is None:
         self.Z = Z
     else:
         self.Z = GFp2element(1)
示例#4
0
 def ladder3pt(self, m, xP, xQ, xD):
     """
     Montgomery's ladder. Calculates x(P+[m]Q) given m and x-coordinates of P, Q, D=Q-P
     Alg. 9 in [SIKE]
     :param m:
     :param xP:
     :param xQ:
     :param xD:
     :return:
     """
     p0 = MontgomeryPoint(xQ, GFp2element(1), self)
     p1 = MontgomeryPoint(xP, GFp2element(1), self)
     p2 = MontgomeryPoint(xD, GFp2element(1), self)
     self.ap24 = (self.A + 2) // 4
     while m > 0:
         if m % 2 == 1:
             [p0, p1] = self.xdbladd(p0, p1, p2)
         else:
             [p0, p2] = self.xdbladd(p0, p2, p1)
         m = m // 2
     return p1
示例#5
0
def ParseParameters(params):
    global p, e2, e3, f, xp2, xq2, xr2, xp3, xq3, xr3, A, C, E0
    e2 = params['eA']
    e3 = params['eB']
    f = params['f']
    # Very first step -- initialization of the modulus
    modulo_initialize((2**e2) * (3**e3) * f - 1)
    A = GFp2element(params['A'][0], params['A'][1])
    E0 = MontgomeryCurve(A, GFp2element(1))
    xp2 = GFp2element(params['xp2'][0], params['xp2'][1])
    xq2 = GFp2element(params['xq2'][0], params['xq2'][1])
    xr2 = GFp2element(params['xr2'][0], params['xr2'][1])
    xp3 = GFp2element(params['xp3'][0], params['xp3'][1])
    xq3 = GFp2element(params['xq3'][0], params['xq3'][1])
    xr3 = GFp2element(params['xr3'][0], params['xr3'][1])
示例#6
0
 def iso3e(self, e3, S1, X11=None, X22=None, X33=None):
     """
     Compute and optionally evaluate a 3^e-isogeny
     Alg. 18 from [SIKE]
     :param e3: 
     :param S1: 
     :param X11: 
     :param X22: 
     :param X33: 
     :return: 
     """
     S = S1
     if not X11 is None:
         X1 = MontgomeryPoint(X11, GFp2element(1), self)
     else:
         X1 = None
     if not X22 is None:
         X2 = MontgomeryPoint(X22, GFp2element(1), self)
     else:
         X2 = None
     if not X33 is None:
         X3 = MontgomeryPoint(X33, GFp2element(1), self)
     else:
         X3 = None
     curve = None
     for e in range(e3 - 1, -1, -1):  #
         T = S.mul3e(e)
         [curve, K1, K2] = self.iso3_curve(T)
         if not e == 0:
             S = self.iso3_eval(K1, K2, S, curve)
         if not X1 is None:
             X1 = self.iso3_eval(K1, K2, X1, curve)
         if not X2 is None:
             X2 = self.iso3_eval(K1, K2, X2, curve)
         if not X3 is None:
             X3 = self.iso3_eval(K1, K2, X3, curve)
     return [curve, X1, X2, X3]
示例#7
0
    def iso2e(self, e2, S1, X11=None, X22=None, X33=None):
        """
        Compute and optionally evaluate a 2^e2-isogeny

        :param e2:
        :param S1:
        :param X11:
        :param X22:
        :param X33:
        :return:
        """
        S = S1
        if not X11 is None:
            X1 = MontgomeryPoint(X11, GFp2element(1), self)
        else:
            X1 = None
        if not X22 is None:
            X2 = MontgomeryPoint(X22, GFp2element(1), self)
        else:
            X2 = None
        if not X33 is None:
            X3 = MontgomeryPoint(X33, GFp2element(1), self)
        else:
            X3 = None
        curve = None
        for e in range(e2 - 1, -1, -1):
            T = S.mul2e(e)
            curve = self.iso2_curve(T)
            if not e == 0:
                S = self.iso2_eval(T, S, curve)
            if not X1 is None:
                X1 = self.iso2_eval(T, X1, curve)
            if not X2 is None:
                X2 = self.iso2_eval(T, X2, curve)
            if not X3 is None:
                X3 = self.iso2_eval(T, X3, curve)
        return [curve, X1, X2, X3]
示例#8
0
 def iso2eby4(self, e2, S, X11=None, X22=None, X33=None):
     """
     Compute and optionally evaluate a 2^e2-isogeny
     Alg. 17 from [SIKE]
     :param e2:
     :param S1:
     :param X11:
     :param X22:
     :param X33:
     :return:
     """
     if not X11 is None:
         X1 = MontgomeryPoint(X11, GFp2element(1), self)
     else:
         X1 = None
     if not X22 is None:
         X2 = MontgomeryPoint(X22, GFp2element(1), self)
     else:
         X2 = None
     if not X33 is None:
         X3 = MontgomeryPoint(X33, GFp2element(1), self)
     else:
         X3 = None
     curve = None
     for e in range(e2 - 2, -2, -2):
         T = S.mul2e(e)
         [curve, K1, K2, K3] = self.iso4_curve(T)
         if not e == 0:
             S = self.iso4_eval(K1, K2, K3, S, curve)
         if not X1 is None:
             X1 = self.iso4_eval(K1, K2, K3, X1, curve)
         if not X2 is None:
             X2 = self.iso4_eval(K1, K2, K3, X2, curve)
         if not X3 is None:
             X3 = self.iso4_eval(K1, K2, K3, X3, curve)
     return [curve, X1, X2, X3]
示例#9
0
def isoex3(sk3, e3, pk):
    """
    Generate shared key in 3^e3-torsion
    Alg. 24 from [SIKE]
    :param sk3: Bob's secret key
    :param e3: Power of 3
    :param pk: Alice's public key encoded as three points
    :return:  j-invariant of the shared curve
    """
    curve = MontgomeryCurve(GFp2element(1))
    x1 = pk[0]
    x2 = pk[1]
    x3 = pk[2]
    curve.seta(x1, x2, x3)
    s = curve.ladder3pt(sk3, x1, x2, x3)
    [image, _, _, _] = curve.iso3e(e3, s)
    return image.jinv()
示例#10
0
def isoex2(sk2, e2, pk):
    """
    Generate shared key in 2^e2-torsion
    Alg. 23 from [SIKE]
    :param sk2: Alice's secret key
    :param e2: Power of 2
    :param pk: Bob's public key encoded as three points
    :return: j-invariant of the shared curve
    """
    curve = MontgomeryCurve(GFp2element(1))
    x1 = pk[0]
    x2 = pk[1]
    x3 = pk[2]
    curve.seta(x1, x2, x3)
    s = curve.ladder3pt(sk2, x1, x2, x3)
    [image, _, _, _] = curve.iso2eby4(e2, s)
    return image.jinv()
示例#11
0
class MontgomeryPoint:
    X = GFp2element(0)
    Z = GFp2element(1)
    parent = None

    def getx(self):
        assert (not self.Z == 0)
        return self.X // self.Z

    def __init__(self, X, Z, parent):
        self.parent = parent
        assert (isinstance(X, GFp2element))
        self.X = X
        #        self.Y = Y
        if not Z is None:
            self.Z = Z
        else:
            self.Z = GFp2element(1)

    def __str__(self):
        return ('(' + str(self.X) + ' : ' + str(self.Z) + '); x = ' +
                str(self.X // self.Z))

    def __repr__(self):
        return ('(' + str(self.X) + ' : ' + str(self.Z) + '); x = ' +
                str(self.X // self.Z))

    def __add__(self, other):
        pass

    def mul2(self):
        """
        Montgomery point x-only multiplication by 2
        Alg. 3 from [SIKE]
        :return:
        """
        t0 = self.X - self.Z
        t1 = self.X + self.Z
        t0 = t0 * t0
        t1 = t1 * t1
        z = t0 * self.parent.C24
        x = z * t1
        t1 = t1 - t0
        t0 = t1 * self.parent.Ap24
        z = z + t0
        z = z * t1
        return MontgomeryPoint(x, z, self.parent)

    def mul3(self):
        """
        Montgomery point x-only multiplication by 3
        Alg. 6 from [SIKE]
        :return:
        """
        t0 = self.X - self.Z
        t2 = t0 * t0
        t1 = self.X + self.Z
        t3 = t1 * t1
        t4 = t1 + t0
        t0 = t1 - t0
        t1 = t4 * t4
        t1 = t1 - t3
        t1 = t1 - t2
        t5 = t3 * self.parent.Ap24
        t3 = t5 * t3
        t6 = t2 * self.parent.Am24
        t2 = t2 * t6
        t3 = t2 - t3
        t2 = t5 - t6
        t1 = t2 * t1
        t2 = t3 + t1
        t2 = t2 * t2
        x = t2 * t4
        t1 = t3 - t1
        t1 = t1 * t1
        z = t1 * t0
        return MontgomeryPoint(x, z, self.parent)

    def mul2e(self, e):
        """
        e-repeated Montgomery point x-only multiplication by 2
        Alg. 4 from [SIKE]
        :return:
        """
        res = MontgomeryPoint(self.X, self.Z, self.parent)
        for i in range(0, e):
            res = res.mul2()
        return res

    def mul3e(self, e):
        """
        e-repeated Montgomery point x-only multiplication by 3
        Alg. 7 from [SIKE]
        :return:
        """
        res = MontgomeryPoint(self.X, self.Z, self.parent)
        for i in range(0, e):
            res = res.mul3()
        return res