Commit 7c7ed08f authored by GUILLEVIC Aurore's avatar GUILLEVIC Aurore
Browse files

in curve parameter files, add polynomials as global variables

parent d3b0a565
......@@ -13,6 +13,21 @@ from sage.schemes.elliptic_curves.constructor import EllipticCurve
import PairingFriendlyCurve
from PairingFriendlyCurve import get_curve_parameter_b_j0, get_curve_generator_order_r_j0
# do not import these parameters, use "import BLS12" then "BLS12.Px"
Px = [1, 1, 0, 2, 0, -2, 1]
Px_den = 3
Rx = [1, 0, -1, 0, 1]
Rx_den = 1
Cx = [1, -2, 1]
Cx_den = 3
Tx = [1, 1]
Tx_den = 1
Yx = [1, -1, -2, 2]
Yx_den = 3
BETAx = [1, -1, 0, 3, -3, 1]
BETAx_den = 1
LAMBx = [-1, 0, 1]
LAMBx_den = 1
class BLS12(EllipticCurve_finite_field):
"""
......
import sage
from exceptions import ValueError
from sage.functions.log import log
from sage.functions.other import ceil
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
import PairingFriendlyCurve
from PairingFriendlyCurve import get_curve_parameter_b_j0, get_curve_generator_order_r_j0
# do not import these parameters, use "from BLS6 import Px,Rx,Cx,Tx
Px = [1, 0, 4, -3, 1] # px = (1/3) * (x^4 - 3*x^3 + 4*x^2 + 1)
Px_den = 3
Rx = [1, -1, 1] # rx = x^2 - x + 1
Rx_den = 1
Cx = [1, -2, 1] # cx = (x - 1)^2 / 3 = (x^2 -2*x + 1)/3
Cx_den = 3
Tx = [1, 1] # tx = x+1
Tx_den = 1
Yx = [1, -3, 2] # yx = (1/3) * (2*x^2 - 3*x + 1)
Yx_den = 3
BETAx = [-2, 5, -4, 1]# bx = (1/3) * (x^3 - 4*x^2 + 5*x - 2)
BETAx_den = 3
LAMBx = [-1, 1] # (-x) and (x-1) are 3-th roots of unity mod rx
LAMBx_den = 1
class BLS6(EllipticCurve_finite_field):
"""
A Barreto-Lynn-Scott curve of embedding degree k=6, here rho = 2 because p has degree 4 and r has degree 2.
This is only to compare to MNT curves.
Discriminant D=3
if x=1 mod 3 then rx = x^2-x+1, px and cx = (x^2-2*x+1)/3 are integers
if x=2 mod 3 then rx = (x^2-x+1)/3, px and cx = (x^2-2*x+1) are integers
if x=0 mod 3 then px is not an integer
"""
def __init__(self, u, b=None):
"""
u is the seed such that p=P_BLS6(u), and b is the curve coefficient, s.t. y^2 = x^3 + b has a subgroup of order r=R_BLS6(u)
(there are two possible choices for b: b, 1/b (a twist) but only one has order r)
"""
self._k = 6 # embedding degree
self._a = 0 # first curve parameter is 0 because j=0
self._D = 3
# polynomials (will be needed later for polynomial selection)
# P_BLS6 = (1/3) * (x^4 - 3*x^3 + 4*x^2 + 1) # = (x-1)^2*(x^2-x+1)/3 + x
# if x=1 mod 3:
# R_BLS6 = x^2 - x + 1
# C_BLS6 = (1/3) * (x - 1)^2 # cofactor such that p+1-tr == c*r
# if x=2 mod 3:
# R_BLS6 = (x^2 - x + 1)/3
# C_BLS6 = (x - 1)^2 # cofactor such that p+1-tr == c*r
# T_BLS6 = x + 1
# Y_BLS6 = (x-1)*(2*x-1)/3 # = (2*x^2 - 3*x + 1)/3
# Y such that T^2 - 4*P = -3*Y^2
# BETA_BLS6 = (1/3) * (x - 2) * (x - 1)^2 # Bx^2+Bx+1 = 0 mod Px
# LAMB_BLS6 = x-1 # Lx^2+Lx+1 = 0 mod Rx
# do not divides by 3 so that it has integer coeffs.
# pb type with 1/3 (as an int, it is 0) -> uses Integer(1)/Integer(3)
self.polynomial_p = [1, 0, 4, -3, 1]
self.polynomial_p_denom = Integer(3)
self.polynomial_r = [1, -1, 1]
self.polynomial_c = [1, -2, 1]
if (u % 3) == 1:
self.polynomial_r_denom = Integer(1)
self.polynomial_c_denom = Integer(3)
elif (u % 3) == 2:
self.polynomial_r_denom = Integer(3)
self.polynomial_c_denom = Integer(1)
else:
raise ValueError("error for BLS6 curve to have integer parameters p,r,t, the seed u should satisfy u=1,2 mod 3 but u={: #x}={} mod 3 given".format(u, (u%3)))
self.polynomial_tr = [1, 1]
self.polynomial_tr_denom = Integer(1)
self.polynomial_y = [1, -3, 2]
self.polynomial_y_denom = Integer(3)
#self.polynomial_beta = [-2, 5, -4, 1]
self.polynomial_beta = [-1, -5, 4, -1]
self.polynomial_beta_denom = Integer(3)
self.polynomial_lamb = [-1, 1]
self.polynomial_lamb_denom = Integer(1)
self._u = Integer(u)
self._p = sum([Integer(self.polynomial_p[i])*self._u**i for i in range(len(self.polynomial_p))]) // self.polynomial_p_denom
self._pbits = self._p.nbits()
self._tr= sum([Integer(self.polynomial_tr[i])*self._u**i for i in range(len(self.polynomial_tr))])
self._r = sum([Integer(self.polynomial_r[i])*self._u**i for i in range(len(self.polynomial_r))]) // self.polynomial_r_denom
self._c = sum([Integer(self.polynomial_c[i])*self._u**i for i in range(len(self.polynomial_c))]) // self.polynomial_c_denom # cofactor
if not self._c * self._r == self._p + 1 - self._tr:
raise ValueError("Error: r*c != p+1-tr\nr={}\nc={}\np+1-tr={}\n".format(self._r,self._c,self._p+1-self._tr))
self._y = sum([Integer(self.polynomial_y[i])*self._u**i for i in range(len(self.polynomial_y))]) // self.polynomial_y_denom
# GLV parameter for fast scalar multiplication thanks to automorphism
# psi: (x,y) -> (beta*x,y) = [lambda mod r]*(x,y) if (x,y) is of order r
# where beta is a root of x^2+x+1 mod p, beta = (-1 + sqrt(Fp(-3)))/2
# and lambda is a root of x^2+x+1 mod r, lamb = (-1 + sqrt(Fr(-3)))/2
# there are two choices: beta, -beta-1, and the same for lamb: lamb, -lamb-1
# arbitrarily the positive ones are chosen
self._beta = sum([Integer(self.polynomial_beta[i])*self._u**i for i in range(len(self.polynomial_beta))]) // self.polynomial_beta_denom
self._lamb = sum([Integer(self.polynomial_lamb[i])*self._u**i for i in range(len(self.polynomial_lamb))]) // self.polynomial_lamb_denom
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")
if ((self._beta**2 + self._beta + 1) % self._p) != 0:
raise ValueError("Error beta^2 + beta + 1 != 0 mod p")
if ((self._lamb**2 + self._lamb + 1) % self._r) != 0:
raise ValueError("Error lamb^2 + lamb + 1 != 0 mod r")
self._Fpz = PolynomialRing(self._Fp, names=('z',))
(self._z,) = self._Fpz._first_ngens(1)
if b != None:
try:
b = Integer(b)
except:
raise
self._b = b
self._bp = self._Fp(b)
else:
# check that beta = 2*U/(-3*V-U) before, where U=t/2, V = y/2 and 2V = 2 mod 3
self._b, self._bp = get_curve_parameter_b_j0(self._tr, self._y, self._beta, self._p, self._Fp)
self._ap = self._Fp(0) # first curve parameter is 0 because j=0
# Now self._b is such that E: y^2 = x^3 + b has order r
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,0,self._bp])
except ValueError as err:
print("ValueError at EllipticCurve_finite_field.__init__: {}".format(err))
raise
except:
print("An error occupred when initialising the elliptic curve")
raise
self.order_checked = super(BLS6,self).order()
if self.order_checked != (self._p+1-self._tr):
print("Error, wrong order")
raise ValueError("Wrong curve order: this one is a twist")
# computes a generator
self._G = get_curve_generator_order_r_j0(self)
self._Gx = self._G[0]
self._Gy = self._G[1]
# adjust beta and lamb according to the curve
# do we have (beta*x,y) = lamb*(x,y)?
if self([self._Gx*self._beta, self._Gy]) != self._lamb*self._G:
print("adjusting beta, lambda")
if self([self._Gx*(-self._beta-1), self._Gy]) == self._lamb*self._G:
self._beta = -self._beta-1
print("beta -> -beta-1")
elif self([self._Gx*self._beta, self._Gy]) == (-self._lamb-1)*self._G:
self._lamb = -self._lamb-1
print("lamb -> -lamb-1")
elif self([self._Gx*(-self._beta-1), self._Gy]) == (-self._lamb-1)*self._G:
self._beta = -self._beta-1
self._lamb = -self._lamb-1
print("lamb -> -lamb-1")
print("beta -> -beta-1")
else:
raise ValueError("Error while adjusting beta, lamb: compatibility not found")
def _repr_(self):
return "BLS6 p"+str(self._pbits)+" (Barreto-Lynn-Scott k=6) curve with seed "+str(self._u)+"\n"+super(BLS6,self)._repr_()
def u(self):
return self._u
def T(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 D(self):
return self._D
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 self._beta
def lamb(self):
return self._lamb
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)
......@@ -21,6 +21,13 @@ from sage.schemes.elliptic_curves.constructor import EllipticCurve
import PairingFriendlyCurve
from PairingFriendlyCurve import get_curve_parameter_b_j0, get_curve_generator_order_r_j0
Px = [1,6,24,36,36]
Rx = [1,6,18,36,36]
Cx = [1]
Tx = [1,0,6]
Yx = [1,4,6]
BETAx = [1,9,18,18]
LAMBx = [1,6,18,36]
class BN(EllipticCurve_finite_field):
"""
......@@ -187,3 +194,78 @@ class BN(EllipticCurve_finite_field):
PairingFriendlyCurve.print_parameters_for_RELIC(self)
"""
ZZx.<x> = ZZ[]
k = 12; D = 3; rho = 2.0; #sextic twists, V = [6*x + 2, -1, -1, -1], x in Z
px = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
rx = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
cx = 1 # cofactor such that p+1-tr == c*r
tx = 6*x^2 + 1
yx = 6*x^2 + 4*x + 1 # such that T_BN^2 - 4*P_BN = -3*Y_BN^2
# s = (x-2)/6
QQs.<s> = QQ[]
k = 12; D = 3
ps = (s^4 - 2*s^3 + 12*s^2 - 20*s + 28)/36
rs = (s^4 - 2*s^3 + 6*s^2 + 4*s + 4)/36
ts = (s^2 - 4*s + 10)/6
ys = (s^2 + 2)/6
cs = 1
ps == (ts^2+D*ys^2)/4
(ps+1-ts) % rs == 0
cs * rs == (ps+1-ts)
# MAGMA compute the shortest Miller loop
QQ := Rationals();
QQs<s> := PolynomialRing(QQ);
k := 12; D := 3;
ps := (s^4 - 2*s^3 + 12*s^2 - 20*s + 28)/36;
rs := (s^4 - 2*s^3 + 6*s^2 + 4*s + 4)/36;
ts := (s^2 - 4*s + 10)/6;
ys := (s^2 + 2)/6;
cs := 1;
us := ts-1;
M := Matrix(QQs, 4, 4, [rs,0,0,0, -us,1,0,0, (-us^2 mod rs),0,1,0, (-us^3 mod rs),0,0,1]);
LLL(M);
[ s 1 -1 1]
((s +us -us^2 +us^3) mod rs) eq 0;
Phi_12 := CyclotomicPolynomial(12);
Evaluate(Phi_12,ps) mod rs;
hard := Evaluate(Phi_12,ps) div rs;
# Fuentes et al method
M := Matrix(QQs, 4, 4, [hard,0,0,0, -ps,1,0,0, -ps^2,0,1,0, -ps^3,0,0,1]);
R := LLL(M);
((2*s^2 - 2*s + 14) -(s^2 + 2*s + 4)*ps - (s^2 - 4*s + 4)*ps^2 + (s^3 - s^2 + 10*s - 18)*ps^3) mod hard;
((2*s^2 - 2*s + 14) -(s^2 + 2*s + 4)*ps - (s^2 - 4*s + 4)*ps^2 + (s^3 - s^2 + 10*s - 18)*ps^3) eq (s^3 - s^2 + 4*s)*hard;
/*
[ 2*s^2 - 2*s + 14 -s^2 - 2*s - 4 -s^2 + 4*s - 4 s^3 - s^2 + 10*s - 18]
[ -s^2 - 2*s - 4 s^2 + 2*s + 10 s^3 - s^2 + 10*s - 18 -2*s^2 + 2*s - 14]
[ s^2 + 2*s + 10 s^3 - 2*s^2 + 8*s - 22 -2*s^2 + 2*s - 14 s^2 + 2*s + 4]
[s^3 - 2*s^2 + 8*s - 22 -s^2 + 4*s - 4 s^2 + 2*s + 4 -s^2 - 2*s - 10]
*/
c3 := hard div ps^3;
c2 := (hard - c3*ps^3) div ps^2;
c1 := (hard - c3*ps^3 -c2*ps^2) div ps;
c0 := (hard - c3*ps^3 -c2*ps^2 - c1*ps);
c0;
//-1/6*s^3 + 1/6*s^2 - 5/3*s + 2
(c0 + c1*ps + c2*ps^2 + c3*ps^3) eq hard;
//6*(c0, c1, c2, c3)
-s^3 + s^2 - 10*s + 12
-s^3 + 3*s^2 - 12*s + 26
s^2 - 4*s + 10
6
"""
......@@ -13,6 +13,21 @@ from sage.schemes.elliptic_curves.constructor import EllipticCurve
import PairingFriendlyCurve
from PairingFriendlyCurve import get_curve_parameter_a_j1728, get_curve_generator_order_r_j1728
Px = [3125, 2398, 625, 0, 240, 152, 48, 0, 5, 2, 1]
Px_den = 980
Rx = [625, 0, 0, 0, 48, 0, 0, 0, 1]
Rx_den = 61250
# when u = 25, 45 mod 70, then P(u), T(u), (P+1-T)(u) are all integers, and 61250 | R(u)
Cx = [625, 250, 125]
Cx_den = 2
Tx = [35, 41, 0, 0, 0, 2]
Tx_den = 35 # we need u = 25,45 mod 70 for T to be integer
Yx = [120, 38, 0, 0, 5, 1]
Yx_den = 70
BETAx = [-5651, -3115, -2740, -748, -498, -32, -120, -16, -11, 1]
BETAx_den = 4018 # 2 * 7^2 * 41
LAMBx = [24, 0, 0, 0, 1]
LAMBx_den = 7
class KSS16(EllipticCurve_finite_field):
"""
......
......@@ -434,6 +434,12 @@ test_vector_MNT6 = [
2047, 225, 2, "pbc-gen", 212, 2),# SNFS (d=2,cost=212)
]
test_vector_BLS6 = [
{'u':2**168+2**166+2**150+2**106, 'b': 4,'pnbits':672,'rnbits':337,'cost_S':116,'deg_h_S':3,'cost_C':128,'deg_h_C':2,'label':"BLS6 u=2^168+2^166+2^150+2^106"},
{'u':-2**208+2**205+2**138+2**53+2**22-1,'b': 1,'pnbits':830,'rnbits':416,'cost_S':128,'deg_h_S':3,'cost_C':149,'deg_h_C':2,'label':"BLS6 u=-2^208+2^205+2^138+2^53+2^22-1"},
{'u':-2**208-2**206+2**196+2**21, 'b': 5,'pnbits':832,'rnbits':417,'cost_S':128,'deg_h_S':3,'cost_C':149,'deg_h_C':2,'label':"BLS6 u=-2^208-2^206+2^196+2^21"},
]
test_vector_CocksPinch5 = [
{'k':5,
'T':0xe000000000000036,
......
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