diff --git a/zksnark/bn128_curve.py b/zksnark/bn128_curve.py index d12404f..0e7c15c 100644 --- a/zksnark/bn128_curve.py +++ b/zksnark/bn128_curve.py @@ -12,15 +12,15 @@ assert (field_modulus ** 12 - 1) % curve_order == 0 # Curve is y**2 = x**3 + 3 b = FQ(3) # Twisted curve over FQ**2 -b2 = FQ2([3, 0]) / FQ2([0, 1]) +b2 = FQ2([3, 0]) / FQ2([9, 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)) # Generator for twisted curve over FQ2 -G2 = (FQ2([16260673061341949275257563295988632869519996389676903622179081103440260644990, 11559732032986387107991004021392285783925812861821192530917403151452391805634]), - FQ2([15530828784031078730107954109694902500959150953518636601196686752670329677317, 4082367875863433681332203403145435568316851327593401208105741076214120093531])) +G2 = (FQ2([10857046999023057135944570762232829481370756359578518086990519993285655852781, 11559732032986387107991004021392285783925812861821192530917403151452391805634]), + FQ2([8495653923123431417604973247489272438418190587263600148770280649306958101930, 4082367875863433681332203403145435568316851327593401208105741076214120093531])) # Check that a point is on the curve defined by y**2 == x**3 + b def is_on_curve(pt, b): @@ -95,9 +95,15 @@ def neg(pt): def twist(pt): if pt is None: return None - x, y = pt - nx = FQ12([x.coeffs[0]] + [0] * 5 + [x.coeffs[1]] + [0] * 5) - ny = FQ12([y.coeffs[0]] + [0] * 5 + [y.coeffs[1]] + [0] * 5) + _x, _y = pt + # Field isomorphism from Z[p] / x**2 to Z[p] / x**2 - 18*x + 82 + xcoeffs = [_x.coeffs[0] - _x.coeffs[1] * 9, _x.coeffs[1]] + ycoeffs = [_y.coeffs[0] - _y.coeffs[1] * 9, _y.coeffs[1]] + # Isomorphism into subfield of Z[p] / w**12 - 18 * w**6 + 82, + # where w**6 = x + nx = FQ12([xcoeffs[0]] + [0] * 5 + [xcoeffs[1]] + [0] * 5) + ny = FQ12([ycoeffs[0]] + [0] * 5 + [ycoeffs[1]] + [0] * 5) + # Divide x coord by w**2 and y coord by w**3 return (nx * w **2, ny * w**3) # Check that the twist creates a point that is on the curve diff --git a/zksnark/bn128_field_elements.py b/zksnark/bn128_field_elements.py index d12e733..9dff5ce 100644 --- a/zksnark/bn128_field_elements.py +++ b/zksnark/bn128_field_elements.py @@ -12,9 +12,7 @@ field_modulus = 2188824287183927522224640574525727508869631115729782366268903789 # See, it's prime! assert pow(2, field_modulus, field_modulus) == 2 -# The modulus of the polynomial in this representation of FQ2 -FQ2_modulus_coeffs = [82, -18] # Implied + [1] -# And in FQ12 +# The modulus of the polynomial in this representation of FQ12 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 @@ -236,7 +234,7 @@ class FQP(): class FQ2(FQP): def __init__(self, coeffs): self.coeffs = [FQ(c) for c in coeffs] - self.modulus_coeffs = FQ2_modulus_coeffs + self.modulus_coeffs = [1, 0] self.degree = 2 self.__class__.degree = 2 @@ -252,15 +250,6 @@ assert one / f + x / f == (one + x) / f assert one * f + x * f == (one + x) * f 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 class FQ12(FQP): def __init__(self, coeffs): diff --git a/zksnark/bn128_pairing.py b/zksnark/bn128_pairing.py index 5d1f310..2924f2a 100644 --- a/zksnark/bn128_pairing.py +++ b/zksnark/bn128_pairing.py @@ -1,7 +1,6 @@ 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 -from optimized_field_elements import FQ2, FQ12, FQcomplex -# from bn128_field_elements import FQ2, FQ12, FQcomplex +from optimized_field_elements import FQ2, FQ12 ate_loop_count = 29793968203157093288 log_ate_loop_count = 63 diff --git a/zksnark/bn128_pairing_test.py b/zksnark/bn128_pairing_test.py index 3edfbc4..4993615 100644 --- a/zksnark/bn128_pairing_test.py +++ b/zksnark/bn128_pairing_test.py @@ -1,4 +1,5 @@ from optimized_pairing import pairing, neg, G2, G1, multiply, FQ12, curve_order +# from bn128_pairing import pairing, neg, G2, G1, multiply, FQ12, curve_order import time a = time.time() diff --git a/zksnark/optimized_curve.py b/zksnark/optimized_curve.py index 27d38f9..7ee42ab 100644 --- a/zksnark/optimized_curve.py +++ b/zksnark/optimized_curve.py @@ -12,15 +12,15 @@ assert (field_modulus ** 12 - 1) % curve_order == 0 # Curve is y**2 = x**3 + 3 b = FQ(3) # Twisted curve over FQ**2 -b2 = FQ2([3, 0]) / FQ2([0, 1]) +b2 = FQ2([3, 0]) / FQ2([9, 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), FQ(1)) # Generator for twisted curve over FQ2 -G2 = (FQ2([16260673061341949275257563295988632869519996389676903622179081103440260644990, 11559732032986387107991004021392285783925812861821192530917403151452391805634]), - FQ2([15530828784031078730107954109694902500959150953518636601196686752670329677317, 4082367875863433681332203403145435568316851327593401208105741076214120093531]), FQ2.one()) +G2 = (FQ2([10857046999023057135944570762232829481370756359578518086990519993285655852781, 11559732032986387107991004021392285783925812861821192530917403151452391805634]), + FQ2([8495653923123431417604973247489272438418190587263600148770280649306958101930, 4082367875863433681332203403145435568316851327593401208105741076214120093531]), FQ2.one()) # Check that a point is on the curve defined by y**2 == x**3 + b def is_on_curve(pt, b): @@ -119,10 +119,15 @@ def neg(pt): def twist(pt): if pt is None: return None - x, y, z = pt - nx = FQ12([x.coeffs[0]] + [0] * 5 + [x.coeffs[1]] + [0] * 5) - ny = FQ12([y.coeffs[0]] + [0] * 5 + [y.coeffs[1]] + [0] * 5) - nz = FQ12([z.coeffs[0]] + [0] * 5 + [z.coeffs[1]] + [0] * 5) + _x, _y, _z = pt + # Field isomorphism from Z[p] / x**2 to Z[p] / x**2 - 18*x + 82 + xcoeffs = [_x.coeffs[0] - _x.coeffs[1] * 9, _x.coeffs[1]] + ycoeffs = [_y.coeffs[0] - _y.coeffs[1] * 9, _y.coeffs[1]] + zcoeffs = [_z.coeffs[0] - _z.coeffs[1] * 9, _z.coeffs[1]] + x, y, z = _x - _y * 9, _y, _z + nx = FQ12([xcoeffs[0]] + [0] * 5 + [xcoeffs[1]] + [0] * 5) + ny = FQ12([ycoeffs[0]] + [0] * 5 + [ycoeffs[1]] + [0] * 5) + nz = FQ12([zcoeffs[0]] + [0] * 5 + [zcoeffs[1]] + [0] * 5) return (nx * w **2, ny * w**3, nz) # Check that the twist creates a point that is on the curve diff --git a/zksnark/optimized_field_elements.py b/zksnark/optimized_field_elements.py index 34fd3e8..e3b25b3 100644 --- a/zksnark/optimized_field_elements.py +++ b/zksnark/optimized_field_elements.py @@ -1,6 +1,4 @@ field_modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583 -FQ2_modulus_coeffs = [82, -18] # Implied + [1] -FQ2_mc_tuples = [(0, 82), (1, -18)] FQ12_modulus_coeffs = [82, 0, 0, 0, 0, 0, -18, 0, 0, 0, 0, 0] # Implied + [1] FQ12_mc_tuples = [(i, c) for i, c in enumerate(FQ12_modulus_coeffs) if c] @@ -172,8 +170,8 @@ class FQP(): class FQ2(FQP): def __init__(self, coeffs): self.coeffs = coeffs - self.modulus_coeffs = FQ2_modulus_coeffs - self.mc_tuples = FQ2_mc_tuples + self.modulus_coeffs = [1, 0] + self.mc_tuples = [(0, 1)] self.degree = 2 self.__class__.degree = 2 @@ -189,16 +187,6 @@ assert one / f + x / f == (one + x) / f assert one * f + x * f == (one + x) * f assert x ** (field_modulus ** 2 - 1) == one - -# The quadratic extension field -class FQcomplex(FQP): - def __init__(self, coeffs): - self.coeffs = coeffs - self.modulus_coeffs = [1, 0] - self.mc_tuples = [(0, 1)] - self.degree = 2 - self.__class__.degree = 2 - # The 12th-degree extension field class FQ12(FQP): def __init__(self, coeffs): diff --git a/zksnark/optimized_pairing.py b/zksnark/optimized_pairing.py index 73aee02..78652b1 100644 --- a/zksnark/optimized_pairing.py +++ b/zksnark/optimized_pairing.py @@ -1,7 +1,6 @@ from optimized_curve import double, add, multiply, is_on_curve, neg, twist, b, b2, b12, curve_order, G1, G2, G12, normalize from bn128_field_elements import field_modulus, FQ -from optimized_field_elements import FQ2, FQ12, FQcomplex -# from bn128_field_elements import FQ2, FQ12, FQcomplex +from optimized_field_elements import FQ2, FQ12 ate_loop_count = 29793968203157093288 log_ate_loop_count = 63