Esempio n. 1
0
def test_python(p, i1, i2, number=0, repeat=3):
    import compositum as c
    K = GF(p)
    P = K.extension(i1, 'x')
    R, phi, phinv = c.ffext(P, i2)
    
    a = P.random_element()
    c = R.random_element()
    d = R.random_element()
    context = globals()
    context.update(locals())
    tembed = sage_timeit('phi(a)', context, number=number, repeat=repeat, seconds=True)
    tproject = sage_timeit('phinv(c)', context, number=number, repeat=repeat, seconds=True)
    tmul = sage_timeit('c*d', context, number=number, repeat=repeat, seconds=True)

    return tembed, tproject, tmul
Esempio n. 2
0
class Curve:
    def __init__(self, f, n, N, a, ext):
        self.f = f
        self.n = n
        self.N = N
        self.p = 2**n*N*f - 1
        self.Fp = GF(self.p)
        self.Fpx = self.Fp['x']; x = self.Fpx.gen()
        self.Fp2 = self.Fp.extension(x**2+ext, 'u')
        self.a = self.Fp2(a)
        self.cof_P = (self.p+1)//self.N

    def __repr__(self):
        return 'Montgomery curve defined by y^2 = x^3 + (' + repr(self.a) + ')*x^2 + x over ' + repr(self.Fp2)

    __str__ = __repr__

    def random_point(self, k=1, twist=False) :
        '''
        INPUT:
        * k = 1 or 2 if you want a point defined over Fp or Fp2
        OUTPUT:
        * [x,1] a random point on the montgomery curve, in the xz-model
        '''
        F = self.Fp2 if k==2 else self.Fp
        x = F.random_element()
        #strange trick for generalize with twist
        while not(F(x**3+self.a*x**2+x).is_square()) != twist :
            x = F.random_element()
        #self is not the curve if twist=True, but anyway
        return point.Point(x, F(1), self)

    def weierstrass(self) :
        '''
        INPUT:

        OUTPUT:
        * E the elliptic curve in Weierstrass model (y^2 = x^3+a*x+b)
        '''
        return EllipticCurve(self.Fp2, [1-(self.a**2)/3, self.a*(2*(self.a**2)/9-1)/3])

    def power_of_2_order_random_point(self, k, extension_field = 2, twist = False) :
        
            # INPUT:
            # * k an integer
            # * extension_field an integer
            # * twist a boolean
            # OUTPUT:
            # * R a point of the curve or its twist, of order 2**k, defined over \F_{p^k}, given in the Montgomery model
        
        if (k > self.n) :
            raise RuntimeError('there is no point of order 2^%d over Fp^%d' % (k, extension_field))
        cof = (self.p+1) // (2**k)

        if extension_field == 1 :
            # E(Fp) \simeq ZZ / ((p+1)/2) ZZ \times ZZ / 2 ZZ
            # there is no point of order 2^curve.n
            if k == self.n :
                raise RuntimeError('impossible to get a point of order 2^%d over Fp' % k)
            else :
                # we need to divide by 2 the cofactor because of the ZZ / 2 ZZ part above
                cof = cof // 2
        R = cof * self.random_point(extension_field, twist)
        while not(R.is_power_of_2_order_point(k)) :
            R = cof * self.random_point(extension_field, twist)
        return R

    def pairing_group_random_point(self, extension_degree = 2, twist = False) :
        '''
        INPUT:
        * extension_degree an integer
        * twist a boolean
        OUTPUT:
        * a point of order self.N defined over self.Fp^extension_degree defined over the curve or its twist.
        '''
        R = self.cof_P * self.random_point(extension_degree, twist)
        while R.z == 0 :
            R = self.cof_P * self.random_point(extension_degree, twist)
        return R

    def getPointFromWeierstrass(self, P) :
        '''
        INPUT:
        * P a point on the Weierstrass curve
        OUTPUT:
        * the corresponding point on the montgomery curve, in the xz-model
        '''
        if P[2] == 0 :
            return point.Point(1, 0, self)
        if P[2] == 1 :
            return point.Point(P[0] - self.a/3, 1, self)
        X, Y, Z = P[0]/P[2], P[1]/P[2], 1
        return self.getPointFromWeierstrass([X,Y,Z])
Esempio n. 3
0
class Curve:
    def __init__(self, f, n, N, a, ext, Delta, strategy):
        self.f = f
        self.n = n
        self.N = N
        self.p = 2**n * N * f - 1
        self.Fp = GF(self.p)
        self.Fpx = self.Fp['x']
        x = self.Fpx.gen()
        self.Fp2 = self.Fp.extension(x**2 + ext, 'u')
        self.a = self.Fp2(a)
        self.Delta = Delta
        self.cof_P = (self.p + 1) // self.N
        self.strategy = strategy

    def __repr__(self):
        return 'Montgomery curve defined by y^2 = x^3 + (' + repr(
            self.a) + ')*x^2 + x over ' + repr(self.Fp2)

    __str__ = __repr__

    def random_point(self, k=1, twist=False):
        '''
        INPUT:
        * k = 1 or 2 if you want a point defined over Fp or Fp2
        OUTPUT:
        * [x,1] a random point on the montgomery curve, in the xz-model
        '''
        F = self.Fp2 if k == 2 else self.Fp
        x = F.random_element()
        #strange trick for generalize with twist
        while not (F(x**3 + self.a * x**2 + x).is_square()) != twist:
            x = F.random_element()
        #self is not the curve if twist=True, but anyway
        return point.Point(x, F(1), self)

    def weierstrass(self):
        '''
        INPUT:

        OUTPUT:
        * E the elliptic curve in Weierstrass model (y^2 = x^3+a*x+b)
        '''
        return EllipticCurve(
            self.Fp2,
            [1 - (self.a**2) / 3, self.a * (2 * (self.a**2) / 9 - 1) / 3])

    def power_of_2_order_random_point(self, k, extension_field=2, twist=False):
        '''
            INPUT:
            * k an integer
            * extension_field an integer
            * twist a boolean
            OUTPUT:
            * R a point of the curve or its twist, of order 2**k, defined over \F_{p^k}, given in the Montgomery model
        '''
        if (k > self.n):
            raise RuntimeError('there is no point of order 2^%d over Fp^$d' %
                               (k, extension_field))
        cof = (self.p + 1) // (2**k)

        if extension_field == 1:
            # As  E(Fp) \simeq ZZ / ((p+1)/2) ZZ \times ZZ / 2 ZZ
            # there is no point of order 2^curve.n
            if k == self.n:
                raise RuntimeError(
                    'impossible to get a point of order 2^%d over Fp' % k)
            else:
                # we need to divide by 2 the cofactor because of the ZZ / 2 ZZ part above
                cof = cof // 2
        R = cof * self.random_point(extension_field, twist)
        while not (R.is_power_of_2_order_point(k)):
            R = cof * self.random_point(extension_field, twist)
        return R

    def pairing_group_random_point(self, extension_degree=2, twist=False):
        '''
        INPUT:
        * extension_degree an integer
        * twist a boolean
        OUTPUT:
        * a point of order self.N defined over self.Fp^extension_degree defined over the curve or its twist.
        '''
        R = self.cof_P * self.random_point(extension_degree, twist)
        while R.z == 0:
            R = self.cof_P * self.random_point(extension_degree, twist)
        return R

    def getPointFromWeierstrass(self, P):
        '''
        INPUT:
        * P a point on the Weierstrass curve
        OUTPUT:
        * the corresponding point on the montgomery curve, in the xz-model
        '''
        if P[2] == 0:
            return point.Point(1, 0, self)
        if P[2] == 1:
            return point.Point(P[0] - self.a / 3, 1, self)
        X, Y, Z = P[0] / P[2], P[1] / P[2], 1
        return self.getPointFromWeierstrass([X, Y, Z])

    @staticmethod
    def strategy(n, p, q):
        '''
        INPUT:
        * n the height of the tree
        * p the cost of one multiplication step
        * q the cost of one isogeny step
        OUTPUT:
        * a list corresponding to a strategy
        REMARK:
        from Luca De Feo's answer on crypto.stackexchange.com
        '''
        S = {1: []}
        C = {1: 0}
        for i in range(2, n + 2):
            b, cost = min(((b, C[i - b] + C[b] + b * p + (i - b) * q)
                           for b in range(1, i)),
                          key=lambda t: t[1])
            S[i] = [b] + S[i - b] + S[b]
            C[i] = cost
        return S[n + 1]