Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
Cocks-Pinch variant
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
MASSON Simon
Cocks-Pinch variant
Commits
0c5398bb
Commit
0c5398bb
authored
Apr 08, 2019
by
Emmanuel Thomé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
moved some more files, used by cost_pairing.sage
parent
c000b56c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1077 additions
and
1 deletion
+1077
-1
BLS12.py
BLS12.py
+183
-0
BN.py
BN.py
+185
-0
KSS16.py
KSS16.py
+188
-0
MNT6.py
MNT6.py
+166
-0
PairingFriendlyCurve.py
PairingFriendlyCurve.py
+354
-0
cost_pairing.py
cost_pairing.py
+1
-1
No files found.
BLS12.py
0 → 100644
View file @
0c5398bb
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
class
BLS12
(
EllipticCurve_finite_field
):
"""
A Barreto-Lynn-Scott curve of embedding degree 12
"""
def
__init__
(
self
,
u
,
b
=
None
):
"""
u is the seed such that p=P_BLS12(u), and b is the curve coefficient, s.t. y^2 = x^3 + b has a subgroup of order r=R_BLS12(u)
(there are two possible choices for b: b, 1/b (a twist) but only one has order r)
"""
self
.
_k
=
12
# 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_BLS12 = (u-1)^2*(u^4 - u^2 + 1)/3 + u #= (s^6 - 2*s^5 + 2*s^3 + s + 1)/3
# R_BLS12 = u^4 - u^2 + 1
# C_BLS12 = (1/3) * (u - 1)^2 # cofactor such that p+1-tr == c*r
# T_BLS12 = u + 1
# Y_BLS12 = (u-1)*(2*u^2 - 1)/3 # = (2*s^3 - 2*s^2 - s + 1)/3
# Y such that T^2 - 4*P = -3*Y^2
# BETA_BLS12 = u^5 - 3*u^4 + 3*u^3 - u + 1
# LAMB_BLS12 = u^2 -1
# 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
,
1
,
0
,
2
,
0
,
-
2
,
1
]
self
.
polynomial_p_denom
=
3
self
.
polynomial_r
=
[
1
,
0
,
-
1
,
0
,
1
]
self
.
polynomial_r_denom
=
1
self
.
polynomial_c
=
[
1
,
-
2
,
1
]
self
.
polynomial_c_denom
=
3
self
.
polynomial_tr
=
[
1
,
1
]
self
.
polynomial_tr_denom
=
1
self
.
polynomial_y
=
[
1
,
-
1
,
-
2
,
2
]
self
.
polynomial_y_denom
=
3
self
.
polynomial_beta
=
[
1
,
-
1
,
0
,
3
,
-
3
,
1
]
self
.
polynomial_beta_denom
=
1
self
.
polynomial_lamb
=
[
-
1
,
0
,
1
]
self
.
polynomial_lamb_denom
=
1
self
.
_u
=
Integer
(
u
)
self
.
_p
=
(
self
.
_u
-
1
)
**
2
*
(
self
.
_u
**
4
-
self
.
_u
**
2
+
1
)
//
3
+
self
.
_u
self
.
_pbits
=
self
.
_p
.
nbits
()
self
.
_tr
=
self
.
_u
+
1
self
.
_r
=
self
.
_u
**
4
-
self
.
_u
**
2
+
1
self
.
_c
=
(
self
.
_u
-
1
)
**
2
//
3
# cofactor
if
not
self
.
_c
*
self
.
_r
==
self
.
_p
+
1
-
self
.
_tr
:
raise
ValueError
(
"Error: r*c != p+1-tr
\n
r={}
\n
c={}
\n
p+1-tr={}
\n
"
.
format
(
self
.
_r
,
self
.
_c
,
self
.
_p
+
1
-
self
.
_tr
))
self
.
_y
=
((
self
.
_u
-
1
)
*
(
2
*
self
.
_u
**
2
-
1
))
//
3
# 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
=
self
.
_u
**
5
-
3
*
self
.
_u
**
4
+
3
*
self
.
_u
**
3
-
self
.
_u
+
1
self
.
_lamb
=
self
.
_u
**
2
-
1
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
(
BLS12
,
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
"BLS12 p"
+
str
(
self
.
_pbits
)
+
" (Barreto-Lynn-Scott k=12) curve with seed "
+
str
(
self
.
_u
)
+
"
\n
"
+
super
(
BLS12
,
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
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
)
BN.py
0 → 100644
View file @
0c5398bb
# http://doc.sagemath.org/html/en/thematic_tutorials/tutorial-objects-and-classes.html
# http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html
# http://doc.sagemath.org/html/en/thematic_tutorials/tutorial-implementing-algebraic-structures.html
# https://docs.python.org/3/library/functions.html#super
# https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
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_generic import EllipticCurve_generic
#from sage.schemes.elliptic_curves.ell_field import EllipticCurve_field
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
class
BN
(
EllipticCurve_finite_field
):
"""
A Barreto-Naehrig curve
"""
def
__init__
(
self
,
u
,
b
=
None
):
"""
u is the seed such that p=P_BN(u), and b is the curve coefficient, s.t. y^2 = x^3 + b has exactly order r=R_BN(u)
(there are two possible choices for b: b, 1/b (a twist) but only one has order r)
"""
self
.
_k
=
12
# 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_BN = 36*u^4 + 36*u^3 + 24*u^2 + 6*u + 1
# R_BN = 36*u^4 + 36*u^3 + 18*u^2 + 6*u + 1
# C_BN = 1 # cofactor such that p+1-tr == c*r
# T_BN = 6*u^2 + 1
# Y_BN = 6*u^2 + 4*u + 1 # such that T_BN^2 - 4*P_BN = -3*Y_BN^2
# BETA_BN = 18*u^3 + 18*u^2 + 9*u + 1
# LAMB_BN = 36*u^3 + 18*u^2 + 6*u + 1
self
.
polynomial_p
=
[
1
,
6
,
24
,
36
,
36
]
self
.
polynomial_r
=
[
1
,
6
,
18
,
36
,
36
]
self
.
polynomial_c
=
[
1
]
self
.
polynomial_tr
=
[
1
,
0
,
6
]
self
.
polynomial_y
=
[
1
,
4
,
6
]
self
.
polynomial_beta
=
[
1
,
9
,
18
,
18
]
self
.
polynomial_lamb
=
[
1
,
6
,
18
,
36
]
self
.
_u
=
Integer
(
u
)
self
.
_p
=
36
*
self
.
_u
**
4
+
36
*
self
.
_u
**
3
+
24
*
self
.
_u
**
2
+
6
*
self
.
_u
+
1
self
.
_pbits
=
self
.
_p
.
nbits
()
self
.
_tr
=
6
*
self
.
_u
**
2
+
1
self
.
_r
=
36
*
self
.
_u
**
4
+
36
*
self
.
_u
**
3
+
18
*
self
.
_u
**
2
+
6
*
self
.
_u
+
1
self
.
_c
=
Integer
(
1
)
self
.
_y
=
6
*
self
.
_u
**
2
+
4
*
self
.
_u
+
1
# such that T^2 - 4*P = -3*Y^2
# 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
# beta = 18*u^3 + 18*u^2 + 9*u + 1 (other one is -beta-1)
# and lambda is a root of x^2+x+1 mod r, lamb = (-1 +/- sqrt(Fr(-3)))/2
# lamb = 36*u^3 + 18*u^2 + 6*u + 1 (other one is -lamb-1)
# there are two choices: beta, -beta-1, and the same for lamb: lamb, -lamb-1
# arbitrarily the positive ones are chosen
self
.
_beta
=
18
*
self
.
_u
**
3
+
18
*
self
.
_u
**
2
+
9
*
self
.
_u
+
1
self
.
_lamb
=
36
*
self
.
_u
**
3
+
18
*
self
.
_u
**
2
+
6
*
self
.
_u
+
1
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
:
# BN curves:
# Pereira et al solution: b = c^4 + d^6 or b = c^6 + 4*d^4 for c, d in Fp*
# https://eprint.iacr.org/2010/429
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
(
BN
,
self
).
order
()
if
self
.
order_checked
!=
self
.
_r
:
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
]
# note that there is no cofactor for BN curves because r=p+1-tr
# 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
"BN p"
+
str
(
self
.
_pbits
)
+
" (Barreto-Naehrig) curve with seed "
+
str
(
self
.
_u
)
+
"
\n
"
+
super
(
BN
,
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
# cofactor is Integer(1) because r=p+1-tr and r is prime
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
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
)
KSS16.py
0 → 100644
View file @
0c5398bb
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_a_j1728
,
get_curve_generator_order_r_j1728
class
KSS16
(
EllipticCurve_finite_field
):
"""
A Kachisa-Schaefer-Scott curve of embedding degree 16
"""
def
__init__
(
self
,
u
,
a
=
None
):
"""
u is the seed such that p=P_KSS16(u), and a is the curve coefficient, s.t. y^2 = x^3 + a*x has a subgroup of order r=R_KSS16(u)
(there are two possible choices for a: a, 1/a (a twist) but only one has order r)
"""
self
.
_k
=
16
# embedding degree
self
.
_b
=
0
# second curve parameter is 0 because j=1728
self
.
_D
=
4
# 4, not 1, be careful with that
# polynomials (will be needed later for polynomial selection)
# P_KSS16 = (s^10 + 2*s^9 + 5*s^8 + 48*s^6 + 152*s^5 + 240*s^4 + 625*s^2 + 2398*s + 3125)/980
# R_KSS16 = (s^8 + 48*s^4 + 625)/61250 # 625 = 5^4, 61250 = 2*5^4*7^2
# T_KSS16 = (2*s^5 + 41*s + 35)/35
# C_KSS16 = (125/2) * (s^2 + 2*s + 5) # C such that P+1-T = C*R
# Y_KSS16 = (1/70) * (s^5 + 5*s^4 + 38*s + 120) # Y such that T^2 - 4*P = -3*Y^2
# assert (P_KSS16+1-T_KSS16) == C_KSS16*R_KSS16
# assert (T_KSS16^2 + D_KSS16*Y_KSS16^2)/4 == P_KSS16
# sqrt(-1) mod P
# BETA_KSS16 = (s^9-11*s^8-16*s^7-120*s^6-32*s^5-498*s^4-748*s^3-2740*s^2-3115*s-5651)/4018
# LAMB_KSS16 = (1/7)*(s^4 + 24) # sqrt(-1) mod R
self
.
polynomial_p
=
[
3125
,
2398
,
625
,
0
,
240
,
152
,
48
,
0
,
5
,
2
,
1
]
self
.
polynomial_p_denom
=
980
self
.
polynomial_r
=
[
625
,
0
,
0
,
0
,
48
,
0
,
0
,
0
,
1
]
self
.
polynomial_r_denom
=
61250
# when u = 25, 45 mod 70, then P(u), T(u), (P+1-T)(u) are all integers, and 61250 | R(u)
self
.
polynomial_c
=
[
625
,
250
,
125
]
self
.
polynomial_c_denom
=
2
self
.
polynomial_tr
=
[
35
,
41
,
0
,
0
,
0
,
2
]
self
.
polynomial_tr_denom
=
35
# we need u = 25,45 mod 70 for T to be integer
self
.
polynomial_y
=
[
120
,
38
,
0
,
0
,
5
,
1
]
self
.
polynomial_y_denom
=
70
self
.
polynomial_beta
=
[
-
5651
,
-
3115
,
-
2740
,
-
748
,
-
498
,
-
32
,
-
120
,
-
16
,
-
11
,
1
]
self
.
polynomial_beta_denom
=
4018
# 2 * 7^2 * 41
self
.
polynomial_lamb
=
[
24
,
0
,
0
,
0
,
1
]
self
.
polynomial_lamb_denom
=
7
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
.
_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
self
.
_tr
=
sum
([
Integer
(
self
.
polynomial_tr
[
i
])
*
self
.
_u
**
i
for
i
in
range
(
len
(
self
.
polynomial_tr
))])
//
self
.
polynomial_tr_denom
if
not
self
.
_c
*
self
.
_r
==
self
.
_p
+
1
-
self
.
_tr
:
raise
ValueError
(
"Error: r*c != p+1-tr
\n
r={}
\n
c={}
\n
p+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) -> (-x,i*y) = [lambda mod r]*(x,y) if (x,y) is of order r
# where beta is a root of x^2+1 mod p, beta = sqrt(-1) mod p
# and lambda is a root of x^2+1 mod r, lamb = sqrt(-1) mod r
# there are two choices: beta, -beta, and the same for lamb: lamb, -lamb
# arbitrarily the positive ones are chosen
# unfortunately beta has always denominator 41, computes modulo p: / instead of //
self
.
_beta
=
sum
([
Integer
(
self
.
polynomial_beta
[
i
])
*
self
.
_u
**
i
for
i
in
range
(
len
(
self
.
polynomial_beta
))])
/
Integer
(
self
.
polynomial_beta_denom
)
# LAMB is an integer when u=25,45 mod 70, which should be the case for P, T, R to be integers.
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"
)
# beta has denominator 41, reduces mod p:
self
.
_beta
=
Integer
(
self
.
_Fp
(
self
.
_beta
))
if
((
self
.
_beta
**
2
+
1
)
%
self
.
_p
)
!=
0
:
raise
ValueError
(
"Error beta^2 + 1 != 0 mod p"
)
if
((
self
.
_lamb
**
2
+
1
)
%
self
.
_r
)
!=
0
:
raise
ValueError
(
"Error lamb^2 + 1 != 0 mod r"
)
self
.
_Fpz
=
PolynomialRing
(
self
.
_Fp
,
names
=
(
'z'
,))
(
self
.
_z
,)
=
self
.
_Fpz
.
_first_ngens
(
1
)
self
.
_bp
=
self
.
_Fp
(
0
)
# second curve parameter is 0 because j=1728
if
a
!=
None
:
try
:
a
=
Integer
(
a
)
except
:
raise
self
.
_a
=
a
self
.
_ap
=
self
.
_Fp
(
a
)
else
:
# check that beta = U/V, where U=t/2, V = y
self
.
_a
,
self
.
_ap
=
get_curve_parameter_a_j1728
(
self
.
_tr
,
self
.
_y
,
self
.
_beta
,
self
.
_p
,
self
.
_Fp
)
# Now self._a is such that E: y^2 = x^3 + a*x 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
,
self
.
_ap
,
0
])
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
(
KSS16
,
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_j1728
(
self
)
self
.
_Gx
=
self
.
_G
[
0
]
self
.
_Gy
=
self
.
_G
[
1
]
# adjust beta and lamb according to the curve
# do we have (-x,beta*y) = lamb*(x,y)?
if
self
([
-
self
.
_Gx
,
self
.
_Gy
*
self
.
_beta
])
!=
self
.
_lamb
*
self
.
_G
:
print
(
"adjusting beta, lambda"
)
if
self
([
-
self
.
_Gx
,
self
.
_Gy
*
(
-
self
.
_beta
)])
==
self
.
_lamb
*
self
.
_G
:
self
.
_beta
=
self
.
_p
-
self
.
_beta
print
(
"beta -> -beta"
)
elif
self
([
-
self
.
_Gx
,
self
.
_Gy
*
self
.
_beta
])
==
(
-
self
.
_lamb
)
*
self
.
_G
:
self
.
_lamb
=
-
self
.
_lamb
print
(
"lamb -> -lamb"
)
elif
self
([
-
self
.
_Gx
,
self
.
_Gy
*
(
-
self
.
_beta
)])
==
(
-
self
.
_lamb
)
*
self
.
_G
:
self
.
_beta
=
self
.
_p
-
self
.
_beta
self
.
_lamb
=
-
self
.
_lamb
print
(
"lamb -> -lamb"
)
print
(
"beta -> -beta"
)
else
:
raise
ValueError
(
"Error while adjusting beta, lamb: compatibility not found"
)
def
_repr_
(
self
):
return
"KSS16 p"
+
str
(
self
.
_pbits
)
+
" (Kachisa-Schaefer-Scott k=16) curve with seed "
+
str
(
self
.
_u
)
+
"
\n
"
+
super
(
KSS16
,
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
# Integer
def
ap
(
self
):
return
self
.
_ap
# in Fp (finite field element)
def
b
(
self
):
return
self
.
_b
# 0
def
bp
(
self
):
return
self
.
_bp
# 0
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
)
MNT6.py
0 → 100644
View file @
0c5398bb
# MNT curves with k=6
# This time, j != 0.
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
import
PairingFriendlyCurve
from
PairingFriendlyCurve
import
get_curve_generator_order_r
class
MNT6
(
EllipticCurve_finite_field
):
"""
A Miyaji-Nakabayashi-Takano curve of embedding degree 6
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.20.8113&rep=rep1&type=pdf
"""
def
__init__
(
self
,
u
,
a
,
b
,
D
=
None
,
c
=
None
):
"""
u is the seed such that p=P_MNT6(u), and a,b are the curve coefficients,
s.t. y^2 = x^3 + a*x + b has exactly order r=R_MNT6(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
=
Integer
(
a
)
self
.
_b
=
Integer
(
b
)
if
D
!=
None
:
self
.
_D
=
Integer
(
D
)
# polynomials (will be needed later for polynomial selection)
#P_MNT6 = 4*x^2+1
#R_MNT6 = 4*x^2 - 2*x + 1
#C_MNT6 = 1
#T_MNT6 = 2*x + 1
#DY2_MNT6 = 12*x^2 - 4*x + 3
# no beta, lambda
self
.
polynomial_p
=
[
1
,
0
,
4
]
self
.
polynomial_p_denom
=
1
self
.
polynomial_r
=
[
1
,
-
2
,
4
]
self
.
polynomial_r_denom
=
1
self
.
polynomial_c
=
[
1
]
self
.
polynomial_c_denom
=
1
self
.
polynomial_tr
=
[
1
,
2
]
self
.
polynomial_tr_denom
=
1
self
.
_u
=
Integer
(
u
)
self
.
_p
=
Integer
(
4
)
*
(
self
.
_u
)
**
2
+
Integer
(
1
)
self
.
_pbits
=
self
.
_p
.
nbits
()
self
.
_tr
=
Integer
(
2
)
*
self
.
_u
+
1
self
.
_r
=
Integer
(
4
)
*
self
.
_u
**
2
-
Integer
(
2
)
*
self
.
_u
+
1
if
c
!=
None
and
c
!=
1
and
(
self
.
_r
%
Integer
(
c
))
==
0
:
self
.
_c
=
Integer
(
c
)
self
.
_r
=
self
.
_r
//
self
.
_c
else
:
self
.
_c
=
Integer
(
1
)
if
not
self
.
_c
*
self
.
_r
==
self
.
_p
+
1
-
self
.
_tr
:
raise
ValueError
(
"Error: r*c != p+1-tr
\n
r={}
\n
c={}
\n
p+1-tr={}
\n
"
.
format
(
self
.
_r
,
self
.
_c
,
self
.
_p
+
1
-
self
.
_tr
))
#print("computing y")
self
.
_y
=
Integer
(((
4
*
self
.
_p
-
self
.
_tr
**
2
)
//
self
.
_D
).
sqrt
())
#print("y done")
try
:
self
.
_Fp
=
FiniteField
(
self
.
_p
)
except
ValueError
as
err
: