From 45ee928f137160b0372971e1028feb5b9016f8e0 Mon Sep 17 00:00:00 2001 From: petscheit Date: Wed, 18 Dec 2024 11:48:36 +0100 Subject: [PATCH] chore: move vector operators to ModuloCircuit --- .../garaga/extension_field_modulo_circuit.py | 46 ---- hydra/garaga/modulo_circuit.py | 46 ++++ hydra/garaga/precompiled_circuits/ec.py | 62 +---- .../garaga/precompiled_circuits/final_exp.py | 14 +- .../precompiled_circuits/miller_tower.py | 252 +++++++++--------- .../precompiled_circuits/multi_miller_loop.py | 58 ++-- 6 files changed, 216 insertions(+), 262 deletions(-) diff --git a/hydra/garaga/extension_field_modulo_circuit.py b/hydra/garaga/extension_field_modulo_circuit.py index 825ed249..5e6a15d2 100644 --- a/hydra/garaga/extension_field_modulo_circuit.py +++ b/hydra/garaga/extension_field_modulo_circuit.py @@ -285,52 +285,6 @@ def eval_poly_in_precomputed_Z( return X_of_z - def extf_add( - self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] - ) -> list[ModuloCircuitElement]: - """ - Adds two polynomials with coefficients `X` and `Y`. - Returns R = [x0 + y0, x1 + y1, x2 + y2, ... + xn-1 + yn-1] mod p - """ - assert len(X) == len(Y), f"len(X)={len(X)} != len(Y)={len(Y)}" - return [ - self.add(x_i, y_i, comment=f"Fp{len(X)} add coeff {i}/{len(X)-1}") - for i, (x_i, y_i) in enumerate(zip(X, Y)) - ] - - def extf_scalar_mul( - self, X: list[ModuloCircuitElement], c: ModuloCircuitElement - ) -> list[ModuloCircuitElement]: - """ - Multiplies a polynomial with coefficients `X` by a scalar `c`. - Input : I(x) = i0 + i1*x + i2*x^2 + ... + in-1*x^n-1 - Output : O(x) = ci0 + ci1*x + ci2*x^2 + ... + cin-1*x^n-1. - This is done in the circuit. - """ - assert isinstance(c, ModuloCircuitElement), "c must be a ModuloCircuitElement" - return [ - self.mul(x_i, c, comment=f"Fp{len(X)} scalar mul coeff {i}/{len(X)-1}") - for i, x_i in enumerate(X) - ] - - def extf_neg(self, X: list[ModuloCircuitElement]) -> list[ModuloCircuitElement]: - """ - Negates a polynomial with coefficients `X`. - Returns R = [-x0, -x1, -x2, ... -xn-1] mod p - """ - return [ - self.neg(x_i, comment=f"Fp{len(X)} neg coeff {i}/{len(X)-1}") - for i, x_i in enumerate(X) - ] - - def extf_sub( - self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] - ) -> list[ModuloCircuitElement]: - return [ - self.sub(x, y, comment=f"Fp{len(X)} sub coeff {i}/{len(X)-1}") - for i, (x, y) in enumerate(zip(X, Y)) - ] - def extf_mul( self, Ps: list[list[ModuloCircuitElement]], diff --git a/hydra/garaga/modulo_circuit.py b/hydra/garaga/modulo_circuit.py index 6f8887ff..7a34abc0 100644 --- a/hydra/garaga/modulo_circuit.py +++ b/hydra/garaga/modulo_circuit.py @@ -961,6 +961,52 @@ def fp2_parity( # Return parity as [s, 0] return [s, zero] + def vector_sub( + self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] + ) -> list[ModuloCircuitElement]: + return [ + self.sub(x, y, comment=f"Fp{len(X)} sub coeff {i}/{len(X)-1}") + for i, (x, y) in enumerate(zip(X, Y)) + ] + + def vector_scale( + self, X: list[ModuloCircuitElement], c: ModuloCircuitElement + ) -> list[ModuloCircuitElement]: + """ + Multiplies a polynomial with coefficients `X` by a scalar `c`. + Input : I(x) = i0 + i1*x + i2*x^2 + ... + in-1*x^n-1 + Output : O(x) = ci0 + ci1*x + ci2*x^2 + ... + cin-1*x^n-1. + This is done in the circuit. + """ + assert isinstance(c, ModuloCircuitElement), "c must be a ModuloCircuitElement" + return [ + self.mul(x_i, c, comment=f"Fp{len(X)} scalar mul coeff {i}/{len(X)-1}") + for i, x_i in enumerate(X) + ] + + def vector_add( + self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] + ) -> list[ModuloCircuitElement]: + """ + Adds two polynomials with coefficients `X` and `Y`. + Returns R = [x0 + y0, x1 + y1, x2 + y2, ... + xn-1 + yn-1] mod p + """ + assert len(X) == len(Y), f"len(X)={len(X)} != len(Y)={len(Y)}" + return [ + self.add(x_i, y_i, comment=f"Fp{len(X)} add coeff {i}/{len(X)-1}") + for i, (x_i, y_i) in enumerate(zip(X, Y)) + ] + + def vector_neg(self, X: list[ModuloCircuitElement]) -> list[ModuloCircuitElement]: + """ + Negates a polynomial with coefficients `X`. + Returns R = [-x0, -x1, -x2, ... -xn-1] mod p + """ + return [ + self.neg(x_i, comment=f"Fp{len(X)} neg coeff {i}/{len(X)-1}") + for i, x_i in enumerate(X) + ] + def sub_and_assert( self, a: ModuloCircuitElement, diff --git a/hydra/garaga/precompiled_circuits/ec.py b/hydra/garaga/precompiled_circuits/ec.py index f819c092..38cd03af 100644 --- a/hydra/garaga/precompiled_circuits/ec.py +++ b/hydra/garaga/precompiled_circuits/ec.py @@ -662,52 +662,6 @@ def __init__(self, name: str, curve_id: int, compilation_mode: int = 0): ) self.curve = CURVES[curve_id] - def extf_sub( - self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] - ) -> list[ModuloCircuitElement]: - return [ - self.sub(x, y, comment=f"Fp{len(X)} sub coeff {i}/{len(X)-1}") - for i, (x, y) in enumerate(zip(X, Y)) - ] - - def extf_scalar_mul( - self, X: list[ModuloCircuitElement], c: ModuloCircuitElement - ) -> list[ModuloCircuitElement]: - """ - Multiplies a polynomial with coefficients `X` by a scalar `c`. - Input : I(x) = i0 + i1*x + i2*x^2 + ... + in-1*x^n-1 - Output : O(x) = ci0 + ci1*x + ci2*x^2 + ... + cin-1*x^n-1. - This is done in the circuit. - """ - assert isinstance(c, ModuloCircuitElement), "c must be a ModuloCircuitElement" - return [ - self.mul(x_i, c, comment=f"Fp{len(X)} scalar mul coeff {i}/{len(X)-1}") - for i, x_i in enumerate(X) - ] - - def extf_add( - self, X: list[ModuloCircuitElement], Y: list[ModuloCircuitElement] - ) -> list[ModuloCircuitElement]: - """ - Adds two polynomials with coefficients `X` and `Y`. - Returns R = [x0 + y0, x1 + y1, x2 + y2, ... + xn-1 + yn-1] mod p - """ - assert len(X) == len(Y), f"len(X)={len(X)} != len(Y)={len(Y)}" - return [ - self.add(x_i, y_i, comment=f"Fp{len(X)} add coeff {i}/{len(X)-1}") - for i, (x_i, y_i) in enumerate(zip(X, Y)) - ] - - def extf_neg(self, X: list[ModuloCircuitElement]) -> list[ModuloCircuitElement]: - """ - Negates a polynomial with coefficients `X`. - Returns R = [-x0, -x1, -x2, ... -xn-1] mod p - """ - return [ - self.neg(x_i, comment=f"Fp{len(X)} neg coeff {i}/{len(X)-1}") - for i, x_i in enumerate(X) - ] - def _compute_adding_slope( self, P: tuple[ @@ -721,7 +675,7 @@ def _compute_adding_slope( ): xP, yP = P xQ, yQ = Q - slope = self.fp2_div(self.extf_sub(yP, yQ), self.extf_sub(xP, xQ)) + slope = self.fp2_div(self.vector_sub(yP, yQ), self.vector_sub(xP, xQ)) return slope def _compute_doubling_slope_a_eq_0( @@ -733,8 +687,8 @@ def _compute_doubling_slope_a_eq_0( # Compute doubling slope m = (3x^2 + A) / 2y three = self.set_or_get_constant(self.field(3)) - m_num = self.extf_scalar_mul(self.fp2_square(xP), three) - m_den = self.extf_add(yP, yP) + m_num = self.vector_scale(self.fp2_square(xP), three) + m_den = self.vector_add(yP, yP) m = self.fp2_div(m_num, m_den) return m @@ -747,8 +701,8 @@ def add_points( xQ, yQ = Q slope = self._compute_adding_slope(P, Q) slope_sqr = self.fp2_square(slope) - nx = self.extf_sub(self.extf_sub(slope_sqr, xP), xQ) - ny = self.extf_sub(self.fp2_mul(slope, self.extf_sub(xP, nx)), yP) + nx = self.vector_sub(self.vector_sub(slope_sqr, xP), xQ) + ny = self.vector_sub(self.fp2_mul(slope, self.vector_sub(xP, nx)), yP) return (nx, ny) def double_point_a_eq_0( @@ -758,8 +712,8 @@ def double_point_a_eq_0( xP, yP = P slope = self._compute_doubling_slope_a_eq_0(P) slope_sqr = self.fp2_square(slope) - nx = self.extf_sub(self.extf_sub(slope_sqr, xP), xP) - ny = self.extf_sub(self.fp2_mul(slope, self.extf_sub(xP, nx)), yP) + nx = self.vector_sub(self.vector_sub(slope_sqr, xP), xP) + ny = self.vector_sub(self.fp2_mul(slope, self.vector_sub(xP, nx)), yP) return (nx, ny) def double_n_times(self, P, n): @@ -772,4 +726,4 @@ def negate_point( self, P: tuple[list[ModuloCircuitElement], list[ModuloCircuitElement]] ) -> tuple[list[ModuloCircuitElement], list[ModuloCircuitElement]]: x, y = P - return (x, self.extf_neg(y)) + return (x, self.vector_neg(y)) diff --git a/hydra/garaga/precompiled_circuits/final_exp.py b/hydra/garaga/precompiled_circuits/final_exp.py index 267e750a..0faf7a1d 100644 --- a/hydra/garaga/precompiled_circuits/final_exp.py +++ b/hydra/garaga/precompiled_circuits/final_exp.py @@ -67,8 +67,8 @@ def square_torus( X, self.curve_id, biject_from_direct=True ) SQ = self.write_elements(SQ, WriteOps.COMMIT) - two_SQ = self.extf_add(SQ, SQ) - two_SQ_min_X = self.extf_sub(two_SQ, X) + two_SQ = self.vector_add(SQ, SQ) + two_SQ_min_X = self.vector_sub(two_SQ, X) # %{ Q, V = nondeterministic_extension_field_mul_divmod( @@ -113,7 +113,7 @@ def mul_torus( num = copy.deepcopy(xy) num[1] = self.add(xy[1], self.set_or_get_constant(1)) - den = self.extf_add(X, Y) + den = self.vector_add(X, Y) return self.extf_div(num, den, self.extension_degree) def inverse_torus(self, X: list[ModuloCircuitElement]): @@ -165,7 +165,7 @@ def frobenius_torus( frob[i] = self.add(frob[i], op_res) if len(self.v_torus_powers_inv[frob_power]) == 1: - return self.extf_scalar_mul(frob, self.v_torus_powers_inv[frob_power][0]) + return self.vector_scale(frob, self.v_torus_powers_inv[frob_power][0]) else: Y = [ self.set_or_get_constant(v) for v in self.v_torus_powers_inv[frob_power] @@ -187,7 +187,7 @@ def easy_part( assert len(den) == 6, f"Expected 6 elements in den, got {len(den)}" num = self.write_elements(num, operation=WriteOps.INPUT) - num = self.extf_neg(num) + num = self.vector_neg(num) den = self.write_elements(den, WriteOps.INPUT) c = self.extf_div(num, den, self.extension_degree) @@ -281,7 +281,7 @@ def final_exp_part1(self, num: list[PyFelt], den: list[PyFelt]) -> list[PyFelt]: # The final exp result is DecompressTorus(MulTorus(c, t1) # MulTorus(t1, c) = (t1*c + v)/(t1 + c). # (t1+c = 0) ==> MulTorus(t1, c) is E12.One() in the Torus. - _sum = self.extf_add(t1, c) + _sum = self.vector_add(t1, c) self.extend_output(_sum) # From this case we can conclude the result is 1 or !=1 without decompression. # In case we want to decompress to get the result in GT, @@ -379,7 +379,7 @@ def final_exp_part1( # The final exp result is DecompressTorus(MulTorus(t0, t2)). # MulTorus(t0, t2) = (t0*t2 + v)/(t0 + t2). # (T0+T2 = 0) ==> MulTorus(t0, t2) is one in the Torus. - _sum = self.extf_add(t0, t2) + _sum = self.vector_add(t0, t2) self.extend_output(_sum) # From this case we can conclude the result is 1 or !=1 without decompression. # In case we want to decompress to get the result in GT, diff --git a/hydra/garaga/precompiled_circuits/miller_tower.py b/hydra/garaga/precompiled_circuits/miller_tower.py index a94a5dca..bd1a3781 100644 --- a/hydra/garaga/precompiled_circuits/miller_tower.py +++ b/hydra/garaga/precompiled_circuits/miller_tower.py @@ -72,14 +72,14 @@ def mul_by_line_tower( c3, c4 = line_evaluated[0:2], line_evaluated[2:4] b = self._fp6_by_01(b, c3, c4) - d0 = self.extf_add( + d0 = self.vector_add( [self.set_or_get_constant(1), self.set_or_get_constant(0)], c3 ) - d = self.extf_add(c0_fp6, c1_fp6) + d = self.vector_add(c0_fp6, c1_fp6) d = self._fp6_by_01(d, d0, c4) - z_c1 = self.extf_add(self.extf_neg(self.extf_add(a, b)), d) - z_c0 = self.extf_add(self.fp6_mul_by_non_residue(b), a) + z_c1 = self.vector_add(self.vector_neg(self.vector_add(a, b)), d) + z_c0 = self.vector_add(self.fp6_mul_by_non_residue(b), a) return z_c0 + z_c1 elif self.curve_id == 1: @@ -113,13 +113,13 @@ def mul_by_line_tower( d = [self.add(self.set_or_get_constant(1), c1[0]), c1[1]] - z_c1 = self.extf_add(c1_fp6, c0_fp6) + z_c1 = self.vector_add(c1_fp6, c0_fp6) z_c1 = self._fp6_by_01(z_c1, c0, d) - z_c1 = self.extf_sub(z_c1, a) - z_c1 = self.extf_sub(z_c1, b) + z_c1 = self.vector_sub(z_c1, a) + z_c1 = self.vector_sub(z_c1, b) z_c0 = self.fp6_mul_by_non_residue(b) - z_c0 = self.extf_add(z_c0, a) + z_c0 = self.vector_add(z_c0, a) return z_c0 + z_c1 def mul_by_line_line_tower(self, tower_fp12, line_line): @@ -136,11 +136,11 @@ def mul_line_by_line_tower(self, l1, l2): x3 = self.fp2_mul(c3, d3) x4 = self.fp2_mul(c4, d4) - x04 = self.extf_add(c4, d4) - x03 = self.extf_add(c3, d3) - tmp = self.extf_add(c3, c4) - x34 = self.extf_sub( - self.extf_sub(self.fp2_mul(self.extf_add(d3, d4), tmp), x3), x4 + x04 = self.vector_add(c4, d4) + x03 = self.vector_add(c3, d3) + tmp = self.vector_add(c3, c4) + x34 = self.vector_sub( + self.vector_sub(self.fp2_mul(self.vector_add(d3, d4), tmp), x3), x4 ) z00 = self.fp2_mul_by_non_residue(x4) z00 = [self.add(z00[0], self.set_or_get_constant(1)), z00[1]] @@ -154,16 +154,16 @@ def mul_line_by_line_tower(self, l1, l2): x0 = self.fp2_mul(c0, d0) x1 = self.fp2_mul(c1, d1) - x04 = self.extf_add(d0, c0) - tmp = self.extf_add(c0, c1) - x01 = self.extf_sub( - self.extf_sub(self.fp2_mul(self.extf_add(d0, d1), tmp), x0), x1 + x04 = self.vector_add(d0, c0) + tmp = self.vector_add(c0, c1) + x01 = self.vector_sub( + self.vector_sub(self.fp2_mul(self.vector_add(d0, d1), tmp), x0), x1 ) - x14 = self.extf_add(d1, c1) + x14 = self.vector_add(d1, c1) z00 = self.fp2_mul_by_non_residue( [self.set_or_get_constant(1), self.set_or_get_constant(0)] ) - z00 = self.extf_add(z00, x0) + z00 = self.vector_add(z00, x0) # C0B0 + C0B1 + C0B2 + C1B1 + C1B2 return z00 + x01 + x1 + x04 + x14 @@ -175,22 +175,22 @@ def _fp6_by_01(self, e6: list[ModuloCircuitElement], c0, c1): b0, b1, b2 = e6[0:2], e6[2:4], e6[4:6] a = self.fp2_mul(b0, c0) b = self.fp2_mul(b1, c1) - tmp = self.extf_add(b1, b2) + tmp = self.vector_add(b1, b2) t0 = self.fp2_mul(c1, tmp) - t0 = self.extf_sub(t0, b) + t0 = self.vector_sub(t0, b) t0 = self.fp2_mul_by_non_residue(t0) - t0 = self.extf_add(t0, a) + t0 = self.vector_add(t0, a) - tmp = self.extf_add(b0, b2) + tmp = self.vector_add(b0, b2) t2 = self.fp2_mul(c0, tmp) - t2 = self.extf_sub(t2, a) - t2 = self.extf_add(t2, b) + t2 = self.vector_sub(t2, a) + t2 = self.vector_add(t2, b) - t1 = self.extf_add(c0, c1) - tmp = self.extf_add(b0, b1) + t1 = self.vector_add(c0, c1) + tmp = self.vector_add(b0, b1) t1 = self.fp2_mul(t1, tmp) - t1 = self.extf_sub(t1, a) - t1 = self.extf_sub(t1, b) + t1 = self.vector_sub(t1, a) + t1 = self.vector_sub(t1, b) b0 = t0 b1 = t1 @@ -208,12 +208,12 @@ def fp12_square(self, a: list[ModuloCircuitElement]): assert len(a) == 12 xc0, xc1 = a[0:6], a[6:12] - c0 = self.extf_sub(xc0, xc1) - c3 = self.extf_add(xc0, self.extf_neg(self.fp6_mul_by_non_residue(xc1))) + c0 = self.vector_sub(xc0, xc1) + c3 = self.vector_add(xc0, self.vector_neg(self.fp6_mul_by_non_residue(xc1))) c2 = self.fp6_mul(xc0, xc1) - c0 = self.extf_add(self.fp6_mul(c0, c3), c2) - z_c1 = self.extf_add(c2, c2) - z_c0 = self.extf_add(c0, self.fp6_mul_by_non_residue(c2)) + c0 = self.vector_add(self.fp6_mul(c0, c3), c2) + z_c1 = self.vector_add(c2, c2) + z_c0 = self.vector_add(c0, self.fp6_mul_by_non_residue(c2)) return z_c0 + z_c1 @@ -224,15 +224,15 @@ def fp12_mul(self, x: list[ModuloCircuitElement], y: list[ModuloCircuitElement]) x_c0, x_c1 = x[0:6], x[6:12] y_c0, y_c1 = y[0:6], y[6:12] - a = self.extf_add(x_c0, x_c1) - b = self.extf_add(y_c0, y_c1) + a = self.vector_add(x_c0, x_c1) + b = self.vector_add(y_c0, y_c1) a = self.fp6_mul(a, b) b = self.fp6_mul(x_c0, y_c0) c = self.fp6_mul(x_c1, y_c1) - z_c1 = self.extf_sub(a, b) - z_c1 = self.extf_sub(z_c1, c) + z_c1 = self.vector_sub(a, b) + z_c1 = self.vector_sub(z_c1, c) z_c0 = self.fp6_mul_by_non_residue(c) - z_c0 = self.extf_add(z_c0, b) + z_c0 = self.vector_add(z_c0, b) return z_c0 + z_c1 @@ -247,26 +247,26 @@ def fp6_mul(self, a: list[ModuloCircuitElement], b: list[ModuloCircuitElement]): t1 = self.fp2_mul(xb1, yb1) t2 = self.fp2_mul(xb2, yb2) - c0 = self.extf_add(xb1, xb2) - tmp = self.extf_add(yb1, yb2) + c0 = self.vector_add(xb1, xb2) + tmp = self.vector_add(yb1, yb2) - c0 = self.extf_add( + c0 = self.vector_add( self.fp2_mul_by_non_residue( - self.extf_sub(self.extf_sub(self.fp2_mul(c0, tmp), t1), t2) + self.vector_sub(self.vector_sub(self.fp2_mul(c0, tmp), t1), t2) ), t0, ) - c1 = self.extf_add(xb0, xb1) - tmp = self.extf_add(yb0, yb1) - c1 = self.extf_sub(self.extf_sub(self.fp2_mul(c1, tmp), t0), t1) + c1 = self.vector_add(xb0, xb1) + tmp = self.vector_add(yb0, yb1) + c1 = self.vector_sub(self.vector_sub(self.fp2_mul(c1, tmp), t0), t1) tmp = self.fp2_mul_by_non_residue(t2) - c1 = self.extf_add(c1, tmp) + c1 = self.vector_add(c1, tmp) - tmp = self.extf_add(xb0, xb2) - c2 = self.extf_add( - self.extf_sub( - self.extf_sub(self.fp2_mul(self.extf_add(yb0, yb2), tmp), t0), t2 + tmp = self.vector_add(xb0, xb2) + c2 = self.vector_add( + self.vector_sub( + self.vector_sub(self.fp2_mul(self.vector_add(yb0, yb2), tmp), t0), t2 ), t1, ) @@ -282,11 +282,11 @@ def fp12_inverse(self, a: list[ModuloCircuitElement]): t0 = self.fp6_square(xc0) t1 = self.fp6_square(xc1) tmp = self.fp6_mul_by_non_residue(t1) - t0 = self.extf_sub(t0, tmp) + t0 = self.vector_sub(t0, tmp) t1 = self.fp6_inverse(t0) z_c0 = self.fp6_mul(xc0, t1) z_c1 = self.fp6_mul(xc1, t1) - z_c1 = self.extf_neg(z_c1) + z_c1 = self.vector_neg(z_c1) return z_c0 + z_c1 @@ -322,15 +322,15 @@ def fp6_inverse(self, a: list[ModuloCircuitElement]): t3 = self.fp2_mul(xb0, xb1) t4 = self.fp2_mul(xb0, xb2) t5 = self.fp2_mul(xb1, xb2) - c0 = self.extf_add(self.extf_neg(self.fp2_mul_by_non_residue(t5)), t0) - c1 = self.extf_sub(self.fp2_mul_by_non_residue(t2), t3) - c2 = self.extf_sub(t1, t4) + c0 = self.vector_add(self.vector_neg(self.fp2_mul_by_non_residue(t5)), t0) + c1 = self.vector_sub(self.fp2_mul_by_non_residue(t2), t3) + c2 = self.vector_sub(t1, t4) t6 = self.fp2_mul(xb0, c0) d1 = self.fp2_mul(xb2, c1) d2 = self.fp2_mul(xb1, c2) - d1 = self.fp2_mul_by_non_residue(self.extf_add(d1, d2)) - t6 = self.extf_add(t6, d1) + d1 = self.fp2_mul_by_non_residue(self.vector_add(d1, d2)) + t6 = self.vector_add(t6, d1) t6 = self.fp2_inv(t6) zb0 = self.fp2_mul(c0, t6) zb1 = self.fp2_mul(c1, t6) @@ -343,18 +343,18 @@ def fp6_square(self, a: list[ModuloCircuitElement]): xb0, xb1, xb2 = a[0:2], a[2:4], a[4:6] c4 = self.fp2_mul(xb0, xb1) - c4 = self.extf_add(c4, c4) + c4 = self.vector_add(c4, c4) c5 = self.fp2_square(xb2) - c1 = self.extf_add(self.fp2_mul_by_non_residue(c5), c4) - c2 = self.extf_sub(c4, c5) + c1 = self.vector_add(self.fp2_mul_by_non_residue(c5), c4) + c2 = self.vector_sub(c4, c5) c3 = self.fp2_square(xb0) - c4 = self.extf_add(self.extf_sub(xb0, xb1), xb2) + c4 = self.vector_add(self.vector_sub(xb0, xb1), xb2) c5 = self.fp2_mul(xb1, xb2) - c5 = self.extf_add(c5, c5) + c5 = self.vector_add(c5, c5) c4 = self.fp2_square(c4) - c0 = self.extf_add(self.fp2_mul_by_non_residue(c5), c3) - zb2 = self.extf_sub(self.extf_add(self.extf_add(c2, c4), c5), c3) + c0 = self.vector_add(self.fp2_mul_by_non_residue(c5), c3) + zb2 = self.vector_sub(self.vector_add(self.vector_add(c2, c4), c5), c3) zb0 = c0 zb1 = c1 @@ -378,55 +378,55 @@ def fp12_cyclotomic_square(self, a: list[ModuloCircuitElement]): t0 = self.fp2_square(xc1b1) t1 = self.fp2_square(xc0b0) - t6 = self.extf_add(xc1b1, xc0b0) + t6 = self.vector_add(xc1b1, xc0b0) t6 = self.fp2_square(t6) - t6 = self.extf_sub(t6, t0) - t6 = self.extf_sub(t6, t1) + t6 = self.vector_sub(t6, t0) + t6 = self.vector_sub(t6, t1) t2 = self.fp2_square(xc0b2) t3 = self.fp2_square(xc1b0) - t7 = self.extf_add(xc0b2, xc1b0) + t7 = self.vector_add(xc0b2, xc1b0) t7 = self.fp2_square(t7) - t7 = self.extf_sub(t7, t2) - t7 = self.extf_sub(t7, t3) + t7 = self.vector_sub(t7, t2) + t7 = self.vector_sub(t7, t3) t4 = self.fp2_square(xc1b2) t5 = self.fp2_square(xc0b1) - t8 = self.extf_add(xc1b2, xc0b1) + t8 = self.vector_add(xc1b2, xc0b1) t8 = self.fp2_square(t8) - t8 = self.extf_sub(t8, t4) - t8 = self.extf_sub(t8, t5) + t8 = self.vector_sub(t8, t4) + t8 = self.vector_sub(t8, t5) t8 = self.fp2_mul_by_non_residue(t8) t0 = self.fp2_mul_by_non_residue(t0) - t0 = self.extf_add(t0, t1) + t0 = self.vector_add(t0, t1) t2 = self.fp2_mul_by_non_residue(t2) - t2 = self.extf_add(t2, t3) + t2 = self.vector_add(t2, t3) t4 = self.fp2_mul_by_non_residue(t4) - t4 = self.extf_add(t4, t5) + t4 = self.vector_add(t4, t5) - zc0b0 = self.extf_sub(t0, xc0b0) - zc0b0 = self.extf_add(zc0b0, zc0b0) - zc0b0 = self.extf_add(zc0b0, t0) + zc0b0 = self.vector_sub(t0, xc0b0) + zc0b0 = self.vector_add(zc0b0, zc0b0) + zc0b0 = self.vector_add(zc0b0, t0) - zc0b1 = self.extf_sub(t2, xc0b1) - zc0b1 = self.extf_add(zc0b1, zc0b1) - zc0b1 = self.extf_add(zc0b1, t2) + zc0b1 = self.vector_sub(t2, xc0b1) + zc0b1 = self.vector_add(zc0b1, zc0b1) + zc0b1 = self.vector_add(zc0b1, t2) - zc0b2 = self.extf_sub(t4, xc0b2) - zc0b2 = self.extf_add(zc0b2, zc0b2) - zc0b2 = self.extf_add(zc0b2, t4) + zc0b2 = self.vector_sub(t4, xc0b2) + zc0b2 = self.vector_add(zc0b2, zc0b2) + zc0b2 = self.vector_add(zc0b2, t4) - zc1b0 = self.extf_add(t8, xc1b0) - zc1b0 = self.extf_add(zc1b0, zc1b0) - zc1b0 = self.extf_add(zc1b0, t8) + zc1b0 = self.vector_add(t8, xc1b0) + zc1b0 = self.vector_add(zc1b0, zc1b0) + zc1b0 = self.vector_add(zc1b0, t8) - zc1b1 = self.extf_add(t6, xc1b1) - zc1b1 = self.extf_add(zc1b1, zc1b1) - zc1b1 = self.extf_add(zc1b1, t6) + zc1b1 = self.vector_add(t6, xc1b1) + zc1b1 = self.vector_add(zc1b1, zc1b1) + zc1b1 = self.vector_add(zc1b1, t6) - zc1b2 = self.extf_add(t7, xc1b2) - zc1b2 = self.extf_add(zc1b2, zc1b2) - zc1b2 = self.extf_add(zc1b2, t7) + zc1b2 = self.vector_add(t7, xc1b2) + zc1b2 = self.vector_add(zc1b2, zc1b2) + zc1b2 = self.vector_add(zc1b2, t7) return zc0b0 + zc0b1 + zc0b2 + zc1b0 + zc1b1 + zc1b2 @@ -521,41 +521,41 @@ def fp12_cyclotomic_square_compressed( t0 = self.fp2_square(xc0b1) t1 = self.fp2_square(xc1b2) - t5 = self.extf_add(xc0b1, xc1b2) + t5 = self.vector_add(xc0b1, xc1b2) t2 = self.fp2_square(t5) - t3 = self.extf_add(t0, t1) - t5 = self.extf_sub(t2, t3) + t3 = self.vector_add(t0, t1) + t5 = self.vector_sub(t2, t3) - t6 = self.extf_add(xc1b0, xc0b2) + t6 = self.vector_add(xc1b0, xc0b2) t3 = self.fp2_square(t6) t2 = self.fp2_square(xc1b0) t6 = self.fp2_mul_by_non_residue(t5) - t5 = self.extf_add(t6, xc1b0) - t5 = self.extf_add(t5, t5) + t5 = self.vector_add(t6, xc1b0) + t5 = self.vector_add(t5, t5) - zc1b0 = self.extf_add(t5, t6) + zc1b0 = self.vector_add(t5, t6) t4 = self.fp2_mul_by_non_residue(t1) - t5 = self.extf_add(t0, t4) - t6 = self.extf_sub(t5, xc0b2) + t5 = self.vector_add(t0, t4) + t6 = self.vector_sub(t5, xc0b2) t1 = self.fp2_square(xc0b2) - t6 = self.extf_add(t6, t6) - zc0b2 = self.extf_add(t6, t5) + t6 = self.vector_add(t6, t6) + zc0b2 = self.vector_add(t6, t5) t4 = self.fp2_mul_by_non_residue(t1) - t5 = self.extf_add(t2, t4) - t6 = self.extf_sub(t5, xc0b1) - t6 = self.extf_add(t6, t6) - zc0b1 = self.extf_add(t6, t5) + t5 = self.vector_add(t2, t4) + t6 = self.vector_sub(t5, xc0b1) + t6 = self.vector_add(t6, t6) + zc0b1 = self.vector_add(t6, t5) - t0 = self.extf_add(t2, t1) - t5 = self.extf_sub(t3, t0) - t6 = self.extf_add(t5, xc1b2) - t6 = self.extf_add(t6, t6) - zc1b2 = self.extf_add(t5, t6) + t0 = self.vector_add(t2, t1) + t5 = self.vector_sub(t3, t0) + t6 = self.vector_add(t5, xc1b2) + t6 = self.vector_add(t6, t6) + zc1b2 = self.vector_add(t5, t6) return zc0b1 + zc0b2 + zc1b0 + zc1b2 @@ -564,7 +564,7 @@ def fp12_decompress_karabina_pt_I_c1b2_Z(self, xc0b1, xc1b2): assert len(xc0b1) == len(xc1b2) == 2 t0 = self.fp2_mul(xc0b1, xc1b2) - t0 = self.extf_add(t0, t0) + t0 = self.vector_add(t0, t0) # t1 = xc0b2 @@ -580,14 +580,14 @@ def fp12_decompress_karabina_pt_I_c1b2_NZ( assert len(xc0b1) == len(xc0b2) == len(xc1b0) == len(xc1b2) == 2 t0 = self.fp2_square(xc0b1) - t1 = self.extf_sub(t0, xc0b2) - t1 = self.extf_add(t1, t1) - t1 = self.extf_add(t1, t0) + t1 = self.vector_sub(t0, xc0b2) + t1 = self.vector_add(t1, t1) + t1 = self.vector_add(t1, t0) t2 = self.fp2_square(xc1b2) - t0 = self.extf_add(self.fp2_mul_by_non_residue(t2), t1) - t1 = self.extf_add(xc1b0, xc1b0) - t1 = self.extf_add(t1, t1) + t0 = self.vector_add(self.fp2_mul_by_non_residue(t2), t1) + t1 = self.vector_add(xc1b0, xc1b0) + t1 = self.vector_add(t1, t1) return t0, t1 @@ -606,11 +606,11 @@ def fp12_decompress_karabina_pt_II( zc1b1 = self.fp2_div(t0, t1) t1 = self.fp2_mul(xc0b2, xc0b1) - t2 = self.extf_sub(self.fp2_square(zc1b1), t1) - t2 = self.extf_add(t2, t2) - t2 = self.extf_sub(t2, t1) + t2 = self.vector_sub(self.fp2_square(zc1b1), t1) + t2 = self.vector_add(t2, t2) + t2 = self.vector_sub(t2, t1) t1 = self.fp2_mul(xc1b0, xc1b2) - t2 = self.extf_add(t2, t1) + t2 = self.vector_add(t2, t1) zc0b0 = self.fp2_mul_by_non_residue(t2) zc0b0 = [ self.add(zc0b0[0], self.set_or_get_constant(1)), diff --git a/hydra/garaga/precompiled_circuits/multi_miller_loop.py b/hydra/garaga/precompiled_circuits/multi_miller_loop.py index 9afd1d65..691a1fa3 100644 --- a/hydra/garaga/precompiled_circuits/multi_miller_loop.py +++ b/hydra/garaga/precompiled_circuits/multi_miller_loop.py @@ -142,7 +142,7 @@ def precompute_consts(self, n_pairs: int = None, skip_P_precompute: bool = False if -1 in self.loop_counter: self.Qneg = [ - (self.Q[i][0], self.extf_neg(self.Q[i][1])) for i in range(n_pairs) + (self.Q[i][0], self.vector_neg(self.Q[i][1])) for i in range(n_pairs) ] else: self.Qneg = None @@ -177,7 +177,7 @@ def compute_doubling_slope( comment="Doubling slope numerator end", ), ] - den = self.extf_add(Q[1], Q[1]) + den = self.vector_add(Q[1], Q[1]) return self.fp2_div(num, den) def compute_adding_slope( @@ -193,8 +193,8 @@ def compute_adding_slope( ) -> list[ModuloCircuitElement]: # num = ya - yb # den = xa - xb - num = self.extf_sub(Qa[1], Qb[1]) - den = self.extf_sub(Qa[0], Qb[0]) + num = self.vector_sub(Qa[1], Qb[1]) + den = self.vector_sub(Qa[0], Qb[0]) return self.fp2_div(num, den) def build_sparse_line_eval( @@ -267,14 +267,14 @@ def _add( if self.precompute_lines and (k + 1) <= self.n_points_precomputed_lines: return (None, None), self.get_next_precomputed_line() λ = self.compute_adding_slope(Qa, Qb) - xr = self.extf_sub(X=self.fp2_square(X=λ), Y=self.extf_add(Qa[0], Qb[0])) - yr = self.extf_sub( - X=self.fp2_mul(X=λ, Y=self.extf_sub(Qa[0], xr)), + xr = self.vector_sub(X=self.fp2_square(X=λ), Y=self.vector_add(Qa[0], Qb[0])) + yr = self.vector_sub( + X=self.fp2_mul(X=λ, Y=self.vector_sub(Qa[0], xr)), Y=Qa[1], ) p = (xr, yr) lineR0 = λ - lineR1 = self.extf_sub(self.fp2_mul(λ, Qa[0]), Qa[1]) + lineR1 = self.vector_sub(self.fp2_mul(λ, Qa[0]), Qa[1]) return p, (lineR0, lineR1) @@ -303,7 +303,7 @@ def _line_compute( return self.get_next_precomputed_line() λ = self.compute_adding_slope(Qa, Qb) lineR0 = λ - lineR1 = self.extf_sub(self.fp2_mul(λ, Qa[0]), Qa[1]) + lineR1 = self.vector_sub(self.fp2_mul(λ, Qa[0]), Qa[1]) return lineR0, lineR1 def line_compute( @@ -337,15 +337,15 @@ def _double( λ = self.compute_doubling_slope(Q) # Compute λ = 3x² / 2y # Compute xr = λ² - 2x - xr = self.extf_sub(X=self.fp2_square(X=λ), Y=self.extf_add(Q[0], Q[0])) + xr = self.vector_sub(X=self.fp2_square(X=λ), Y=self.vector_add(Q[0], Q[0])) # Compute yr = λ(x - xr) - y - yr = self.extf_sub(X=self.fp2_mul(λ, self.extf_sub(Q[0], xr)), Y=Q[1]) + yr = self.vector_sub(X=self.fp2_mul(λ, self.vector_sub(Q[0], xr)), Y=Q[1]) p = (xr, yr) lineR0 = λ - lineR1 = self.extf_sub(self.fp2_mul(λ, Q[0]), Q[1]) + lineR1 = self.vector_sub(self.fp2_mul(λ, Q[0]), Q[1]) return p, (lineR0, lineR1) @@ -382,26 +382,26 @@ def _double_and_add( # compute x3 = λ1²-x1-x2 - x3 = self.extf_sub(X=self.fp2_square(X=λ1), Y=self.extf_add(Qa[0], Qb[0])) + x3 = self.vector_sub(X=self.fp2_square(X=λ1), Y=self.vector_add(Qa[0], Qb[0])) # omit y3 computation line1R0 = λ1 - line1R1 = self.extf_sub(self.fp2_mul(λ1, Qa[0]), Qa[1]) + line1R1 = self.vector_sub(self.fp2_mul(λ1, Qa[0]), Qa[1]) # compute λ2 = -λ1-2y1/(x3-x1) - num = self.extf_add(Qa[1], Qa[1]) - den = self.extf_sub(x3, Qa[0]) - λ2 = self.extf_neg(self.extf_add(λ1, self.fp2_div(num, den))) + num = self.vector_add(Qa[1], Qa[1]) + den = self.vector_sub(x3, Qa[0]) + λ2 = self.vector_neg(self.vector_add(λ1, self.fp2_div(num, den))) # compute xr = λ2²-x1-x3 - x4 = self.extf_sub(self.extf_sub(self.fp2_square(λ2), Qa[0]), x3) + x4 = self.vector_sub(self.vector_sub(self.fp2_square(λ2), Qa[0]), x3) # compute y4 = λ2(x1 - x4)-y1 - y4 = self.extf_sub(self.fp2_mul(λ2, self.extf_sub(Qa[0], x4)), Qa[1]) + y4 = self.vector_sub(self.fp2_mul(λ2, self.vector_sub(Qa[0], x4)), Qa[1]) line2R0 = λ2 - line2R1 = self.extf_sub(self.fp2_mul(λ2, Qa[0]), Qa[1]) + line2R1 = self.vector_sub(self.fp2_mul(λ2, Qa[0]), Qa[1]) return (x4, y4), (line1R0, line1R1), (line2R0, line2R1) @@ -448,30 +448,30 @@ def _triple( self.mul(num_tmp[0], self.set_or_get_constant(3)), self.mul(num_tmp[1], self.set_or_get_constant(6)), ] - den = self.extf_add(Q[1], Q[1]) + den = self.vector_add(Q[1], Q[1]) λ1 = self.fp2_div(num, den) line1R0 = λ1 - line1R1 = self.extf_sub(self.fp2_mul(λ1, Q[0]), Q[1]) + line1R1 = self.vector_sub(self.fp2_mul(λ1, Q[0]), Q[1]) # x2 = λ1^2 - 2x - x2 = self.extf_sub(self.fp2_square(λ1), self.extf_add(Q[0], Q[0])) + x2 = self.vector_sub(self.fp2_square(λ1), self.vector_add(Q[0], Q[0])) # ommit yr computation, and # compute λ2 = 2y/(x2 − x) − λ1. # However in https://github.com/Consensys/gnark/blob/7cfcd5a723b0726dcfe75a5fc7249a23d690b00b/std/algebra/emulated/sw_bls12381/pairing.go#L548 # It's coded as x - x2. - λ2 = self.extf_sub(self.fp2_div(den, self.extf_sub(Q[0], x2)), λ1) + λ2 = self.vector_sub(self.fp2_div(den, self.vector_sub(Q[0], x2)), λ1) line2R0 = λ2 - line2R1 = self.extf_sub(self.fp2_mul(λ2, Q[0]), Q[1]) + line2R1 = self.vector_sub(self.fp2_mul(λ2, Q[0]), Q[1]) # // xr = λ²-p.x-x2 - xr = self.extf_sub(self.fp2_square(λ2), self.extf_add(Q[0], x2)) + xr = self.vector_sub(self.fp2_square(λ2), self.vector_add(Q[0], x2)) # // yr = λ(p.x-xr) - p.y - yr = self.extf_sub(self.fp2_mul(λ2, self.extf_sub(Q[0], xr)), Q[1]) + yr = self.vector_sub(self.fp2_mul(λ2, self.vector_sub(Q[0], xr)), Q[1]) return (xr, yr), (line1R0, line1R1), (line2R0, line2R1) @@ -644,11 +644,11 @@ def set_or_get_constants(): q1y, nr1p3, ) - q2x = self.extf_scalar_mul( + q2x = self.vector_scale( self.Q[k][0], nr2p2, ) - q2y = self.extf_scalar_mul( + q2y = self.vector_scale( self.Q[k][1], nr2p3, )