Commit cd6a0638 authored by GUILLEVIC Aurore's avatar GUILLEVIC Aurore

classes for CocksPinch curves: k=6 D=3, k=8 D=4, other k,D

parent 32c9fea8
This diff is collapsed.
This diff is collapsed.
# New Cocks-Pinch curves with rho = 2 but optimal ate pairing available.
# k=5 or k=7
# any j possible
import sage
from exceptions import ValueError
from sage.functions.log import log
from sage.functions.other import ceil
from sage.functions.other import sqrt
from sage.arith.misc import XGCD, xgcd
from sage.rings.integer import Integer
from sage.rings.finite_rings.finite_field_constructor import FiniteField
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field
from sage.schemes.elliptic_curves.constructor import EllipticCurve
from sage.misc.functional import cyclotomic_polynomial
import PairingFriendlyCurve
from PairingFriendlyCurve import print_parameters, print_parameters_for_RELIC
from PairingFriendlyCurve import get_curve_generator_order_r
class CocksPinch_k(EllipticCurve_finite_field):
"""
A Cocks-Pinch curve of embedding degree k (=5,7), any given D, rho>=2 and optimal ate pairing available.
"""
def __init__(self, k, T, D, exp_tr, p, r, tr, y, a, b):
"""
:param k : embedding degree
:param T : seed
:param exp_tr: integer such that tr = u^exp_tr + 1 mod r
:param a : curve parameter in E: y^2 = x^3 + a*x + b
:param b : curve parameter in E: y^2 = x^3 + a*x + b
:param p : prime, field characteristic
:param r : prime, divides the curve order
:param tr : trace of the curve
:param y : integer s.t. p = (tr^2 + D*y^2)/4
"""
#T = Integer(u)
self._k = int(k) # embedding degree
self._D = Integer(D) # curve discriminant
self._a = Integer(a)
self._b = Integer(b)
self._u = Integer(T)
self._i = int(exp_tr)
self._r = Integer(r)
self._p = Integer(p)
self._tr= Integer(tr)
self._y = Integer(y)
#self.polynomial_r = [1,1,1,1,1] # 1+u+u^2+u^3+u^4
self.polynomial_r = cyclotomic_polynomial(self._k).list()
r_ = sum([Integer(self.polynomial_r[i])*self._u**i for i in range(len(self.polynomial_r))])
if self._r != r_:
raise ValueError("Error: r does not match the polynomial r(T)\nr = {:= #x} #(input)\nr = {:= #x} # from polynomial r(T) = {}".format(r_,self._r,self.polynomial_r))
else:
print("valid r")
# can check that tr mod r = T^i mod r...
if ((self._p+1-self._tr) % self._r) != 0:
raise ValueError("Error: p+1-tr mod r != 0,\np+1-tr={}\np ={}\nr ={}\ntr ={}\np+1-tr % r = {}\n".format((self._p+1-self._tr), self._p, self._r, self._tr, ((self._p+1-self._tr) % self._r) ))
self._c = (self._p+1-self._tr) // self._r
self._pbits = self._p.nbits()
try:
self._Fp = FiniteField(self._p)
except ValueError as err:
print("ValueError creating Fp: {}".format(err))
raise
except:
print("Error creating Fp")
raise
if not self._r.is_prime():
raise ValueError("Error r is not prime")
self._Fpz = PolynomialRing(self._Fp, names=('z',))
(self._z,) = self._Fpz._first_ngens(1)
self._ap = self._Fp(a)
self._bp = self._Fp(b)
try:
# this init function of super inherits from class EllipticCurve_generic defined in ell_generic.py
# __init__ method inherited from ell_generic
EllipticCurve_finite_field.__init__(self, self._Fp, [0,0,0,self._ap,self._bp])
except ValueError as err:
print("ValueError at EllipticCurve_finite_field.__init__: {}".format(err))
raise
except:
print("An error occured when initialising the elliptic curve")
raise
if self._pbits <= 384:
print("check curve order")
self.order_checked = super(CocksPinch_k,self).order()
if self.order_checked != (self._p+1-self._tr):
#if (self.order_checked % self._r) != 0:
print("Error, wrong order")
raise ValueError("Wrong curve order: this one is a twist")
else:
print("check order (randomized because pnbits = {})".format(self._pbits))
self.curve_order = self._p + Integer(1) - self._tr
self.twist_order = self._p + Integer(1) + self._tr
for i in range(10):
P = self.random_element()
if self.curve_order*P != self(0):
if self.twist_order*P == self(0):
raise ValueError("Wrong curve order: this one is a twist: (p+1+tr)*P = 0\ntr={}\np+1-tr={}\np+1+tr={}\n".format(self._tr,self.curve_order,self.twist_order))
else:
print("computing actual curve order to compare")
self.order_checked = super(CocksPinch_k,self).order()
raise ValueError("Wrong curve order:\np+1-tr = {}\np+1+tr = {}\nchecked order = {}\np = {}".format(self.curve_order,self.twist_order,self.order_checked,self._p))
print("ok")
# computes a generator
#print("compute a generator")
self._G = get_curve_generator_order_r(self)
self._Gx = self._G[0]
self._Gy = self._G[1]
def _repr_(self):
return "CP"+str(self._k)+" p"+str(self._pbits)+" (modified Cocks-Pinch k="+str(self._k)+") curve with seed "+str(self._u)+"\n"+super(CocksPinch_k,self)._repr_()
def u(self):
return self._u
def p(self):
return self._p
def r(self):
return self._r
def c(self):
return self._c
def tr(self):
return self._tr
def y(self):
return self._y
def a(self):
return self._a # 0
def ap(self):
return self._ap # 0
def b(self):
return self._b # Integer
def bp(self):
return self._bp # in Fp (finite field element)
def beta(self):
return None
def lamb(self):
return None
def k(self):
return self._k
def Fp(self):
return self._Fp
def Fpz(self):
return self._Fpz, self._z
def G(self):
return self._G
def print_parameters(self):
PairingFriendlyCurve.print_parameters(self)
def print_parameters_for_RELIC(self):
PairingFriendlyCurve.print_parameters_for_RELIC(self)
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment