Added very preliminary pairing code
This commit is contained in:
parent
711bd9532b
commit
05aa71bb1b
|
@ -7,7 +7,6 @@ b = FQ(3)
|
||||||
b2 = FQ2([3, 0])
|
b2 = FQ2([3, 0])
|
||||||
b12 = FQ12([3] + [0] * 11) / FQ12([0] * 6 + [1] + [0] * 5)
|
b12 = FQ12([3] + [0] * 11) / FQ12([0] * 6 + [1] + [0] * 5)
|
||||||
|
|
||||||
ate_loop_count = 29793968203157093288
|
|
||||||
|
|
||||||
G1 = (FQ(1), FQ(2))
|
G1 = (FQ(1), FQ(2))
|
||||||
# Second element corresponds to modsqrt(67) * i in our quadratic field representation
|
# Second element corresponds to modsqrt(67) * i in our quadratic field representation
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# 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_field_elements import field_modulus, FQ, FQ2, FQ12
|
||||||
|
|
||||||
|
ate_loop_count = 29793968203157093288
|
||||||
|
log_ate_loop_count = 64
|
||||||
|
|
||||||
|
# Create a function representing the line between P1 and P2,
|
||||||
|
# and evaluate it at T
|
||||||
|
def linefunc(P1, P2, T):
|
||||||
|
x1, y1 = P1
|
||||||
|
x2, y2 = P2
|
||||||
|
xt, yt = T
|
||||||
|
if x1 != x2:
|
||||||
|
m = (y2 - y1) / (x2 - x1)
|
||||||
|
return (yt - y1) - m * (xt - x1)
|
||||||
|
elif y1 == y2:
|
||||||
|
m = 3 * x1**2 / (2 * y1)
|
||||||
|
return (yt - y1) - m * (xt - x1)
|
||||||
|
else:
|
||||||
|
return xt - x1
|
||||||
|
|
||||||
|
def cast_point_to_fq12(pt):
|
||||||
|
if pt is None:
|
||||||
|
return None
|
||||||
|
x, y = pt
|
||||||
|
return (FQ12([x.n] + [0] * 11), FQ12([y.n] + [0] * 11))
|
||||||
|
|
||||||
|
# Check consistency of the "line function"
|
||||||
|
one, two, three, negone = G1, double(G1), multiply(G1, 3), multiply(G1, curve_order - 1)
|
||||||
|
|
||||||
|
assert linefunc(one, two, one) == FQ(0)
|
||||||
|
assert linefunc(one, two, two) == FQ(0)
|
||||||
|
assert linefunc(one, two, three) != FQ(0)
|
||||||
|
assert linefunc(one, negone, one) == FQ(0)
|
||||||
|
assert linefunc(one, negone, negone) == FQ(0)
|
||||||
|
assert linefunc(one, negone, two) != FQ(0)
|
||||||
|
assert linefunc(one, one, one) == FQ(0)
|
||||||
|
assert linefunc(one, one, two) != FQ(0)
|
||||||
|
|
||||||
|
# Main miller loop
|
||||||
|
def miller_loop(Q, P):
|
||||||
|
R = Q
|
||||||
|
f = FQ12.one()
|
||||||
|
for i in range(log_ate_loop_count, -1, -1):
|
||||||
|
f = f * f / linefunc(R, R, P)
|
||||||
|
R = double(R)
|
||||||
|
if ate_loop_count & (2**i):
|
||||||
|
f = f * linefunc(R, Q, P)
|
||||||
|
R = add(R, Q)
|
||||||
|
Q1 = (Q[0] ** field_modulus, Q[1] ** field_modulus)
|
||||||
|
nQ2 = (Q[0] ** (field_modulus ** 2), -Q[1] ** (field_modulus ** 2))
|
||||||
|
f = f * linefunc(R, Q1, P)
|
||||||
|
R = add(R, Q1)
|
||||||
|
f = f * linefunc(R, nQ2, P)
|
||||||
|
R = add(R, nQ2)
|
||||||
|
return f ** ((field_modulus ** 12 - 1) / curve_order)
|
||||||
|
|
||||||
|
# Pairing computation
|
||||||
|
def pairing(Q, P):
|
||||||
|
assert is_on_curve(Q, b2)
|
||||||
|
assert is_on_curve(P, b)
|
||||||
|
return miller_loop(twist(Q), cast_point_to_fq12(P))
|
Loading…
Reference in New Issue