Pairing works now! Yay!!!
This commit is contained in:
parent
4b3e13de37
commit
78f3c227fe
|
@ -2,15 +2,23 @@ from bn128_field_elements import field_modulus, FQ, FQ2, FQ12
|
||||||
|
|
||||||
curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||||
|
|
||||||
|
# Curve order should be prime
|
||||||
|
assert pow(2, curve_order, curve_order) == 2
|
||||||
|
# Curve order should be a factor of field_modulus**12 - 1
|
||||||
|
assert (field_modulus ** 12 - 1) % curve_order == 0
|
||||||
|
|
||||||
# Curve is y**2 = x**3 + 3
|
# Curve is y**2 = x**3 + 3
|
||||||
b = FQ(3)
|
b = FQ(3)
|
||||||
b2 = FQ2([3, 0])
|
# Twisted curve over FQ**2
|
||||||
b12 = FQ12([3] + [0] * 11) / FQ12([0] * 6 + [1] + [0] * 5)
|
b2 = FQ2([3, 0]) / FQ2([0, 1])
|
||||||
|
# Extension curve over FQ**12; same b value as over FQ
|
||||||
|
b12 = FQ12([3] + [0] * 11)
|
||||||
|
|
||||||
|
# Generator for curve over FQ
|
||||||
G1 = (FQ(1), FQ(2))
|
G1 = (FQ(1), FQ(2))
|
||||||
# Second element corresponds to modsqrt(67) * i in our quadratic field representation
|
# Generator for twisted curve over FQ2
|
||||||
G2 = (FQ2([4, 0]), FQ2([16893045765507297706785249332518927989146279141265438554111591828131739815230L, 16469166999615883226695964867118064280147127342783597836693979910667010785192]))
|
G2 = (FQ2([16260673061341949275257563295988632869519996389676903622179081103440260644990L, 11559732032986387107991004021392285783925812861821192530917403151452391805634L]),
|
||||||
|
FQ2([15530828784031078730107954109694902500959150953518636601196686752670329677317L, 4082367875863433681332203403145435568316851327593401208105741076214120093531L]))
|
||||||
|
|
||||||
# Check that a point is on the curve defined by y**2 == x**3 + b
|
# Check that a point is on the curve defined by y**2 == x**3 + b
|
||||||
def is_on_curve(pt, b):
|
def is_on_curve(pt, b):
|
||||||
|
@ -68,18 +76,27 @@ assert multiply(G1, curve_order) is None
|
||||||
assert add(add(double(G2), G2), G2) == double(double(G2))
|
assert add(add(double(G2), G2), G2) == double(double(G2))
|
||||||
assert double(G2) != G2
|
assert double(G2) != G2
|
||||||
assert add(multiply(G2, 9), multiply(G2, 5)) == add(multiply(G2, 12), multiply(G2, 2))
|
assert add(multiply(G2, 9), multiply(G2, 5)) == add(multiply(G2, 12), multiply(G2, 2))
|
||||||
|
assert multiply(G2, curve_order) is None
|
||||||
assert multiply(G2, 2 * field_modulus - curve_order) is not None
|
assert multiply(G2, 2 * field_modulus - curve_order) is not None
|
||||||
|
assert is_on_curve(multiply(G2, 9), b2)
|
||||||
|
|
||||||
# "Twist" a point in E(FQ2) into a point in E(FQ12)
|
# "Twist" a point in E(FQ2) into a point in E(FQ12)
|
||||||
w = FQ12([0, 1] + [0] * 10)
|
w = FQ12([0, 1] + [0] * 10)
|
||||||
|
|
||||||
|
# Convert P => -P
|
||||||
|
def neg(pt):
|
||||||
|
if pt is None:
|
||||||
|
return None
|
||||||
|
x, y = pt
|
||||||
|
return (x, -y)
|
||||||
|
|
||||||
def twist(pt):
|
def twist(pt):
|
||||||
if pt is None:
|
if pt is None:
|
||||||
return None
|
return None
|
||||||
x, y = pt
|
x, y = pt
|
||||||
nx = FQ12([x.coeffs[0]] + [0] * 5 + [x.coeffs[1]] + [0] * 5)
|
nx = FQ12([x.coeffs[0]] + [0] * 5 + [x.coeffs[1]] + [0] * 5)
|
||||||
ny = FQ12([y.coeffs[0]] + [0] * 5 + [y.coeffs[1]] + [0] * 5)
|
ny = FQ12([y.coeffs[0]] + [0] * 5 + [y.coeffs[1]] + [0] * 5)
|
||||||
return (nx / w **2, ny / w**3)
|
return (nx * w **2, ny * w**3)
|
||||||
|
|
||||||
# Check that the twist creates a point that is on the curve
|
# Check that the twist creates a point that is on the curve
|
||||||
assert is_on_curve(twist(G2), b12)
|
assert is_on_curve(twist(G2), b12)
|
||||||
|
@ -90,3 +107,5 @@ G12 = twist(G2)
|
||||||
assert add(add(double(G12), G12), G12) == double(double(G12))
|
assert add(add(double(G12), G12), G12) == double(double(G12))
|
||||||
assert double(G12) != G12
|
assert double(G12) != G12
|
||||||
assert add(multiply(G12, 9), multiply(G12, 5)) == add(multiply(G12, 12), multiply(G12, 2))
|
assert add(multiply(G12, 9), multiply(G12, 5)) == add(multiply(G12, 12), multiply(G12, 2))
|
||||||
|
assert is_on_curve(multiply(G12, 9), b12)
|
||||||
|
assert multiply(G12, curve_order) is None
|
||||||
|
|
|
@ -7,9 +7,9 @@ field_modulus = 2188824287183927522224640574525727508869631115729782366268903789
|
||||||
assert pow(2, field_modulus, field_modulus) == 2
|
assert pow(2, field_modulus, field_modulus) == 2
|
||||||
|
|
||||||
# The modulus of the polynomial in this representation of FQ2
|
# The modulus of the polynomial in this representation of FQ2
|
||||||
FQ2_modulus_coeffs = [82, 18] # Implied + [1]
|
FQ2_modulus_coeffs = [82, -18] # Implied + [1]
|
||||||
# And in FQ12
|
# And in FQ12
|
||||||
FQ12_modulus_coeffs = [82, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0] # Implied + [1]
|
FQ12_modulus_coeffs = [82, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0] # Implied + [1]
|
||||||
|
|
||||||
# Extended euclidean algorithm to find modular inverses for
|
# Extended euclidean algorithm to find modular inverses for
|
||||||
# integers
|
# integers
|
||||||
|
@ -237,6 +237,15 @@ assert one / f + x / f == (one + x) / f
|
||||||
assert one * f + x * f == (one + x) * f
|
assert one * f + x * f == (one + x) * f
|
||||||
assert x ** (field_modulus ** 2 - 1) == one
|
assert x ** (field_modulus ** 2 - 1) == one
|
||||||
|
|
||||||
|
|
||||||
|
# The quadratic extension field
|
||||||
|
class FQcomplex(FQP):
|
||||||
|
def __init__(self, coeffs):
|
||||||
|
self.coeffs = [FQ(c) for c in coeffs]
|
||||||
|
self.modulus_coeffs = [1, 0]
|
||||||
|
self.degree = 2
|
||||||
|
self.__class__.degree = 2
|
||||||
|
|
||||||
# The 12th-degree extension field
|
# The 12th-degree extension field
|
||||||
class FQ12(FQP):
|
class FQ12(FQP):
|
||||||
def __init__(self, coeffs):
|
def __init__(self, coeffs):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# NOT YET FINISHED! Pairing code has bugs in it, is NOT bilinear!
|
# NOT YET FINISHED! Pairing code has bugs in it, is NOT bilinear!
|
||||||
|
|
||||||
from bn128_curve import double, add, multiply, is_on_curve, twist, b, b2, b12, curve_order, G1, G2
|
from bn128_curve import double, add, multiply, is_on_curve, neg, twist, b, b2, b12, curve_order, G1, G2, G12
|
||||||
from bn128_field_elements import field_modulus, FQ, FQ2, FQ12
|
from bn128_field_elements import field_modulus, FQ, FQ2, FQ12, FQcomplex
|
||||||
|
|
||||||
ate_loop_count = 29793968203157093288
|
ate_loop_count = 29793968203157093288
|
||||||
log_ate_loop_count = 63
|
log_ate_loop_count = 63
|
||||||
|
@ -15,10 +15,10 @@ def linefunc(P1, P2, T):
|
||||||
xt, yt = T
|
xt, yt = T
|
||||||
if x1 != x2:
|
if x1 != x2:
|
||||||
m = (y2 - y1) / (x2 - x1)
|
m = (y2 - y1) / (x2 - x1)
|
||||||
return (yt - y1) - m * (xt - x1)
|
return m * (xt - x1) - (yt - y1)
|
||||||
elif y1 == y2:
|
elif y1 == y2:
|
||||||
m = 3 * x1**2 / (2 * y1)
|
m = 3 * x1**2 / (2 * y1)
|
||||||
return (yt - y1) - m * (xt - x1)
|
return m * (xt - x1) - (yt - y1)
|
||||||
else:
|
else:
|
||||||
return xt - x1
|
return xt - x1
|
||||||
|
|
||||||
|
@ -57,7 +57,9 @@ def miller_loop(Q, P):
|
||||||
R = add(R, Q)
|
R = add(R, Q)
|
||||||
assert R == multiply(Q, ate_loop_count)
|
assert R == multiply(Q, ate_loop_count)
|
||||||
Q1 = (Q[0] ** field_modulus, Q[1] ** field_modulus)
|
Q1 = (Q[0] ** field_modulus, Q[1] ** field_modulus)
|
||||||
|
assert is_on_curve(Q1, b12)
|
||||||
nQ2 = (Q[0] ** (field_modulus ** 2), -Q[1] ** (field_modulus ** 2))
|
nQ2 = (Q[0] ** (field_modulus ** 2), -Q[1] ** (field_modulus ** 2))
|
||||||
|
assert is_on_curve(nQ2, b12)
|
||||||
f = f * linefunc(R, Q1, P)
|
f = f * linefunc(R, Q1, P)
|
||||||
R = add(R, Q1)
|
R = add(R, Q1)
|
||||||
f = f * linefunc(R, nQ2, P)
|
f = f * linefunc(R, nQ2, P)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
from bn128_pairing import pairing, neg, G2, G1, multiply, FQ12, curve_order
|
||||||
|
|
||||||
|
p1 = pairing(G2, G1)
|
||||||
|
pn1 = pairing(G2, neg(G1))
|
||||||
|
assert p1 * pn1 == FQ12.one()
|
||||||
|
print 'Pairing check against negative in G1 passed'
|
||||||
|
np1 = pairing(neg(G2), G1)
|
||||||
|
assert p1 * np1 == FQ12.one()
|
||||||
|
assert pn1 == np1
|
||||||
|
print 'Pairing check against negative in G2 passed'
|
||||||
|
assert p1 ** curve_order == FQ12.one()
|
||||||
|
print 'Pairing output has correct order'
|
||||||
|
p2 = pairing(G2, multiply(G1, 2))
|
||||||
|
assert p1 * p1 == p2
|
||||||
|
print 'Pairing bilinearity in G1 passed'
|
||||||
|
assert p1 != p2 and p1 != np1 and p2 != np1
|
||||||
|
print 'Pairing is non-degenerate'
|
||||||
|
po2 = pairing(multiply(G2, 2), G1)
|
||||||
|
assert p1 * p1 == po2
|
||||||
|
print 'Pairing bilinearity in G2 passed'
|
||||||
|
p3 = pairing(multiply(G2, 27), multiply(G1, 37))
|
||||||
|
po3 = pairing(G2, multiply(G1, 999))
|
||||||
|
assert p3 == po3
|
||||||
|
print 'Composite check passed'
|
Loading…
Reference in New Issue