diff --git a/hydra/modulo_circuit.py b/hydra/modulo_circuit.py index f70342a4..39c0ba9b 100644 --- a/hydra/modulo_circuit.py +++ b/hydra/modulo_circuit.py @@ -326,9 +326,7 @@ def __init__( self.generic_circuit = generic_circuit self.compilation_mode = compilation_mode self.exact_output_refs_needed = None - self.input_structs: list[Cairo1SerializableStruct] | None = ( - [] if compilation_mode == 1 else None - ) + self.input_structs: list[Cairo1SerializableStruct] = [] @property def values_offset(self) -> int: @@ -686,7 +684,7 @@ def eval_poly( return acc def extend_output(self, elmts: list[ModuloCircuitElement]): - assert isinstance(elmts, list) + assert isinstance(elmts, (list, tuple)) assert all(isinstance(x, ModuloCircuitElement) for x in elmts) self.output.extend(elmts) return @@ -980,8 +978,8 @@ def compile_circuit_cairo_1( """ else: code += f""" - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::<_, CircuitModulus>::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); """ diff --git a/hydra/modulo_circuit_structs.py b/hydra/modulo_circuit_structs.py index a2ae3a47..ccadbab2 100644 --- a/hydra/modulo_circuit_structs.py +++ b/hydra/modulo_circuit_structs.py @@ -13,7 +13,7 @@ class Cairo1SerializableStruct(ABC): def __post_init__(self): assert type(self.name) == str - if isinstance(self.elmts, list): + if isinstance(self.elmts, (list, tuple)): if isinstance(self.elmts[0], Cairo1SerializableStruct): assert all( isinstance(elmt, self.elmts[0].__class__) for elmt in self.elmts @@ -25,7 +25,7 @@ def __post_init__(self): for elmt in self.elmts ), f"All elements of {self.name} must be of type ModuloCircuitElement or PyFelt" else: - assert self.elmts == None + assert self.elmts == None, f"Elmts must be a list or None, got {self.elmts}" @property def struct_name(self) -> str: @@ -143,6 +143,40 @@ def __len__(self) -> int: return None +class u384Span(Cairo1SerializableStruct): + def serialize(self, raw: bool = False) -> str: + raw_struct = f"{int_array_to_u384_array(self.elmts)}.span()" + if raw: + return raw_struct + else: + return f"let {self.name}:{self.struct_name} = {raw_struct};\n" + + @property + def struct_name(self) -> str: + return "Span" + + def extract_from_circuit_output( + self, offset_to_reference_map: dict[int, str] + ) -> str: + assert len(self.elmts) == 1 + return f"let {self.name}:{self.struct_name} = array![{','.join([f'outputs.get_output({offset_to_reference_map[elmt.offset]})' for elmt in self.elmts])}].span();" + + def dump_to_circuit_input(self) -> str: + code = f""" + let mut {self.name} = {self.name}; + while let Option::Some(val) = {self.name}.pop_front() {{ + circuit_inputs = circuit_inputs.next(*val); + }}; + """ + return code + + def __len__(self) -> int: + if self.elmts is not None: + return len(self.elmts) + else: + return None + + class BLSProcessedPair(Cairo1SerializableStruct): def __init__(self, name: str, elmts: list[ModuloCircuitElement]): super().__init__(name, elmts) @@ -156,9 +190,6 @@ def serialize(self) -> str: assert len(self.elmts) == 2 return f"let {self.name}:{self.struct_name} = {self.struct_name} {{yInv: {int_to_u384(self.elmts[0].value)}, xNegOverY: {int_to_u384(self.elmts[1].value)}}};" - def serialize_input_signature(self): - return f"{self.name}:{self.struct_name}" - def extract_from_circuit_output( self, offset_to_reference_map: dict[int, str] ) -> str: @@ -200,9 +231,6 @@ def serialize(self) -> str: f"let {self.name}:{self.struct_name} = {self.struct_name} {{{members}}};\n" ) - def serialize_input_signature(self): - return f"{self.name}:{self.struct_name}" - def extract_from_circuit_output( self, offset_to_reference_map: dict[int, str] ) -> str: @@ -236,9 +264,6 @@ def serialize(self) -> str: assert len(self.elmts) == 2 return f"let {self.name}:{self.struct_name} = {self.struct_name} {{x: {int_to_u384(self.elmts[0].value)}, y: {int_to_u384(self.elmts[1].value)}}};\n" - def serialize_input_signature(self): - return f"{self.name}:{self.struct_name}" - def extract_from_circuit_output( self, offset_to_reference_map: dict[int, str] ) -> str: @@ -272,8 +297,34 @@ def serialize(self) -> str: assert len(self.elmts) == 4 return f"let {self.name}:{self.struct_name} = {self.struct_name} {{x0: {int_to_u384(self.elmts[0].value)}, x1: {int_to_u384(self.elmts[1].value)}, y0: {int_to_u384(self.elmts[2].value)}, y1: {int_to_u384(self.elmts[3].value)}}};\n" - def serialize_input_signature(self): - return f"{self.name}:{self.struct_name}" + def extract_from_circuit_output( + self, offset_to_reference_map: dict[int, str] + ) -> str: + assert len(self.elmts) == 4 + return f"let {self.name}:{self.struct_name} = {self.struct_name} {{ {','.join([f'{self.members_names[i]}: outputs.get_output({offset_to_reference_map[self.elmts[i].offset]})' for i in range(4)])} }};" + + def dump_to_circuit_input(self) -> str: + code = "" + for mem_name in self.members_names: + code += f"circuit_inputs = circuit_inputs.next({self.name}.{mem_name});\n" + return code + + def __len__(self) -> int: + if self.elmts is not None: + assert len(self.elmts) == 4 + return 4 + else: + return 4 + + +class FunctionFeltEvaluations(Cairo1SerializableStruct): + def __init__(self, name: str, elmts: list[ModuloCircuitElement]): + super().__init__(name, elmts) + self.members_names = ("a_num", "a_den", "b_num", "b_den") + + def serialize(self) -> str: + assert len(self.elmts) == 4 + return f"let {self.name}:{self.struct_name} = {self.struct_name} {{a_num: {int_to_u384(self.elmts[0].value)}, a_den: {int_to_u384(self.elmts[1].value)}, b_num: {int_to_u384(self.elmts[2].value)}, b_den: {int_to_u384(self.elmts[3].value)}}};\n" def extract_from_circuit_output( self, offset_to_reference_map: dict[int, str] @@ -311,9 +362,6 @@ def serialize(self) -> str: f"q: G2Point{{ x0:{int_to_u384(self.elmts[2].value)}, x1: {int_to_u384(self.elmts[3].value)}, y0: {int_to_u384(self.elmts[4].value)}, y1: {int_to_u384(self.elmts[5].value)}}}}};\n" ) - def serialize_input_signature(self): - return f"{self.name}:{self.struct_name}" - def extract_from_circuit_output( self, offset_to_reference_map: dict[int, str] ) -> str: @@ -456,3 +504,42 @@ def __len__(self) -> int: return 6 else: return 6 + + +class SlopeInterceptOutput(Cairo1SerializableStruct): + def __init__(self, name: str, elmts: list[ModuloCircuitElement]): + super().__init__(name, elmts) + self.members_names = ("m_A0", "b_A0", "x_A2", "y_A2", "coeff0", "coeff2") + + def serialize(self, raw: bool = False) -> str: + assert len(self.elmts) == 6 + raw_struct = f"{self.__class__.__name__}{{{','.join([f'{self.members_names[i]}: {int_to_u384(self.elmts[i].value)}' for i in range(len(self))])}}}" + if raw: + return raw_struct + else: + return f"let {self.name}:{self.__class__.__name__} = {raw_struct};\n" + + def extract_from_circuit_output( + self, offset_to_reference_map: dict[int, str] + ) -> str: + assert len(self.elmts) == 6 + code = ( + f"let {self.name}:{self.__class__.__name__} = {self.__class__.__name__}{{\n" + ) + for mem_name, elmt in zip(self.members_names, self.elmts): + code += f"{mem_name}: outputs.get_output({offset_to_reference_map[elmt.offset]}),\n" + code += "};" + return code + + def dump_to_circuit_input(self) -> str: + code = "" + for mem_name in self.members_names: + code += f"circuit_inputs = circuit_inputs.next({self.name}.{mem_name});\n" + return code + + def __len__(self) -> int: + if self.elmts is not None: + assert len(self.elmts) == 6 + return 6 + else: + return 6 diff --git a/hydra/precompiled_circuits/all_circuits.py b/hydra/precompiled_circuits/all_circuits.py index 2eac2624..a748acbc 100644 --- a/hydra/precompiled_circuits/all_circuits.py +++ b/hydra/precompiled_circuits/all_circuits.py @@ -59,6 +59,7 @@ class CircuitID(Enum): MULTI_PAIRING_CHECK = int.from_bytes(b"multi_pairing_check", "big") IS_ON_CURVE_G1_G2 = int.from_bytes(b"is_on_curve_g1_g2", "big") IS_ON_CURVE_G1 = int.from_bytes(b"is_on_curve_g1", "big") + IS_ON_CURVE_G2 = int.from_bytes(b"is_on_curve_g2", "big") DERIVE_POINT_FROM_X = int.from_bytes(b"derive_point_from_x", "big") SLOPE_INTERCEPT_SAME_POINT = int.from_bytes(b"slope_intercept_same_point", "big") ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED = int.from_bytes( @@ -68,6 +69,13 @@ class CircuitID(Enum): EVAL_FUNCTION_CHALLENGE_DUPL = int.from_bytes( b"eval_function_challenge_dupl", "big" ) + INIT_FUNCTION_CHALLENGE_DUPL = int.from_bytes( + b"init_function_challenge_dupl", "big" + ) + ACC_FUNCTION_CHALLENGE_DUPL = int.from_bytes(b"acc_function_challenge_dupl", "big") + FINALIZE_FUNCTION_CHALLENGE_DUPL = int.from_bytes( + b"finalize_function_challenge_dupl", "big" + ) ADD_EC_POINT = int.from_bytes(b"add_ec_point", "big") DOUBLE_EC_POINT = int.from_bytes(b"double_ec_point", "big") MP_CHECK_BIT0_LOOP = int.from_bytes(b"mp_check_bit0_loop", "big") @@ -217,17 +225,22 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: self.name, self.curve_id, compilation_mode=self.compilation_mode ) assert len(input) == 6 + 4, f"got {input} of len {len(input)}" - p = circuit.write_elements(input[0:2], WriteOps.INPUT) - q = circuit.write_elements(input[2:6], WriteOps.INPUT) - - circuit.set_consts(input[6], input[7], input[8], input[9]) + p = circuit.write_struct(G1PointCircuit("p", input[0:2]), WriteOps.INPUT) + q = circuit.write_struct(G2PointCircuit("q", input[2:6]), WriteOps.INPUT) + a = circuit.write_struct(u384("a", [input[6]]), WriteOps.INPUT) + b = circuit.write_struct(u384("b", [input[7]]), WriteOps.INPUT) + b20 = circuit.write_struct(u384("b20", [input[8]]), WriteOps.INPUT) + b21 = circuit.write_struct(u384("b21", [input[9]]), WriteOps.INPUT) + + circuit.set_consts(a, b, b20, b21) lhs, rhs = circuit._is_on_curve_G1(*p) lhs2, rhs2 = circuit._is_on_curve_G2(*q) zero_check = circuit.sub(lhs, rhs) zero_check_2 = [circuit.sub(lhs2[0], rhs2[0]), circuit.sub(lhs2[1], rhs2[1])] - circuit.extend_output([zero_check]) - circuit.extend_output(zero_check_2) + circuit.extend_struct_output(u384("zero_check_0", [zero_check])) + circuit.extend_struct_output(u384("zero_check_1", [zero_check_2[0]])) + circuit.extend_struct_output(u384("zero_check_2", [zero_check_2[1]])) return circuit @@ -255,10 +268,54 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = BasicEC( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - px, py, a, b = circuit.write_elements(input[0:4], WriteOps.INPUT) + px, py = circuit.write_struct(G1PointCircuit("p", input[0:2]), WriteOps.INPUT) + a = circuit.write_struct(u384("a", [input[2]]), WriteOps.INPUT) + b = circuit.write_struct(u384("b", [input[3]]), WriteOps.INPUT) + lhs, rhs = circuit._is_on_curve_G1_weirstrass(px, py, a, b) zero_check = circuit.sub(lhs, rhs) - circuit.extend_output([zero_check]) + circuit.extend_struct_output(u384("zero_check", [zero_check])) + + return circuit + + +class IsOnCurveG2Circuit(BaseModuloCircuit): + def __init__(self, curve_id: int, auto_run: bool = True, compilation_mode: int = 0): + super().__init__( + name="is_on_curve_g2", + input_len=N_LIMBS * (2 + 1), + curve_id=curve_id, + auto_run=auto_run, + compilation_mode=compilation_mode, + ) + + def build_input(self) -> list[PyFelt]: + input = [] + random_point = G2Point.gen_random_point(CurveID(self.curve_id)) + input.append(self.field(random_point.x[0])) + input.append(self.field(random_point.x[1])) + input.append(self.field(random_point.y[0])) + input.append(self.field(random_point.y[1])) + input.append(self.field(CURVES[self.curve_id].a)) + input.append(self.field(CURVES[self.curve_id].b20)) + input.append(self.field(CURVES[self.curve_id].b21)) + return input + + def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: + circuit = BasicEC( + self.name, self.curve_id, compilation_mode=self.compilation_mode + ) + x0, x1, y0, y1 = circuit.write_struct( + G2PointCircuit("p", input[0:4]), WriteOps.INPUT + ) + a = circuit.write_struct(u384("a", [input[4]]), WriteOps.INPUT) + b20 = circuit.write_struct(u384("b20", [input[5]]), WriteOps.INPUT) + b21 = circuit.write_struct(u384("b21", [input[6]]), WriteOps.INPUT) + + lhs, rhs = circuit._is_on_curve_G2_weirstrass(x0, x1, y0, y1, a, b20, b21) + zero_check = [circuit.sub(lhs[0], rhs[0]), circuit.sub(lhs[1], rhs[1])] + circuit.extend_struct_output(u384("zero_check_0", [zero_check[0]])) + circuit.extend_struct_output(u384("zero_check_1", [zero_check[1]])) return circuit @@ -320,7 +377,8 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = ECIPCircuits( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - px, py, a = circuit.write_elements(input[0:3], WriteOps.INPUT) + px, py = circuit.write_struct(G1PointCircuit("p", input[0:2]), WriteOps.INPUT) + a = circuit.write_struct(u384("a", [input[2]]), WriteOps.INPUT) m_A0, b_A0, xA0, yA0, xA2, yA2, coeff0, coeff2 = ( circuit._slope_intercept_same_point((px, py), a) ) @@ -329,7 +387,11 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit.extend_output([m_A0, b_A0, xA0, yA0, xA2, yA2, coeff0, coeff2]) else: # In Cairo1, xA0 and yA0 are not copied from the input - circuit.extend_output([m_A0, b_A0, xA2, yA2, coeff0, coeff2]) + circuit.extend_struct_output( + structs.SlopeInterceptOutput( + "mb", [m_A0, b_A0, xA2, yA2, coeff0, coeff2] + ) + ) return circuit @@ -369,13 +431,25 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = ECIPCircuits( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - acc, m, b, xA, px, py, ep, en, sp, sn = circuit.write_elements( - input[0:10], WriteOps.INPUT - ) + # acc, m, b, xA, px, py, ep, en, sp, sn = circuit.write_elements( + # input[0:10], WriteOps.INPUT + # ) + acc, m, b, xA = ( + circuit.write_struct(u384("acc", [input[0]]), WriteOps.INPUT), + circuit.write_struct(u384("m", [input[1]]), WriteOps.INPUT), + circuit.write_struct(u384("b", [input[2]]), WriteOps.INPUT), + circuit.write_struct(u384("xA", [input[3]]), WriteOps.INPUT), + ) + px, py = circuit.write_struct(G1PointCircuit("p", input[4:6]), WriteOps.INPUT) + ep = circuit.write_struct(u384("ep", [input[6]]), WriteOps.INPUT) + en = circuit.write_struct(u384("en", [input[7]]), WriteOps.INPUT) + sp = circuit.write_struct(u384("sp", [input[8]]), WriteOps.INPUT) + sn = circuit.write_struct(u384("sn", [input[9]]), WriteOps.INPUT) + res_acc = circuit._accumulate_eval_point_challenge_signed_same_point( acc, (m, b), xA, (px, py), ep, en, sp, sn ) - circuit.extend_output([res_acc]) + circuit.extend_struct_output(u384("res_acc", [res_acc])) return circuit @@ -409,9 +483,18 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = ECIPCircuits( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - acc, m, b, xA, Qx, Qy = circuit.write_elements(input[0:6], WriteOps.INPUT) + # acc, m, b, xA, Qx, Qy = circuit.write_elements(input[0:6], WriteOps.INPUT) + acc, m, b, xA = ( + circuit.write_struct(u384("acc", [input[0]]), WriteOps.INPUT), + circuit.write_struct(u384("m", [input[1]]), WriteOps.INPUT), + circuit.write_struct(u384("b", [input[2]]), WriteOps.INPUT), + circuit.write_struct(u384("xA", [input[3]]), WriteOps.INPUT), + ) + Qx, Qy = circuit.write_struct( + G1PointCircuit("Q_result", input[4:6]), WriteOps.INPUT + ) res_acc = circuit._RHS_finalize_acc(acc, (m, b), xA, (Qx, Qy)) - circuit.extend_output([res_acc]) + circuit.extend_struct_output(u384("rhs", [res_acc])) return circuit @@ -470,10 +553,17 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = ECIPCircuits( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - xA0, yA0, xA2, yA2, coeff0, coeff2 = circuit.write_elements( - input[0:6], WriteOps.INPUT + + xA0, yA0 = circuit.write_struct( + G1PointCircuit("A0", [input[0], input[1]]), WriteOps.INPUT + ) + xA2, yA2 = circuit.write_struct( + G1PointCircuit("A2", [input[2], input[3]]), WriteOps.INPUT ) - all_coeffs = circuit.write_elements(input[6:], WriteOps.INPUT) + coeff0 = circuit.write_struct(u384("coeff0", [input[4]]), WriteOps.INPUT) + coeff2 = circuit.write_struct(u384("coeff2", [input[5]]), WriteOps.INPUT) + + all_coeffs = input[6:] def split_list(input_list, lengths): start_idx, result = 0, [] @@ -483,10 +573,23 @@ def split_list(input_list, lengths): return result n_points = self._n_points_from_n_coeffs(len(all_coeffs)) - log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den = split_list( + _log_div_a_num, _log_div_a_den, _log_div_b_num, _log_div_b_den = split_list( all_coeffs, self._n_coeffs_from_n_points(n_points) ) + log_div_a_num = circuit.write_struct( + structs.u384Span("log_div_a_num", _log_div_a_num), WriteOps.INPUT + ) + log_div_a_den = circuit.write_struct( + structs.u384Span("log_div_a_den", _log_div_a_den), WriteOps.INPUT + ) + log_div_b_num = circuit.write_struct( + structs.u384Span("log_div_b_num", _log_div_b_num), WriteOps.INPUT + ) + log_div_b_den = circuit.write_struct( + structs.u384Span("log_div_b_den", _log_div_b_den), WriteOps.INPUT + ) + res = circuit._eval_function_challenge_dupl( (xA0, yA0), (xA2, yA2), @@ -497,8 +600,218 @@ def split_list(input_list, lengths): log_div_b_num, log_div_b_den, ) - circuit.extend_output([res]) + circuit.extend_struct_output(u384("res", [res])) + + return circuit + + +class InitFunctionChallengeDuplCircuit(BaseModuloCircuit): + def __init__( + self, + curve_id: int, + n_points: int = 1, + auto_run: bool = True, + compilation_mode: int = 0, + ) -> None: + self.n_points = n_points + super().__init__( + name=f"init_function_challenge_dupl", + input_len=None, + curve_id=curve_id, + auto_run=auto_run, + compilation_mode=compilation_mode, + ) + + @staticmethod + def _n_coeffs_from_n_points(n_points: int) -> tuple[int, int, int, int]: + return (1 + n_points, 1 + n_points + 1, 1 + n_points + 1, 1 + n_points + 4) + + @staticmethod + def _n_points_from_n_coeffs(n_coeffs: int) -> int: + # n_coeffs = 10 + 4n_points => 4n_points = n_coeffs - 10 + assert n_coeffs >= 10 + assert (n_coeffs - 10) % 4 == 0 + return (n_coeffs - 10) // 4 + + def build_input(self) -> list[PyFelt]: + input = [] + input.extend([self.field.random(), self.field.random()]) # xA0, xA2 + n_coeffs = self._n_coeffs_from_n_points(self.n_points) + for _ in range(sum(n_coeffs)): + input.append(self.field(randint(0, CURVES[self.curve_id].p - 1))) + return input + + def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: + circuit = ECIPCircuits( + self.name, self.curve_id, compilation_mode=self.compilation_mode + ) + xA0 = circuit.write_struct(u384("xA0", [input[0]]), WriteOps.INPUT) + xA2 = circuit.write_struct(u384("xA2", [input[1]]), WriteOps.INPUT) + + all_coeffs = input[2:] + + def split_list(input_list, lengths): + start_idx, result = 0, [] + for length in lengths: + result.append(input_list[start_idx : start_idx + length]) + start_idx += length + return result + + n_points = self._n_points_from_n_coeffs(len(all_coeffs)) + _log_div_a_num, _log_div_a_den, _log_div_b_num, _log_div_b_den = split_list( + all_coeffs, self._n_coeffs_from_n_points(n_points) + ) + + log_div_a_num = circuit.write_struct( + structs.u384Span("log_div_a_num", _log_div_a_num), WriteOps.INPUT + ) + log_div_a_den = circuit.write_struct( + structs.u384Span("log_div_a_den", _log_div_a_den), WriteOps.INPUT + ) + log_div_b_num = circuit.write_struct( + structs.u384Span("log_div_b_num", _log_div_b_num), WriteOps.INPUT + ) + log_div_b_den = circuit.write_struct( + structs.u384Span("log_div_b_den", _log_div_b_den), WriteOps.INPUT + ) + + res = circuit._init_function_challenge_dupl( + xA0, xA2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den + ) + circuit.extend_struct_output( + structs.FunctionFeltEvaluations("A0_evals", res[0:4]) + ) + circuit.extend_struct_output( + structs.FunctionFeltEvaluations("A2_evals", res[4:8]) + ) + circuit.extend_struct_output(u384("xA0_power", [res[8]])) + circuit.extend_struct_output(u384("xA2_power", [res[9]])) + return circuit + +class AccumulateFunctionChallengeDuplCircuit(BaseModuloCircuit): + def __init__( + self, + curve_id: int, + auto_run: bool = True, + compilation_mode: int = 0, + ): + super().__init__( + name="acc_function_challenge_dupl", + input_len=None, + curve_id=curve_id, + auto_run=auto_run, + compilation_mode=compilation_mode, + ) + + def build_input(self) -> list[PyFelt]: + input = [] + input.extend( + [self.field.random() for _ in range(8)] + ) # a_num, a_den, b_num, b_den accumulation evals * 2 + input.extend([self.field.random(), self.field.random()]) # xA0, xA2 + input.extend( + [self.field.random(), self.field.random()] + ) # xA0_power, xA2_power, corresponding the max degree of a_den or b_num of the previous accumulator + input.extend( + [self.field.random() for _ in range(4)] + ) # next coefficients of a_num, a_den, b_num, b_den + return input + + def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: + circuit = ECIPCircuits( + self.name, self.curve_id, compilation_mode=self.compilation_mode + ) + + f_a0_accs = circuit.write_struct( + structs.FunctionFeltEvaluations("f_a0_accs", input[0:4]), WriteOps.INPUT + ) + f_a1_accs = circuit.write_struct( + structs.FunctionFeltEvaluations("f_a1_accs", input[4:8]), WriteOps.INPUT + ) + xA0 = circuit.write_struct(u384("xA0", [input[8]]), WriteOps.INPUT) + xA2 = circuit.write_struct(u384("xA2", [input[9]]), WriteOps.INPUT) + xA0_power = circuit.write_struct(u384("xA0_power", [input[10]]), WriteOps.INPUT) + xA2_power = circuit.write_struct(u384("xA2_power", [input[11]]), WriteOps.INPUT) + next_a_num_coeff = circuit.write_struct( + u384("next_a_num_coeff", [input[12]]), WriteOps.INPUT + ) + next_a_den_coeff = circuit.write_struct( + u384("next_a_den_coeff", [input[13]]), WriteOps.INPUT + ) + next_b_num_coeff = circuit.write_struct( + u384("next_b_num_coeff", [input[14]]), WriteOps.INPUT + ) + next_b_den_coeff = circuit.write_struct( + u384("next_b_den_coeff", [input[15]]), WriteOps.INPUT + ) + + res = circuit._accumulate_function_challenge_dupl( + *f_a0_accs, + *f_a1_accs, + xA0, + xA2, + xA0_power, + xA2_power, + next_a_num_coeff, + next_a_den_coeff, + next_b_num_coeff, + next_b_den_coeff, + ) + + circuit.extend_struct_output( + structs.FunctionFeltEvaluations("next_f_a0_accs", res[0:4]) + ) + circuit.extend_struct_output( + structs.FunctionFeltEvaluations("next_f_a1_accs", res[4:8]) + ) + circuit.extend_struct_output(u384("next_xA0_power", [res[8]])) + circuit.extend_struct_output(u384("next_xA2_power", [res[9]])) + return circuit + + +class FinalizeFunctionChallengeDuplCircuit(BaseModuloCircuit): + def __init__( + self, + curve_id: int, + auto_run: bool = True, + compilation_mode: int = 0, + ): + super().__init__( + name="final_function_challenge_dupl", + input_len=None, + curve_id=curve_id, + auto_run=auto_run, + compilation_mode=compilation_mode, + ) + + def build_input(self) -> list[PyFelt]: + input = [] + input.extend([self.field.random() for _ in range(8)]) # f_a0_accs, f_a1_accs + input.extend([self.field.random() for _ in range(2)]) # yA0, yA2 + input.extend([self.field.random() for _ in range(2)]) # coeff_A0, coeff_A2 + return input + + def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: + circuit = ECIPCircuits( + self.name, self.curve_id, compilation_mode=self.compilation_mode + ) + f_a0_accs = circuit.write_struct( + structs.FunctionFeltEvaluations("f_a0_accs", input[0:4]), WriteOps.INPUT + ) + f_a1_accs = circuit.write_struct( + structs.FunctionFeltEvaluations("f_a1_accs", input[4:8]), WriteOps.INPUT + ) + yA0 = circuit.write_struct(u384("yA0", [input[8]]), WriteOps.INPUT) + yA2 = circuit.write_struct(u384("yA2", [input[9]]), WriteOps.INPUT) + coeff_A0 = circuit.write_struct(u384("coeff_A0", [input[10]]), WriteOps.INPUT) + coeff_A2 = circuit.write_struct(u384("coeff_A2", [input[11]]), WriteOps.INPUT) + + res = circuit._finalize_function_challenge_dupl( + *f_a0_accs, *f_a1_accs, yA0, yA2, coeff_A0, coeff_A2 + ) + + circuit.extend_struct_output(u384("res", [res])) return circuit @@ -531,11 +844,11 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = BasicEC( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - xP, yP, xQ, yQ = circuit.write_elements(input[0:4], WriteOps.INPUT) + xP, yP = circuit.write_struct(G1PointCircuit("p", input[0:2]), WriteOps.INPUT) + xQ, yQ = circuit.write_struct(G1PointCircuit("q", input[2:4]), WriteOps.INPUT) xR, yR = circuit.add_points((xP, yP), (xQ, yQ)) - circuit.extend_output([xR, yR]) + circuit.extend_struct_output(G1PointCircuit("r", [xR, yR])) - # circuit.print_value_segment() return circuit @@ -566,9 +879,10 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ModuloCircuit: circuit = BasicEC( self.name, self.curve_id, compilation_mode=self.compilation_mode ) - xP, yP, A = circuit.write_elements(input[0:3], WriteOps.INPUT) + xP, yP = circuit.write_struct(G1PointCircuit("p", input[0:2]), WriteOps.INPUT) + A = circuit.write_struct(u384("A_weirstrass", [input[2]])) xR, yR = circuit.double_point((xP, yP), A) - circuit.extend_output([xR, yR]) + circuit.extend_struct_output(G1PointCircuit("r", [xR, yR])) return circuit @@ -2074,7 +2388,22 @@ def _run_circuit_inner(self, input: list[PyFelt]) -> ExtensionFieldModuloCircuit }, CircuitID.EVAL_FUNCTION_CHALLENGE_DUPL: { "class": EvalFunctionChallengeDuplCircuit, - "params": [{"n_points": k} for k in range(1, 4)], + "params": [{"n_points": k} for k in [1, 2, 3, 4]], + "filename": "ec", + }, + CircuitID.INIT_FUNCTION_CHALLENGE_DUPL: { + "class": InitFunctionChallengeDuplCircuit, + "params": [{"n_points": k} for k in [5]], + "filename": "ec", + }, + CircuitID.ACC_FUNCTION_CHALLENGE_DUPL: { + "class": AccumulateFunctionChallengeDuplCircuit, + "params": None, + "filename": "ec", + }, + CircuitID.FINALIZE_FUNCTION_CHALLENGE_DUPL: { + "class": FinalizeFunctionChallengeDuplCircuit, + "params": None, "filename": "ec", }, CircuitID.FP12_MUL: { @@ -2133,6 +2462,7 @@ def compilation_mode_to_file_header(mode: int) -> str: use core::circuit::CircuitElement as CE; use core::circuit::CircuitInput as CI; use garaga::definitions::{get_a, get_b, get_p, get_g, get_min_one, G1Point, G2Point, E12D, E12DMulQuotient, G1G2Pair, BNProcessedPair, BLSProcessedPair, MillerLoopResultScalingFactor}; +use garaga::ec_ops::{SlopeInterceptOutput, FunctionFeltEvaluations}; use core::option::Option;\n """ @@ -2149,6 +2479,7 @@ def cairo1_tests_header() -> str: CircuitOutputsTrait, CircuitModulus, AddInputResultTrait, CircuitInputs }; use garaga::definitions::{G1Point, G2Point, E12D, E12DMulQuotient, G1G2Pair, BNProcessedPair, BLSProcessedPair, MillerLoopResultScalingFactor}; + use garaga::ec_ops::{SlopeInterceptOutput, FunctionFeltEvaluations}; """ @@ -2441,6 +2772,11 @@ def format_cairo_files_in_parallel(filenames, compilation_mode): "params": None, "filename": "ec", }, + CircuitID.IS_ON_CURVE_G2: { + "class": IsOnCurveG2Circuit, + "params": None, + "filename": "ec", + }, CircuitID.SLOPE_INTERCEPT_SAME_POINT: { "class": SlopeInterceptSamePointCircuit, "params": None, @@ -2458,7 +2794,22 @@ def format_cairo_files_in_parallel(filenames, compilation_mode): }, CircuitID.EVAL_FUNCTION_CHALLENGE_DUPL: { "class": EvalFunctionChallengeDuplCircuit, - "params": [{"n_points": k} for k in [1, 2, 3]], + "params": [{"n_points": k} for k in [1, 2, 3, 4]], + "filename": "ec", + }, + CircuitID.INIT_FUNCTION_CHALLENGE_DUPL: { + "class": InitFunctionChallengeDuplCircuit, + "params": [{"n_points": k} for k in [5]], + "filename": "ec", + }, + CircuitID.ACC_FUNCTION_CHALLENGE_DUPL: { + "class": AccumulateFunctionChallengeDuplCircuit, + "params": None, + "filename": "ec", + }, + CircuitID.FINALIZE_FUNCTION_CHALLENGE_DUPL: { + "class": FinalizeFunctionChallengeDuplCircuit, + "params": None, "filename": "ec", }, CircuitID.FP12_MUL: { diff --git a/hydra/precompiled_circuits/ec.py b/hydra/precompiled_circuits/ec.py index d9846e9d..0cbca7be 100644 --- a/hydra/precompiled_circuits/ec.py +++ b/hydra/precompiled_circuits/ec.py @@ -19,11 +19,17 @@ def __init__(self, name: str, curve_id: int, compilation_mode: int = 0): ) self.curve = CURVES[curve_id] - def set_consts(self, a: PyFelt, b: PyFelt, b20: PyFelt, b21: PyFelt): - self.a = self.write_element(a) - self.b = self.write_element(b) - self.b20 = self.write_element(b20) - self.b21 = self.write_element(b21) + def set_consts( + self, + a: PyFelt | ModuloCircuitElement, + b: PyFelt | ModuloCircuitElement, + b20: PyFelt | ModuloCircuitElement, + b21: PyFelt | ModuloCircuitElement, + ): + self.a = self.write_element(a) if type(a) == PyFelt else a + self.b = self.write_element(b) if type(b) == PyFelt else b + self.b20 = self.write_element(b20) if type(b20) == PyFelt else b20 + self.b21 = self.write_element(b21) if type(b21) == PyFelt else b21 def _is_on_curve_G1( self, x: ModuloCircuitElement, y: ModuloCircuitElement @@ -296,6 +302,146 @@ def _eval_function_challenge_dupl( return res + def _init_function_challenge_dupl( + self, + xA0: ModuloCircuitElement, + xA2: ModuloCircuitElement, + log_div_a_num: list[ModuloCircuitElement], + log_div_a_den: list[ModuloCircuitElement], + log_div_b_num: list[ModuloCircuitElement], + log_div_b_den: list[ModuloCircuitElement], + ) -> tuple[ModuloCircuitElement, ModuloCircuitElement]: + + # F = a(x) + y*b(x), a and b being rational functions. + # computes F(A0) and F(A2) + + # Precompute powers of xA0 and xA2 for evaluating the polynomials. + xA0_powers = [xA0] + xA2_powers = [xA2] + for _ in range(len(log_div_b_den) - 2): + xA0_powers.append(self.mul(xA0_powers[-1], xA0)) + xA2_powers.append(self.mul(xA2_powers[-1], xA2)) + + A_NUM_A0 = self.eval_poly(log_div_a_num, xA0_powers) + A_DEN_A0 = self.eval_poly(log_div_a_den, xA0_powers) + B_NUM_A0 = self.eval_poly(log_div_b_num, xA0_powers) + B_DEN_A0 = self.eval_poly(log_div_b_den, xA0_powers) + + A_NUM_A2 = self.eval_poly(log_div_a_num, xA2_powers) + A_DEN_A2 = self.eval_poly(log_div_a_den, xA2_powers) + B_NUM_A2 = self.eval_poly(log_div_b_num, xA2_powers) + B_DEN_A2 = self.eval_poly(log_div_b_den, xA2_powers) + + # return F(A0) and F(A2), and the last power of xA0 and xA2 used in a_den (also equal to b_num) + + a_den_degree = len(log_div_a_den) - 1 + assert a_den_degree == len(log_div_b_num) - 1 + + return ( + A_NUM_A0, + A_DEN_A0, + B_NUM_A0, + B_DEN_A0, + A_NUM_A2, + A_DEN_A2, + B_NUM_A2, + B_DEN_A2, + xA0_powers[a_den_degree], + xA2_powers[a_den_degree], + ) + + def _accumulate_function_challenge_dupl( + self, + a_num_acc_A0: ModuloCircuitElement, + a_den_acc_A0: ModuloCircuitElement, + b_num_acc_A0: ModuloCircuitElement, + b_den_acc_A0: ModuloCircuitElement, + a_num_acc_A2: ModuloCircuitElement, + a_den_acc_A2: ModuloCircuitElement, + b_num_acc_A2: ModuloCircuitElement, + b_den_acc_A2: ModuloCircuitElement, + xA0: ModuloCircuitElement, + xA2: ModuloCircuitElement, + xA0_power: ModuloCircuitElement, + xA2_power: ModuloCircuitElement, + next_a_num_coeff: ModuloCircuitElement, + next_a_den_coeff: ModuloCircuitElement, + next_b_num_coeff: ModuloCircuitElement, + next_b_den_coeff: ModuloCircuitElement, + ): + # Update accumulators for A0 + new_a_num_acc_A0 = self.add(a_num_acc_A0, self.mul(next_a_num_coeff, xA0_power)) + next_xA0_power = self.mul(xA0_power, xA0) + new_a_den_acc_A0 = self.add( + a_den_acc_A0, self.mul(next_a_den_coeff, next_xA0_power) + ) + new_b_num_acc_A0 = self.add( + b_num_acc_A0, self.mul(next_b_num_coeff, next_xA0_power) + ) + next_b_den_A0_power = next_xA0_power + for _ in range(3): + next_b_den_A0_power = self.mul(next_b_den_A0_power, xA0) + new_b_den_acc_A0 = self.add( + b_den_acc_A0, self.mul(next_b_den_coeff, next_b_den_A0_power) + ) + + # Update accumulators for A2 + new_a_num_acc_A2 = self.add(a_num_acc_A2, self.mul(next_a_num_coeff, xA2_power)) + next_xA2_power = self.mul(xA2_power, xA2) + new_a_den_acc_A2 = self.add( + a_den_acc_A2, self.mul(next_a_den_coeff, next_xA2_power) + ) + new_b_num_acc_A2 = self.add( + b_num_acc_A2, self.mul(next_b_num_coeff, next_xA2_power) + ) + next_b_den_A2_power = next_xA2_power + for _ in range(3): + next_b_den_A2_power = self.mul(next_b_den_A2_power, xA2) + new_b_den_acc_A2 = self.add( + b_den_acc_A2, self.mul(next_b_den_coeff, next_b_den_A2_power) + ) + + return ( + new_a_num_acc_A0, + new_a_den_acc_A0, + new_b_num_acc_A0, + new_b_den_acc_A0, + new_a_num_acc_A2, + new_a_den_acc_A2, + new_b_num_acc_A2, + new_b_den_acc_A2, + next_xA0_power, + next_xA2_power, + ) + + def _finalize_function_challenge_dupl( + self, + a_num_acc_A0: ModuloCircuitElement, + a_den_acc_A0: ModuloCircuitElement, + b_num_acc_A0: ModuloCircuitElement, + b_den_acc_A0: ModuloCircuitElement, + a_num_acc_A2: ModuloCircuitElement, + a_den_acc_A2: ModuloCircuitElement, + b_num_acc_A2: ModuloCircuitElement, + b_den_acc_A2: ModuloCircuitElement, + yA0: ModuloCircuitElement, + yA2: ModuloCircuitElement, + coeff_A0: ModuloCircuitElement, + coeff_A2: ModuloCircuitElement, + ): + F_A0 = self.add( + self.div(a_num_acc_A0, a_den_acc_A0), + self.mul(yA0, self.div(b_num_acc_A0, b_den_acc_A0)), + ) + F_A2 = self.add( + self.div(a_num_acc_A2, a_den_acc_A2), + self.mul(yA2, self.div(b_num_acc_A2, b_den_acc_A2)), + ) + + # return coeff0*F(A0) - coeff2*F(A2) + res = self.sub(self.mul(coeff_A0, F_A0), self.mul(coeff_A2, F_A2)) + return res + class BasicEC(ModuloCircuit): def __init__(self, name: str, curve_id: int, compilation_mode: int = 0): @@ -383,3 +529,26 @@ def _is_on_curve_G1_weirstrass( ax = self.mul(A, x) x3_ax_b = self.add(x3, self.add(ax, b)) return y2, x3_ax_b + + def _is_on_curve_G2_weirstrass( + self, + x0: ModuloCircuitElement, + x1: ModuloCircuitElement, + y0: ModuloCircuitElement, + y1: ModuloCircuitElement, + a: ModuloCircuitElement, + b0: ModuloCircuitElement, + b1: ModuloCircuitElement, + ): + # y^2 = x^3 + ax + b [Fp2] + + y2 = self.fp2_square([y0, y1]) + x2 = self.fp2_square([x0, x1]) + x3 = self.fp2_mul([x0, x1], x2) + + ax = [self.mul(a, x0), self.mul(a, x1)] + ax_b = [self.add(ax[0], b0), self.add(ax[1], b1)] + + x3_ax_b = [self.add(x3[0], ax_b[0]), self.add(x3[1], ax_b[1])] + + return y2, x3_ax_b diff --git a/src/cairo/src/circuits/ec.cairo b/src/cairo/src/circuits/ec.cairo index 50e157c4..3a6e9032 100644 --- a/src/cairo/src/circuits/ec.cairo +++ b/src/cairo/src/circuits/ec.cairo @@ -10,11 +10,21 @@ use garaga::definitions::{ get_a, get_b, get_p, get_g, get_min_one, G1Point, G2Point, E12D, E12DMulQuotient, G1G2Pair, BNProcessedPair, BLSProcessedPair, MillerLoopResultScalingFactor }; +use garaga::ec_ops::{SlopeInterceptOutput, FunctionFeltEvaluations}; use core::option::Option; fn run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit( - mut input: Array, curve_index: usize -) -> Array { + acc: u384, + m: u384, + b: u384, + xA: u384, + p: G1Point, + ep: u384, + en: u384, + sp: u384, + sn: u384, + curve_index: usize +) -> (u384,) { // CONSTANT stack let in0 = CE::> {}; // 0x0 @@ -41,28 +51,127 @@ fn run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit( let t14 = circuit_add(t9, t13); let t15 = circuit_add(in1, t14); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t15,).new_inputs(); // Prefill constants: circuit_inputs = circuit_inputs.next([0x0, 0x0, 0x0, 0x0]); + circuit_inputs = circuit_inputs.next(acc); + circuit_inputs = circuit_inputs.next(m); + circuit_inputs = circuit_inputs.next(b); + circuit_inputs = circuit_inputs.next(xA); + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(ep); + circuit_inputs = circuit_inputs.next(en); + circuit_inputs = circuit_inputs.next(sp); + circuit_inputs = circuit_inputs.next(sn); - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); + let outputs = match circuit_inputs.done().eval(modulus) { + Result::Ok(outputs) => { outputs }, + Result::Err(_) => { panic!("Expected success") } }; + let res_acc: u384 = outputs.get_output(t15); + return (res_acc,); +} +fn run_ACC_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs: FunctionFeltEvaluations, + f_a1_accs: FunctionFeltEvaluations, + xA0: u384, + xA2: u384, + xA0_power: u384, + xA2_power: u384, + next_a_num_coeff: u384, + next_a_den_coeff: u384, + next_b_num_coeff: u384, + next_b_den_coeff: u384, + curve_index: usize +) -> (FunctionFeltEvaluations, FunctionFeltEvaluations, u384, u384) { + // INPUT stack + let (in0, in1) = (CE::> {}, CE::> {}); + let (in2, in3) = (CE::> {}, CE::> {}); + let (in4, in5) = (CE::> {}, CE::> {}); + let (in6, in7) = (CE::> {}, CE::> {}); + let (in8, in9) = (CE::> {}, CE::> {}); + let (in10, in11) = (CE::> {}, CE::> {}); + let (in12, in13) = (CE::> {}, CE::> {}); + let (in14, in15) = (CE::> {}, CE::> {}); + let t0 = circuit_mul(in12, in10); + let t1 = circuit_add(in0, t0); + let t2 = circuit_mul(in10, in8); + let t3 = circuit_mul(in13, t2); + let t4 = circuit_add(in1, t3); + let t5 = circuit_mul(in14, t2); + let t6 = circuit_add(in2, t5); + let t7 = circuit_mul(t2, in8); + let t8 = circuit_mul(t7, in8); + let t9 = circuit_mul(t8, in8); + let t10 = circuit_mul(in15, t9); + let t11 = circuit_add(in3, t10); + let t12 = circuit_mul(in12, in11); + let t13 = circuit_add(in4, t12); + let t14 = circuit_mul(in11, in9); + let t15 = circuit_mul(in13, t14); + let t16 = circuit_add(in5, t15); + let t17 = circuit_mul(in14, t14); + let t18 = circuit_add(in6, t17); + let t19 = circuit_mul(t14, in9); + let t20 = circuit_mul(t19, in9); + let t21 = circuit_mul(t20, in9); + let t22 = circuit_mul(in15, t21); + let t23 = circuit_add(in7, t22); + + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) + .unwrap(); + + let mut circuit_inputs = (t1, t4, t6, t11, t13, t16, t18, t23, t2, t14,).new_inputs(); + // Prefill constants: + + circuit_inputs = circuit_inputs.next(f_a0_accs.a_num); + circuit_inputs = circuit_inputs.next(f_a0_accs.a_den); + circuit_inputs = circuit_inputs.next(f_a0_accs.b_num); + circuit_inputs = circuit_inputs.next(f_a0_accs.b_den); + circuit_inputs = circuit_inputs.next(f_a1_accs.a_num); + circuit_inputs = circuit_inputs.next(f_a1_accs.a_den); + circuit_inputs = circuit_inputs.next(f_a1_accs.b_num); + circuit_inputs = circuit_inputs.next(f_a1_accs.b_den); + circuit_inputs = circuit_inputs.next(xA0); + circuit_inputs = circuit_inputs.next(xA2); + circuit_inputs = circuit_inputs.next(xA0_power); + circuit_inputs = circuit_inputs.next(xA2_power); + circuit_inputs = circuit_inputs.next(next_a_num_coeff); + circuit_inputs = circuit_inputs.next(next_a_den_coeff); + circuit_inputs = circuit_inputs.next(next_b_num_coeff); + circuit_inputs = circuit_inputs.next(next_b_den_coeff); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t15)]; - return res; + let next_f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: outputs.get_output(t1), + a_den: outputs.get_output(t4), + b_num: outputs.get_output(t6), + b_den: outputs.get_output(t11) + }; + let next_f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: outputs.get_output(t13), + a_den: outputs.get_output(t16), + b_num: outputs.get_output(t18), + b_den: outputs.get_output(t23) + }; + let next_xA0_power: u384 = outputs.get_output(t2); + let next_xA2_power: u384 = outputs.get_output(t14); + return (next_f_a0_accs, next_f_a1_accs, next_xA0_power, next_xA2_power); } - -fn run_ADD_EC_POINT_circuit(mut input: Array, curve_index: usize) -> Array { +fn run_ADD_EC_POINT_circuit(p: G1Point, q: G1Point, curve_index: usize) -> (G1Point,) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -77,27 +186,28 @@ fn run_ADD_EC_POINT_circuit(mut input: Array, curve_index: usize) -> Array let t8 = circuit_mul(t3, t7); let t9 = circuit_sub(t8, in1); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t6, t9,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(q.x); + circuit_inputs = circuit_inputs.next(q.y); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t6), outputs.get_output(t9)]; - return res; + let r: G1Point = G1Point { x: outputs.get_output(t6), y: outputs.get_output(t9) }; + return (r,); } - -fn run_DOUBLE_EC_POINT_circuit(mut input: Array, curve_index: usize) -> Array { +fn run_DOUBLE_EC_POINT_circuit(p: G1Point, A_weirstrass: u384, curve_index: usize) -> (G1Point,) { // CONSTANT stack let in0 = CE::> {}; // 0x3 @@ -117,30 +227,37 @@ fn run_DOUBLE_EC_POINT_circuit(mut input: Array, curve_index: usize) -> Ar let t10 = circuit_mul(t5, t9); let t11 = circuit_sub(in2, t10); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t8, t11,).new_inputs(); // Prefill constants: circuit_inputs = circuit_inputs.next([0x3, 0x0, 0x0, 0x0]); - - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(A_weirstrass); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t8), outputs.get_output(t11)]; - return res; + let r: G1Point = G1Point { x: outputs.get_output(t8), y: outputs.get_output(t11) }; + return (r,); } - fn run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit( - mut input: Array, curve_index: usize -) -> Array { + A0: G1Point, + A2: G1Point, + coeff0: u384, + coeff2: u384, + log_div_a_num: Span, + log_div_a_den: Span, + log_div_b_num: Span, + log_div_b_den: Span, + curve_index: usize +) -> (u384,) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -216,29 +333,60 @@ fn run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit( let t61 = circuit_mul(in5, t59); let t62 = circuit_sub(t60, t61); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t62,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); + circuit_inputs = circuit_inputs.next(A0.x); + circuit_inputs = circuit_inputs.next(A0.y); + circuit_inputs = circuit_inputs.next(A2.x); + circuit_inputs = circuit_inputs.next(A2.y); + circuit_inputs = circuit_inputs.next(coeff0); + circuit_inputs = circuit_inputs.next(coeff2); + + let mut log_div_a_num = log_div_a_num; + while let Option::Some(val) = log_div_a_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_a_den = log_div_a_den; + while let Option::Some(val) = log_div_a_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_num = log_div_b_num; + while let Option::Some(val) = log_div_b_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_den = log_div_b_den; + while let Option::Some(val) = log_div_b_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); }; let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t62)]; - return res; + let res: u384 = outputs.get_output(t62); + return (res,); } - fn run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit( - mut input: Array, curve_index: usize -) -> Array { + A0: G1Point, + A2: G1Point, + coeff0: u384, + coeff2: u384, + log_div_a_num: Span, + log_div_a_den: Span, + log_div_b_num: Span, + log_div_b_den: Span, + curve_index: usize +) -> (u384,) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -334,29 +482,60 @@ fn run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit( let t79 = circuit_mul(in5, t77); let t80 = circuit_sub(t78, t79); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t80,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); + circuit_inputs = circuit_inputs.next(A0.x); + circuit_inputs = circuit_inputs.next(A0.y); + circuit_inputs = circuit_inputs.next(A2.x); + circuit_inputs = circuit_inputs.next(A2.y); + circuit_inputs = circuit_inputs.next(coeff0); + circuit_inputs = circuit_inputs.next(coeff2); + + let mut log_div_a_num = log_div_a_num; + while let Option::Some(val) = log_div_a_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_a_den = log_div_a_den; + while let Option::Some(val) = log_div_a_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_num = log_div_b_num; + while let Option::Some(val) = log_div_b_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_den = log_div_b_den; + while let Option::Some(val) = log_div_b_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); }; let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t80)]; - return res; + let res: u384 = outputs.get_output(t80); + return (res,); } - fn run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit( - mut input: Array, curve_index: usize -) -> Array { + A0: G1Point, + A2: G1Point, + coeff0: u384, + coeff2: u384, + log_div_a_num: Span, + log_div_a_den: Span, + log_div_b_num: Span, + log_div_b_den: Span, + curve_index: usize +) -> (u384,) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -472,27 +651,501 @@ fn run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit( let t97 = circuit_mul(in5, t95); let t98 = circuit_sub(t96, t97); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t98,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); + circuit_inputs = circuit_inputs.next(A0.x); + circuit_inputs = circuit_inputs.next(A0.y); + circuit_inputs = circuit_inputs.next(A2.x); + circuit_inputs = circuit_inputs.next(A2.y); + circuit_inputs = circuit_inputs.next(coeff0); + circuit_inputs = circuit_inputs.next(coeff2); + + let mut log_div_a_num = log_div_a_num; + while let Option::Some(val) = log_div_a_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_a_den = log_div_a_den; + while let Option::Some(val) = log_div_a_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_num = log_div_b_num; + while let Option::Some(val) = log_div_b_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_den = log_div_b_den; + while let Option::Some(val) = log_div_b_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let outputs = match circuit_inputs.done().eval(modulus) { + Result::Ok(outputs) => { outputs }, + Result::Err(_) => { panic!("Expected success") } + }; + let res: u384 = outputs.get_output(t98); + return (res,); +} +fn run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit( + A0: G1Point, + A2: G1Point, + coeff0: u384, + coeff2: u384, + log_div_a_num: Span, + log_div_a_den: Span, + log_div_b_num: Span, + log_div_b_den: Span, + curve_index: usize +) -> (u384,) { + // INPUT stack + let (in0, in1) = (CE::> {}, CE::> {}); + let (in2, in3) = (CE::> {}, CE::> {}); + let (in4, in5) = (CE::> {}, CE::> {}); + let (in6, in7) = (CE::> {}, CE::> {}); + let (in8, in9) = (CE::> {}, CE::> {}); + let (in10, in11) = (CE::> {}, CE::> {}); + let (in12, in13) = (CE::> {}, CE::> {}); + let (in14, in15) = (CE::> {}, CE::> {}); + let (in16, in17) = (CE::> {}, CE::> {}); + let (in18, in19) = (CE::> {}, CE::> {}); + let (in20, in21) = (CE::> {}, CE::> {}); + let (in22, in23) = (CE::> {}, CE::> {}); + let (in24, in25) = (CE::> {}, CE::> {}); + let (in26, in27) = (CE::> {}, CE::> {}); + let (in28, in29) = (CE::> {}, CE::> {}); + let (in30, in31) = (CE::> {}, CE::> {}); + let t0 = circuit_mul(in0, in0); + let t1 = circuit_mul(in2, in2); + let t2 = circuit_mul(t0, in0); + let t3 = circuit_mul(t1, in2); + let t4 = circuit_mul(t2, in0); + let t5 = circuit_mul(t3, in2); + let t6 = circuit_mul(t4, in0); + let t7 = circuit_mul(t5, in2); + let t8 = circuit_mul(t6, in0); + let t9 = circuit_mul(t7, in2); + let t10 = circuit_mul(t8, in0); + let t11 = circuit_mul(t9, in2); + let t12 = circuit_mul(t10, in0); + let t13 = circuit_mul(t11, in2); + let t14 = circuit_mul(in7, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t15 = circuit_add(in6, t14); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t16 = circuit_mul(in8, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t17 = circuit_add(t15, t16); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t18 = circuit_mul(in9, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t19 = circuit_add(t17, t18); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t20 = circuit_mul(in10, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t21 = circuit_add(t19, t20); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t22 = circuit_mul(in12, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t23 = circuit_add(in11, t22); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t24 = circuit_mul(in13, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t25 = circuit_add(t23, t24); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t26 = circuit_mul(in14, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t27 = circuit_add(t25, t26); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t28 = circuit_mul(in15, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t29 = circuit_add(t27, t28); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t30 = circuit_mul(in16, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t31 = circuit_add(t29, t30); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t32 = circuit_inverse(t31); + let t33 = circuit_mul(t21, t32); + let t34 = circuit_mul(in18, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t35 = circuit_add(in17, t34); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t36 = circuit_mul(in19, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t37 = circuit_add(t35, t36); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t38 = circuit_mul(in20, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t39 = circuit_add(t37, t38); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t40 = circuit_mul(in21, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t41 = circuit_add(t39, t40); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t42 = circuit_mul(in22, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t43 = circuit_add(t41, t42); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t44 = circuit_mul(in24, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t45 = circuit_add(in23, t44); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t46 = circuit_mul(in25, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t47 = circuit_add(t45, t46); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t48 = circuit_mul(in26, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t49 = circuit_add(t47, t48); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t50 = circuit_mul(in27, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t51 = circuit_add(t49, t50); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t52 = circuit_mul(in28, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t53 = circuit_add(t51, t52); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t54 = circuit_mul(in29, t8); // Eval UnnamedPoly step coeff_6 * x^6 + let t55 = circuit_add(t53, t54); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t56 = circuit_mul(in30, t10); // Eval UnnamedPoly step coeff_7 * x^7 + let t57 = circuit_add(t55, t56); // Eval UnnamedPoly step + (coeff_7 * x^7) + let t58 = circuit_mul(in31, t12); // Eval UnnamedPoly step coeff_8 * x^8 + let t59 = circuit_add(t57, t58); // Eval UnnamedPoly step + (coeff_8 * x^8) + let t60 = circuit_inverse(t59); + let t61 = circuit_mul(t43, t60); + let t62 = circuit_mul(in1, t61); + let t63 = circuit_add(t33, t62); + let t64 = circuit_mul(in7, in2); // Eval UnnamedPoly step coeff_1 * x^1 + let t65 = circuit_add(in6, t64); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t66 = circuit_mul(in8, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t67 = circuit_add(t65, t66); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t68 = circuit_mul(in9, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t69 = circuit_add(t67, t68); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t70 = circuit_mul(in10, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t71 = circuit_add(t69, t70); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t72 = circuit_mul(in12, in2); // Eval UnnamedPoly step coeff_1 * x^1 + let t73 = circuit_add(in11, t72); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t74 = circuit_mul(in13, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t75 = circuit_add(t73, t74); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t76 = circuit_mul(in14, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t77 = circuit_add(t75, t76); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t78 = circuit_mul(in15, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t79 = circuit_add(t77, t78); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t80 = circuit_mul(in16, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t81 = circuit_add(t79, t80); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t82 = circuit_inverse(t81); + let t83 = circuit_mul(t71, t82); + let t84 = circuit_mul(in18, in2); // Eval UnnamedPoly step coeff_1 * x^1 + let t85 = circuit_add(in17, t84); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t86 = circuit_mul(in19, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t87 = circuit_add(t85, t86); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t88 = circuit_mul(in20, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t89 = circuit_add(t87, t88); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t90 = circuit_mul(in21, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t91 = circuit_add(t89, t90); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t92 = circuit_mul(in22, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t93 = circuit_add(t91, t92); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t94 = circuit_mul(in24, in2); // Eval UnnamedPoly step coeff_1 * x^1 + let t95 = circuit_add(in23, t94); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t96 = circuit_mul(in25, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t97 = circuit_add(t95, t96); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t98 = circuit_mul(in26, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t99 = circuit_add(t97, t98); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t100 = circuit_mul(in27, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t101 = circuit_add(t99, t100); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t102 = circuit_mul(in28, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t103 = circuit_add(t101, t102); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t104 = circuit_mul(in29, t9); // Eval UnnamedPoly step coeff_6 * x^6 + let t105 = circuit_add(t103, t104); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t106 = circuit_mul(in30, t11); // Eval UnnamedPoly step coeff_7 * x^7 + let t107 = circuit_add(t105, t106); // Eval UnnamedPoly step + (coeff_7 * x^7) + let t108 = circuit_mul(in31, t13); // Eval UnnamedPoly step coeff_8 * x^8 + let t109 = circuit_add(t107, t108); // Eval UnnamedPoly step + (coeff_8 * x^8) + let t110 = circuit_inverse(t109); + let t111 = circuit_mul(t93, t110); + let t112 = circuit_mul(in3, t111); + let t113 = circuit_add(t83, t112); + let t114 = circuit_mul(in4, t63); + let t115 = circuit_mul(in5, t113); + let t116 = circuit_sub(t114, t115); + + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) + .unwrap(); + + let mut circuit_inputs = (t116,).new_inputs(); + // Prefill constants: + + circuit_inputs = circuit_inputs.next(A0.x); + circuit_inputs = circuit_inputs.next(A0.y); + circuit_inputs = circuit_inputs.next(A2.x); + circuit_inputs = circuit_inputs.next(A2.y); + circuit_inputs = circuit_inputs.next(coeff0); + circuit_inputs = circuit_inputs.next(coeff2); + + let mut log_div_a_num = log_div_a_num; + while let Option::Some(val) = log_div_a_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_a_den = log_div_a_den; + while let Option::Some(val) = log_div_a_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); }; + let mut log_div_b_num = log_div_b_num; + while let Option::Some(val) = log_div_b_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_den = log_div_b_den; + while let Option::Some(val) = log_div_b_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let outputs = match circuit_inputs.done().eval(modulus) { + Result::Ok(outputs) => { outputs }, + Result::Err(_) => { panic!("Expected success") } + }; + let res: u384 = outputs.get_output(t116); + return (res,); +} +fn run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs: FunctionFeltEvaluations, + f_a1_accs: FunctionFeltEvaluations, + yA0: u384, + yA2: u384, + coeff_A0: u384, + coeff_A2: u384, + curve_index: usize +) -> (u384,) { + // INPUT stack + let (in0, in1) = (CE::> {}, CE::> {}); + let (in2, in3) = (CE::> {}, CE::> {}); + let (in4, in5) = (CE::> {}, CE::> {}); + let (in6, in7) = (CE::> {}, CE::> {}); + let (in8, in9) = (CE::> {}, CE::> {}); + let (in10, in11) = (CE::> {}, CE::> {}); + let t0 = circuit_inverse(in1); + let t1 = circuit_mul(in0, t0); + let t2 = circuit_inverse(in3); + let t3 = circuit_mul(in2, t2); + let t4 = circuit_mul(in8, t3); + let t5 = circuit_add(t1, t4); + let t6 = circuit_inverse(in5); + let t7 = circuit_mul(in4, t6); + let t8 = circuit_inverse(in7); + let t9 = circuit_mul(in6, t8); + let t10 = circuit_mul(in9, t9); + let t11 = circuit_add(t7, t10); + let t12 = circuit_mul(in10, t5); + let t13 = circuit_mul(in11, t11); + let t14 = circuit_sub(t12, t13); + + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) + .unwrap(); + + let mut circuit_inputs = (t14,).new_inputs(); + // Prefill constants: + + circuit_inputs = circuit_inputs.next(f_a0_accs.a_num); + circuit_inputs = circuit_inputs.next(f_a0_accs.a_den); + circuit_inputs = circuit_inputs.next(f_a0_accs.b_num); + circuit_inputs = circuit_inputs.next(f_a0_accs.b_den); + circuit_inputs = circuit_inputs.next(f_a1_accs.a_num); + circuit_inputs = circuit_inputs.next(f_a1_accs.a_den); + circuit_inputs = circuit_inputs.next(f_a1_accs.b_num); + circuit_inputs = circuit_inputs.next(f_a1_accs.b_den); + circuit_inputs = circuit_inputs.next(yA0); + circuit_inputs = circuit_inputs.next(yA2); + circuit_inputs = circuit_inputs.next(coeff_A0); + circuit_inputs = circuit_inputs.next(coeff_A2); + let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t98)]; - return res; + let res: u384 = outputs.get_output(t14); + return (res,); } +fn run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit( + xA0: u384, + xA2: u384, + log_div_a_num: Span, + log_div_a_den: Span, + log_div_b_num: Span, + log_div_b_den: Span, + curve_index: usize +) -> (FunctionFeltEvaluations, FunctionFeltEvaluations, u384, u384) { + // INPUT stack + let (in0, in1) = (CE::> {}, CE::> {}); + let (in2, in3) = (CE::> {}, CE::> {}); + let (in4, in5) = (CE::> {}, CE::> {}); + let (in6, in7) = (CE::> {}, CE::> {}); + let (in8, in9) = (CE::> {}, CE::> {}); + let (in10, in11) = (CE::> {}, CE::> {}); + let (in12, in13) = (CE::> {}, CE::> {}); + let (in14, in15) = (CE::> {}, CE::> {}); + let (in16, in17) = (CE::> {}, CE::> {}); + let (in18, in19) = (CE::> {}, CE::> {}); + let (in20, in21) = (CE::> {}, CE::> {}); + let (in22, in23) = (CE::> {}, CE::> {}); + let (in24, in25) = (CE::> {}, CE::> {}); + let (in26, in27) = (CE::> {}, CE::> {}); + let (in28, in29) = (CE::> {}, CE::> {}); + let (in30, in31) = (CE::> {}, CE::> {}); + let t0 = circuit_mul(in0, in0); + let t1 = circuit_mul(in1, in1); + let t2 = circuit_mul(t0, in0); + let t3 = circuit_mul(t1, in1); + let t4 = circuit_mul(t2, in0); + let t5 = circuit_mul(t3, in1); + let t6 = circuit_mul(t4, in0); + let t7 = circuit_mul(t5, in1); + let t8 = circuit_mul(t6, in0); + let t9 = circuit_mul(t7, in1); + let t10 = circuit_mul(t8, in0); + let t11 = circuit_mul(t9, in1); + let t12 = circuit_mul(t10, in0); + let t13 = circuit_mul(t11, in1); + let t14 = circuit_mul(t12, in0); + let t15 = circuit_mul(t13, in1); + let t16 = circuit_mul(in3, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t17 = circuit_add(in2, t16); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t18 = circuit_mul(in4, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t19 = circuit_add(t17, t18); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t20 = circuit_mul(in5, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t21 = circuit_add(t19, t20); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t22 = circuit_mul(in6, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t23 = circuit_add(t21, t22); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t24 = circuit_mul(in7, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t25 = circuit_add(t23, t24); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t26 = circuit_mul(in9, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t27 = circuit_add(in8, t26); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t28 = circuit_mul(in10, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t29 = circuit_add(t27, t28); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t30 = circuit_mul(in11, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t31 = circuit_add(t29, t30); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t32 = circuit_mul(in12, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t33 = circuit_add(t31, t32); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t34 = circuit_mul(in13, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t35 = circuit_add(t33, t34); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t36 = circuit_mul(in14, t8); // Eval UnnamedPoly step coeff_6 * x^6 + let t37 = circuit_add(t35, t36); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t38 = circuit_mul(in16, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t39 = circuit_add(in15, t38); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t40 = circuit_mul(in17, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t41 = circuit_add(t39, t40); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t42 = circuit_mul(in18, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t43 = circuit_add(t41, t42); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t44 = circuit_mul(in19, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t45 = circuit_add(t43, t44); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t46 = circuit_mul(in20, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t47 = circuit_add(t45, t46); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t48 = circuit_mul(in21, t8); // Eval UnnamedPoly step coeff_6 * x^6 + let t49 = circuit_add(t47, t48); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t50 = circuit_mul(in23, in0); // Eval UnnamedPoly step coeff_1 * x^1 + let t51 = circuit_add(in22, t50); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t52 = circuit_mul(in24, t0); // Eval UnnamedPoly step coeff_2 * x^2 + let t53 = circuit_add(t51, t52); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t54 = circuit_mul(in25, t2); // Eval UnnamedPoly step coeff_3 * x^3 + let t55 = circuit_add(t53, t54); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t56 = circuit_mul(in26, t4); // Eval UnnamedPoly step coeff_4 * x^4 + let t57 = circuit_add(t55, t56); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t58 = circuit_mul(in27, t6); // Eval UnnamedPoly step coeff_5 * x^5 + let t59 = circuit_add(t57, t58); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t60 = circuit_mul(in28, t8); // Eval UnnamedPoly step coeff_6 * x^6 + let t61 = circuit_add(t59, t60); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t62 = circuit_mul(in29, t10); // Eval UnnamedPoly step coeff_7 * x^7 + let t63 = circuit_add(t61, t62); // Eval UnnamedPoly step + (coeff_7 * x^7) + let t64 = circuit_mul(in30, t12); // Eval UnnamedPoly step coeff_8 * x^8 + let t65 = circuit_add(t63, t64); // Eval UnnamedPoly step + (coeff_8 * x^8) + let t66 = circuit_mul(in31, t14); // Eval UnnamedPoly step coeff_9 * x^9 + let t67 = circuit_add(t65, t66); // Eval UnnamedPoly step + (coeff_9 * x^9) + let t68 = circuit_mul(in3, in1); // Eval UnnamedPoly step coeff_1 * x^1 + let t69 = circuit_add(in2, t68); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t70 = circuit_mul(in4, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t71 = circuit_add(t69, t70); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t72 = circuit_mul(in5, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t73 = circuit_add(t71, t72); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t74 = circuit_mul(in6, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t75 = circuit_add(t73, t74); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t76 = circuit_mul(in7, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t77 = circuit_add(t75, t76); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t78 = circuit_mul(in9, in1); // Eval UnnamedPoly step coeff_1 * x^1 + let t79 = circuit_add(in8, t78); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t80 = circuit_mul(in10, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t81 = circuit_add(t79, t80); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t82 = circuit_mul(in11, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t83 = circuit_add(t81, t82); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t84 = circuit_mul(in12, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t85 = circuit_add(t83, t84); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t86 = circuit_mul(in13, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t87 = circuit_add(t85, t86); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t88 = circuit_mul(in14, t9); // Eval UnnamedPoly step coeff_6 * x^6 + let t89 = circuit_add(t87, t88); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t90 = circuit_mul(in16, in1); // Eval UnnamedPoly step coeff_1 * x^1 + let t91 = circuit_add(in15, t90); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t92 = circuit_mul(in17, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t93 = circuit_add(t91, t92); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t94 = circuit_mul(in18, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t95 = circuit_add(t93, t94); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t96 = circuit_mul(in19, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t97 = circuit_add(t95, t96); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t98 = circuit_mul(in20, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t99 = circuit_add(t97, t98); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t100 = circuit_mul(in21, t9); // Eval UnnamedPoly step coeff_6 * x^6 + let t101 = circuit_add(t99, t100); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t102 = circuit_mul(in23, in1); // Eval UnnamedPoly step coeff_1 * x^1 + let t103 = circuit_add(in22, t102); // Eval UnnamedPoly step + (coeff_1 * x^1) + let t104 = circuit_mul(in24, t1); // Eval UnnamedPoly step coeff_2 * x^2 + let t105 = circuit_add(t103, t104); // Eval UnnamedPoly step + (coeff_2 * x^2) + let t106 = circuit_mul(in25, t3); // Eval UnnamedPoly step coeff_3 * x^3 + let t107 = circuit_add(t105, t106); // Eval UnnamedPoly step + (coeff_3 * x^3) + let t108 = circuit_mul(in26, t5); // Eval UnnamedPoly step coeff_4 * x^4 + let t109 = circuit_add(t107, t108); // Eval UnnamedPoly step + (coeff_4 * x^4) + let t110 = circuit_mul(in27, t7); // Eval UnnamedPoly step coeff_5 * x^5 + let t111 = circuit_add(t109, t110); // Eval UnnamedPoly step + (coeff_5 * x^5) + let t112 = circuit_mul(in28, t9); // Eval UnnamedPoly step coeff_6 * x^6 + let t113 = circuit_add(t111, t112); // Eval UnnamedPoly step + (coeff_6 * x^6) + let t114 = circuit_mul(in29, t11); // Eval UnnamedPoly step coeff_7 * x^7 + let t115 = circuit_add(t113, t114); // Eval UnnamedPoly step + (coeff_7 * x^7) + let t116 = circuit_mul(in30, t13); // Eval UnnamedPoly step coeff_8 * x^8 + let t117 = circuit_add(t115, t116); // Eval UnnamedPoly step + (coeff_8 * x^8) + let t118 = circuit_mul(in31, t15); // Eval UnnamedPoly step coeff_9 * x^9 + let t119 = circuit_add(t117, t118); // Eval UnnamedPoly step + (coeff_9 * x^9) + + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) + .unwrap(); + + let mut circuit_inputs = (t25, t37, t49, t67, t77, t89, t101, t119, t10, t11,).new_inputs(); + // Prefill constants: + + circuit_inputs = circuit_inputs.next(xA0); + circuit_inputs = circuit_inputs.next(xA2); + + let mut log_div_a_num = log_div_a_num; + while let Option::Some(val) = log_div_a_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_a_den = log_div_a_den; + while let Option::Some(val) = log_div_a_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_num = log_div_b_num; + while let Option::Some(val) = log_div_b_num.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; + + let mut log_div_b_den = log_div_b_den; + while let Option::Some(val) = log_div_b_den.pop_front() { + circuit_inputs = circuit_inputs.next(*val); + }; -fn run_IS_ON_CURVE_G1_G2_circuit(mut input: Array, curve_index: usize) -> Array { + let outputs = match circuit_inputs.done().eval(modulus) { + Result::Ok(outputs) => { outputs }, + Result::Err(_) => { panic!("Expected success") } + }; + let A0_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: outputs.get_output(t25), + a_den: outputs.get_output(t37), + b_num: outputs.get_output(t49), + b_den: outputs.get_output(t67) + }; + let A2_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: outputs.get_output(t77), + a_den: outputs.get_output(t89), + b_num: outputs.get_output(t101), + b_den: outputs.get_output(t119) + }; + let xA0_power: u384 = outputs.get_output(t10); + let xA2_power: u384 = outputs.get_output(t11); + return (A0_evals, A2_evals, xA0_power, xA2_power); +} +fn run_IS_ON_CURVE_G1_G2_circuit( + p: G1Point, q: G2Point, a: u384, b: u384, b20: u384, b21: u384, curve_index: usize +) -> (u384, u384, u384) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -529,27 +1182,36 @@ fn run_IS_ON_CURVE_G1_G2_circuit(mut input: Array, curve_index: usize) -> let t27 = circuit_sub(t6, t24); let t28 = circuit_sub(t8, t25); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t26, t27, t28,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(q.x0); + circuit_inputs = circuit_inputs.next(q.x1); + circuit_inputs = circuit_inputs.next(q.y0); + circuit_inputs = circuit_inputs.next(q.y1); + circuit_inputs = circuit_inputs.next(a); + circuit_inputs = circuit_inputs.next(b); + circuit_inputs = circuit_inputs.next(b20); + circuit_inputs = circuit_inputs.next(b21); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t26), outputs.get_output(t27), outputs.get_output(t28)]; - return res; + let zero_check_0: u384 = outputs.get_output(t26); + let zero_check_1: u384 = outputs.get_output(t27); + let zero_check_2: u384 = outputs.get_output(t28); + return (zero_check_0, zero_check_1, zero_check_2); } - -fn run_IS_ON_CURVE_G1_circuit(mut input: Array, curve_index: usize) -> Array { +fn run_IS_ON_CURVE_G1_circuit(p: G1Point, a: u384, b: u384, curve_index: usize) -> (u384,) { // INPUT stack let (in0, in1) = (CE::> {}, CE::> {}); let (in2, in3) = (CE::> {}, CE::> {}); @@ -561,27 +1223,88 @@ fn run_IS_ON_CURVE_G1_circuit(mut input: Array, curve_index: usize) -> Arr let t5 = circuit_add(t2, t4); let t6 = circuit_sub(t0, t5); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t6,).new_inputs(); // Prefill constants: - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(a); + circuit_inputs = circuit_inputs.next(b); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t6)]; - return res; + let zero_check: u384 = outputs.get_output(t6); + return (zero_check,); } +fn run_IS_ON_CURVE_G2_circuit( + p: G2Point, a: u384, b20: u384, b21: u384, curve_index: usize +) -> (u384, u384) { + // INPUT stack + let (in0, in1) = (CE::> {}, CE::> {}); + let (in2, in3) = (CE::> {}, CE::> {}); + let (in4, in5) = (CE::> {}, CE::> {}); + let in6 = CE::> {}; + let t0 = circuit_add(in2, in3); + let t1 = circuit_sub(in2, in3); + let t2 = circuit_mul(t0, t1); + let t3 = circuit_mul(in2, in3); + let t4 = circuit_add(t3, t3); + let t5 = circuit_add(in0, in1); + let t6 = circuit_sub(in0, in1); + let t7 = circuit_mul(t5, t6); + let t8 = circuit_mul(in0, in1); + let t9 = circuit_add(t8, t8); + let t10 = circuit_mul(in0, t7); // Fp2 mul start + let t11 = circuit_mul(in1, t9); + let t12 = circuit_sub(t10, t11); // Fp2 mul real part end + let t13 = circuit_mul(in0, t9); + let t14 = circuit_mul(in1, t7); + let t15 = circuit_add(t13, t14); // Fp2 mul imag part end + let t16 = circuit_mul(in4, in0); + let t17 = circuit_mul(in4, in1); + let t18 = circuit_add(t16, in5); + let t19 = circuit_add(t17, in6); + let t20 = circuit_add(t12, t18); + let t21 = circuit_add(t15, t19); + let t22 = circuit_sub(t2, t20); + let t23 = circuit_sub(t4, t21); + + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) + .unwrap(); + + let mut circuit_inputs = (t22, t23,).new_inputs(); + // Prefill constants: + + circuit_inputs = circuit_inputs.next(p.x0); + circuit_inputs = circuit_inputs.next(p.x1); + circuit_inputs = circuit_inputs.next(p.y0); + circuit_inputs = circuit_inputs.next(p.y1); + circuit_inputs = circuit_inputs.next(a); + circuit_inputs = circuit_inputs.next(b20); + circuit_inputs = circuit_inputs.next(b21); -fn run_RHS_FINALIZE_ACC_circuit(mut input: Array, curve_index: usize) -> Array { + let outputs = match circuit_inputs.done().eval(modulus) { + Result::Ok(outputs) => { outputs }, + Result::Err(_) => { panic!("Expected success") } + }; + let zero_check_0: u384 = outputs.get_output(t22); + let zero_check_1: u384 = outputs.get_output(t23); + return (zero_check_0, zero_check_1); +} +fn run_RHS_FINALIZE_ACC_circuit( + acc: u384, m: u384, b: u384, xA: u384, Q_result: G1Point, curve_index: usize +) -> (u384,) { // CONSTANT stack let in0 = CE::> {}; // 0x0 @@ -598,30 +1321,32 @@ fn run_RHS_FINALIZE_ACC_circuit(mut input: Array, curve_index: usize) -> A let t6 = circuit_mul(t0, t5); let t7 = circuit_add(in1, t6); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t7,).new_inputs(); // Prefill constants: circuit_inputs = circuit_inputs.next([0x0, 0x0, 0x0, 0x0]); - - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(acc); + circuit_inputs = circuit_inputs.next(m); + circuit_inputs = circuit_inputs.next(b); + circuit_inputs = circuit_inputs.next(xA); + circuit_inputs = circuit_inputs.next(Q_result.x); + circuit_inputs = circuit_inputs.next(Q_result.y); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![outputs.get_output(t7)]; - return res; + let rhs: u384 = outputs.get_output(t7); + return (rhs,); } - fn run_SLOPE_INTERCEPT_SAME_POINT_circuit( - mut input: Array, curve_index: usize -) -> Array { + p: G1Point, a: u384, curve_index: usize +) -> (SlopeInterceptOutput,) { // CONSTANT stack let in0 = CE::> {}; // 0x3 let in1 = CE::> {}; // 0x0 @@ -662,36 +1387,35 @@ fn run_SLOPE_INTERCEPT_SAME_POINT_circuit( let t30 = circuit_add(t18, t18); let t31 = circuit_add(t29, t30); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) + let modulus = get_p(curve_index); + let modulus = TryInto::< + _, CircuitModulus + >::try_into([modulus.limb0, modulus.limb1, modulus.limb2, modulus.limb3]) .unwrap(); let mut circuit_inputs = (t5, t7, t10, t14, t31, t29,).new_inputs(); // Prefill constants: circuit_inputs = circuit_inputs.next([0x3, 0x0, 0x0, 0x0]); circuit_inputs = circuit_inputs.next([0x0, 0x0, 0x0, 0x0]); - - let mut input = input; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; + circuit_inputs = circuit_inputs.next(p.x); + circuit_inputs = circuit_inputs.next(p.y); + circuit_inputs = circuit_inputs.next(a); let outputs = match circuit_inputs.done().eval(modulus) { Result::Ok(outputs) => { outputs }, Result::Err(_) => { panic!("Expected success") } }; - let res = array![ - outputs.get_output(t5), - outputs.get_output(t7), - outputs.get_output(t10), - outputs.get_output(t14), - outputs.get_output(t31), - outputs.get_output(t29) - ]; - return res; + let mb: SlopeInterceptOutput = SlopeInterceptOutput { + m_A0: outputs.get_output(t5), + b_A0: outputs.get_output(t7), + x_A2: outputs.get_output(t10), + y_A2: outputs.get_output(t14), + coeff0: outputs.get_output(t31), + coeff2: outputs.get_output(t29), + }; + return (mb,); } - #[cfg(test)] mod tests { use core::traits::TryInto; @@ -705,1674 +1429,3627 @@ mod tests { G1Point, G2Point, E12D, E12DMulQuotient, G1G2Pair, BNProcessedPair, BLSProcessedPair, MillerLoopResultScalingFactor }; + use garaga::ec_ops::{SlopeInterceptOutput, FunctionFeltEvaluations}; use super::{ - run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit, run_ADD_EC_POINT_circuit, - run_DOUBLE_EC_POINT_circuit, run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit, - run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit, run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit, - run_IS_ON_CURVE_G1_G2_circuit, run_IS_ON_CURVE_G1_circuit, run_RHS_FINALIZE_ACC_circuit, - run_SLOPE_INTERCEPT_SAME_POINT_circuit + run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit, run_ACC_FUNCTION_CHALLENGE_DUPL_circuit, + run_ADD_EC_POINT_circuit, run_DOUBLE_EC_POINT_circuit, + run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit, run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit, + run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit, run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit, + run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit, run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit, + run_IS_ON_CURVE_G1_G2_circuit, run_IS_ON_CURVE_G1_circuit, run_IS_ON_CURVE_G2_circuit, + run_RHS_FINALIZE_ACC_circuit, run_SLOPE_INTERCEPT_SAME_POINT_circuit }; #[test] fn test_run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 48236672974334179109977992541, - limb1: 52772261131906895400324717330, - limb2: 58680986727142590413291888698, - limb3: 125427789982295314476245312 - }, - u384 { - limb0: 27907682019264955577444723898, - limb1: 4355263602740404459285443583, - limb2: 34370910611551282479913645959, - limb3: 2405913213433732924241100710 - }, - u384 { - limb0: 40094056984486425297894868013, - limb1: 19140770129557362845433890742, - limb2: 75252737910947413936148373983, - limb3: 2662291159799633884827814773 - }, - u384 { - limb0: 37916324419527928981375003573, - limb1: 8304321158085738349121383472, - limb2: 29689845389109744227457670868, - limb3: 5450104296033158396567160121 - }, - u384 { - limb0: 53957612108257091122007993452, - limb1: 22997572988440093112322792644, - limb2: 48724865905504296440658757309, - limb3: 1736900013437018037278270961 - }, - u384 { - limb0: 912990825318660284105510326, - limb1: 21182635136874798837860311805, - limb2: 57155051022259716099317127520, - limb3: 6185271417459784204086313826 - }, - u384 { limb0: 53449051946651914701307420860, limb1: 14501757, limb2: 0, limb3: 0 }, - u384 { limb0: 60202447271442483542105352682, limb1: 483656830, limb2: 0, limb3: 0 }, - u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }, - u384 { - limb0: 54880396502181392957329877674, - limb1: 31935979117156477062286671870, - limb2: 20826981314825584179608359615, - limb3: 8047903782086192180586325942 - } - ]; - let got = run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit(input, 1); - let exp = array![ - u384 { - limb0: 47191975890257107940052057228, - limb1: 53268955230954544998016981221, - limb2: 14052689568156691726722692993, - limb3: 3283879197162547654486347240 + let acc: u384 = u384 { + limb0: 19810622137112247197907222309, + limb1: 13949829356326980055993606151, + limb2: 55107524867879450997190834961, + limb3: 3963825035423832093295592605 + }; + + let m: u384 = u384 { + limb0: 31053108138040436674729129554, + limb1: 36840050990872229935393398650, + limb2: 49253601792028308041844962126, + limb3: 7164544154162499002674255779 + }; + + let b: u384 = u384 { + limb0: 41997912830939420264087550837, + limb1: 13433964319470697008461909961, + limb2: 5290431739583807388282457006, + limb3: 3634618912426067682339811562 + }; + + let xA: u384 = u384 { + limb0: 3203300834232228364118543905, + limb1: 5983187896426808170558818998, + limb2: 39825200540504584272892685436, + limb3: 111895808215459903523237277 + }; + + let p: G1Point = G1Point { + x: u384 { + limb0: 73928849850957586304434882373, + limb1: 62403613622583151174416730636, + limb2: 14789160887090903791443394793, + limb3: 1676137539699393088890560393 + }, + y: u384 { + limb0: 24223059977053185847889130548, + limb1: 78823362552325137370061488399, + limb2: 67428306151240320612652520138, + limb3: 3263212216173856919914429859 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let ep: u384 = u384 { + limb0: 71963122480311421720207286875, limb1: 105329, limb2: 0, limb3: 0 + }; + + let en: u384 = u384 { + limb0: 46466281465763485144644681735, limb1: 54592673, limb2: 0, limb3: 0 + }; + + let sp: u384 = u384 { + limb0: 54880396502181392957329877674, + limb1: 31935979117156477062286671870, + limb2: 20826981314825584179608359615, + limb3: 8047903782086192180586325942 + }; + + let sn: u384 = u384 { + limb0: 54880396502181392957329877674, + limb1: 31935979117156477062286671870, + limb2: 20826981314825584179608359615, + limb3: 8047903782086192180586325942 + }; + + let (res_acc_result) = run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit( + acc, m, b, xA, p, ep, en, sp, sn, 1 + ); + let res_acc: u384 = u384 { + limb0: 31832098235052790436765483859, + limb1: 76105358684692375989006522080, + limb2: 75613970160502882880229543158, + limb3: 7442866907202158780424227665 + }; + assert_eq!(res_acc_result, res_acc); } #[test] fn test_run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit_BN254() { - let input = array![ - u384 { - limb0: 45742550057374806329167237825, - limb1: 5510726952699698538507522860, - limb2: 3049538818873697689, - limb3: 0 - }, - u384 { - limb0: 15596568577007144946107732102, - limb1: 19297690964877084931055598137, - limb2: 1819563013969841841, - limb3: 0 - }, - u384 { - limb0: 43822460752391213489611866548, - limb1: 75118984786188757236103963672, - limb2: 3309626825146705442, - limb3: 0 - }, - u384 { - limb0: 7862869637678795077519372023, - limb1: 4699109503247496940657468379, - limb2: 767913315398900925, - limb3: 0 - }, - u384 { - limb0: 65917823739508736469247779160, - limb1: 3098786748851022159658983169, - limb2: 2488262035068768042, - limb3: 0 - }, - u384 { - limb0: 50853918540922815225247809382, - limb1: 28712599458085412945819279336, - limb2: 2179096613753899535, + let acc: u384 = u384 { + limb0: 44962833349231405535205115340, + limb1: 63647552159553458055189468718, + limb2: 657139397831997394, + limb3: 0 + }; + + let m: u384 = u384 { + limb0: 23834546630586236441457169873, + limb1: 63142044068385616067126408705, + limb2: 2771321714894224673, + limb3: 0 + }; + + let b: u384 = u384 { + limb0: 67662059274113917144334674787, + limb1: 7007062363991965631562297667, + limb2: 952905271153146248, + limb3: 0 + }; + + let xA: u384 = u384 { + limb0: 79151202497022096574680781888, + limb1: 27855742316335792713888636153, + limb2: 2832216618801458470, + limb3: 0 + }; + + let p: G1Point = G1Point { + x: u384 { + limb0: 64312132840204938797507353927, + limb1: 75030634435816891896646251238, + limb2: 1357389798614860830, limb3: 0 }, - u384 { limb0: 29223359368920413333441117546, limb1: 1266803654, limb2: 0, limb3: 0 }, - u384 { limb0: 60619417850417312561337014615, limb1: 130695199, limb2: 0, limb3: 0 }, - u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit(input, 0); - let exp = array![ - u384 { - limb0: 1340259879001784236130471393, - limb1: 13660712802589127909524135549, - limb2: 3365427384532902420, + y: u384 { + limb0: 71456350299612486562277415900, + limb1: 38647649612082196610222287445, + limb2: 3317576273299603468, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let ep: u384 = u384 { + limb0: 61230396717721534908260092755, limb1: 201317335, limb2: 0, limb3: 0 + }; + + let en: u384 = u384 { + limb0: 7735439647149380971218439287, limb1: 69198069, limb2: 0, limb3: 0 + }; + + let sp: u384 = u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }; + + let sn: u384 = u384 { + limb0: 32324006162389411176778628422, + limb1: 57042285082623239461879769745, + limb2: 3486998266802970665, + limb3: 0 + }; + + let (res_acc_result) = run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit( + acc, m, b, xA, p, ep, en, sp, sn, 0 + ); + let res_acc: u384 = u384 { + limb0: 26506561827560973798740398467, + limb1: 65406299512716581578605220062, + limb2: 2159062081397335518, + limb3: 0 + }; + assert_eq!(res_acc_result, res_acc); } #[test] - fn test_run_ADD_EC_POINT_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 33309241899903041961513358397, - limb1: 32760540889815297279239601937, - limb2: 38086476236853588376511117836, - limb3: 270965764379814188804131387 - }, - u384 { - limb0: 72581860487504126768318944525, - limb1: 31621145103658231914301769097, - limb2: 55536431980683803821116358010, - limb3: 6240987171472239626341717516 - }, - u384 { - limb0: 72082562993444989327518483877, - limb1: 13024464066649067809181363132, - limb2: 56793349399505384299966686653, - limb3: 184238452370141420282339148 - }, - u384 { - limb0: 42199985773271920620978677540, - limb1: 13916040143665985832289290704, - limb2: 35162392551902207456764900673, - limb3: 7418744371791558175413717229 + fn test_run_ACC_FUNCTION_CHALLENGE_DUPL_circuit_BLS12_381() { + let f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 12108246340442429455971122644, + limb1: 36573992723376078553845399626, + limb2: 23772335124274775229954098498, + limb3: 2863569299286716314494810078 + }, + a_den: u384 { + limb0: 33875646533936559234872809775, + limb1: 78504313903278613976349702955, + limb2: 10928763983555625777832409826, + limb3: 1382242378138602446805086908 + }, + b_num: u384 { + limb0: 77820720629424806009019504358, + limb1: 25129522554439892503182453198, + limb2: 73755848318658190723354415348, + limb3: 1434823775076896096245150309 + }, + b_den: u384 { + limb0: 25786100892102041398555537288, + limb1: 9688927942274723458760705785, + limb2: 22938303269890629181013757689, + limb3: 478926814095195537286572739 } - ]; - let got = run_ADD_EC_POINT_circuit(input, 1); - let exp = array![ - u384 { - limb0: 26606800313786008572849856966, - limb1: 55900062338705847244460856213, - limb2: 8207948494874813321608342817, - limb3: 3591115672623043846304312833 - }, - u384 { - limb0: 39277942834501501310368560175, - limb1: 8237852828377446336318041496, - limb2: 56007541505134428411022168356, - limb3: 1369959118870367205394143246 + }; + + let f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 34694988415059553205942033992, + limb1: 77263929789656935575577621941, + limb2: 50605482325959137133224655107, + limb3: 163430648919606487753511787 + }, + a_den: u384 { + limb0: 28212222609585886906853123633, + limb1: 23532623940105012734361898218, + limb2: 67365120472097392426905098257, + limb3: 3357851176268082037335105674 + }, + b_num: u384 { + limb0: 52293061812384466408305828874, + limb1: 78921144064263136073971338402, + limb2: 51090796273196843346160009363, + limb3: 3711054840487085193997117763 + }, + b_den: u384 { + limb0: 36880896032498523141231777761, + limb1: 548870523643093760961939326, + limb2: 41706344732079418021235659440, + limb3: 1077859243540896794547046208 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); - } + }; + let xA0: u384 = u384 { + limb0: 7883094338375970564381775266, + limb1: 67341875155230732209969635344, + limb2: 44938239000025171879243587797, + limb3: 5670333930418086673658116755 + }; - #[test] - fn test_run_ADD_EC_POINT_circuit_BN254() { - let input = array![ - u384 { - limb0: 49613233139976166820933933033, - limb1: 43972812792898214110431846422, - limb2: 3124149996396808164, + let xA2: u384 = u384 { + limb0: 68894933265880722394019213294, + limb1: 2502439027959160600217219698, + limb2: 73545631181998657745079280097, + limb3: 1757419049930726713472737204 + }; + + let xA0_power: u384 = u384 { + limb0: 14121208228699269516919110448, + limb1: 874973420913452197171104072, + limb2: 3590101988466229350967840378, + limb3: 4661176354771332880652175936 + }; + + let xA2_power: u384 = u384 { + limb0: 30773822776250261440661563403, + limb1: 51824538137531976673887283560, + limb2: 64452858638021103047684688956, + limb3: 6091289221105689584377452926 + }; + + let next_a_num_coeff: u384 = u384 { + limb0: 51724032430519362254783717615, + limb1: 60231235870227440279854038059, + limb2: 53231759367535954283700670702, + limb3: 6496371611460324880129521596 + }; + + let next_a_den_coeff: u384 = u384 { + limb0: 38445971634047730524652604279, + limb1: 21179994813098858427337462173, + limb2: 60461802833533768996458336992, + limb3: 462388318467056943993442765 + }; + + let next_b_num_coeff: u384 = u384 { + limb0: 73651298421213632996275590989, + limb1: 25937099489720806902956942366, + limb2: 18651622255431763454450187574, + limb3: 228596103238405175955455070 + }; + + let next_b_den_coeff: u384 = u384 { + limb0: 75154308597034933191701533796, + limb1: 44913914927744970354560248654, + limb2: 69559631700243442183360436480, + limb3: 1546726612799563332665020921 + }; + + let ( + next_f_a0_accs_result, + next_f_a1_accs_result, + next_xA0_power_result, + next_xA2_power_result + ) = + run_ACC_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs, + f_a1_accs, + xA0, + xA2, + xA0_power, + xA2_power, + next_a_num_coeff, + next_a_den_coeff, + next_b_num_coeff, + next_b_den_coeff, + 1 + ); + let next_f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 31448122092719716995848518667, + limb1: 57953657845439179933416208913, + limb2: 44627945821521075014253432738, + limb3: 4558522551144338373287929047 + }, + a_den: u384 { + limb0: 75196631134266894151430674545, + limb1: 33729945480267778777440997929, + limb2: 21583091731750224199490995220, + limb3: 2088831330558073102514207902 + }, + b_num: u384 { + limb0: 22853032758296755654635993989, + limb1: 62207943013951400652811630448, + limb2: 56594823313767368622836281977, + limb3: 4959579538431375549238473807 + }, + b_den: u384 { + limb0: 77012490448400821428584662246, + limb1: 65492667021862932169082189867, + limb2: 19875655886458886773940523549, + limb3: 2796876503428529267696099010 + } + }; + + let next_f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 66421375513170572727916247757, + limb1: 50745224475195360655044598375, + limb2: 73610463246752593424311395453, + limb3: 7335320505099146000939656489 + }, + a_den: u384 { + limb0: 27040144243902402208743709614, + limb1: 70900162238629659201824938667, + limb2: 58038864580702886867700031326, + limb3: 3087066545264049473255486244 + }, + b_num: u384 { + limb0: 42915569038074432139233079429, + limb1: 67285627742477967014734970318, + limb2: 48646048481105623761379108744, + limb3: 6105608072173562368059704405 + }, + b_den: u384 { + limb0: 73456520697575806417271113713, + limb1: 28729232678221943574580394470, + limb2: 34080658787962467249308509015, + limb3: 4714836782139058417951276971 + } + }; + + let next_xA0_power: u384 = u384 { + limb0: 15580082960333239011179411029, + limb1: 14431143603339515511671270899, + limb2: 2077071374430543683749228294, + limb3: 5045791552220884191929556457 + }; + + let next_xA2_power: u384 = u384 { + limb0: 78888903959244946111572815485, + limb1: 63508566222265648559989018722, + limb2: 61809550073642674886389507273, + limb3: 1773538514881343474585695695 + }; + assert_eq!(next_f_a0_accs_result, next_f_a0_accs); + assert_eq!(next_f_a1_accs_result, next_f_a1_accs); + assert_eq!(next_xA0_power_result, next_xA0_power); + assert_eq!(next_xA2_power_result, next_xA2_power); + } + + + #[test] + fn test_run_ACC_FUNCTION_CHALLENGE_DUPL_circuit_BN254() { + let f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 26160804169303701108574467383, + limb1: 26200398398246981547555445397, + limb2: 2988395391184350717, limb3: 0 }, - u384 { - limb0: 63824609037301126063922625889, - limb1: 20640785082980109702919037119, - limb2: 2767657580781827941, + a_den: u384 { + limb0: 34485664336970624705514895001, + limb1: 73938261058057061540403910557, + limb2: 680227002010418286, limb3: 0 }, - u384 { - limb0: 16776647801889250781294719899, - limb1: 53819387450153218721863223941, - limb2: 3238971312040363041, + b_num: u384 { + limb0: 10238103933028082051602938081, + limb1: 14801756928247077350447529830, + limb2: 1610249538293080548, limb3: 0 }, - u384 { - limb0: 73131808072361950503339604242, - limb1: 72831540730642989035268380153, - limb2: 1664095061258156717, + b_den: u384 { + limb0: 30809862244687846771967265197, + limb1: 38976969894147591396940506124, + limb2: 3365530714051750039, limb3: 0 } - ]; - let got = run_ADD_EC_POINT_circuit(input, 0); - let exp = array![ - u384 { - limb0: 64557636454391543536058816495, - limb1: 2087384318367081968443430132, - limb2: 109001327450590800, + }; + + let f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 15544142913195453928731074524, + limb1: 16183834845650327124827185620, + limb2: 3274283301470656708, limb3: 0 }, - u384 { - limb0: 8085146166888010828227289768, - limb1: 37697351098583322000520696350, - limb2: 2463462585271942076, + a_den: u384 { + limb0: 4515251077250220512798260103, + limb1: 53676494393428771485733874429, + limb2: 1074818787794107075, + limb3: 0 + }, + b_num: u384 { + limb0: 48527784689210241541249700331, + limb1: 68836875509116639126726990962, + limb2: 3465645697873360170, + limb3: 0 + }, + b_den: u384 { + limb0: 69519341455143905783924654782, + limb1: 32597027569167625847189348169, + limb2: 248754431759402728, + limb3: 0 + } + }; + + let xA0: u384 = u384 { + limb0: 40891579853875313629521435071, + limb1: 51380432001370256856125453412, + limb2: 2523429827510821026, + limb3: 0 + }; + + let xA2: u384 = u384 { + limb0: 74005152646713663672151227870, + limb1: 36017309965444930923992455369, + limb2: 1174837212995248629, + limb3: 0 + }; + + let xA0_power: u384 = u384 { + limb0: 17067298552900150679423746016, + limb1: 3346210529167654900940823776, + limb2: 242359391179174861, + limb3: 0 + }; + + let xA2_power: u384 = u384 { + limb0: 306973362941213357609388067, + limb1: 564901591820726767813982157, + limb2: 293718971296888446, + limb3: 0 + }; + + let next_a_num_coeff: u384 = u384 { + limb0: 53915081349218031573804503368, + limb1: 48221263659303828121639184235, + limb2: 2572253192268151092, + limb3: 0 + }; + + let next_a_den_coeff: u384 = u384 { + limb0: 35946147954191190128290977580, + limb1: 48195982237333787309495976064, + limb2: 2796316601135325512, + limb3: 0 + }; + + let next_b_num_coeff: u384 = u384 { + limb0: 2284078124869378290657040945, + limb1: 15063791196291306759315859498, + limb2: 369469589649843398, + limb3: 0 + }; + + let next_b_den_coeff: u384 = u384 { + limb0: 41556328054675005026691696365, + limb1: 66337016738192611695858475963, + limb2: 1158810910657968373, + limb3: 0 + }; + + let ( + next_f_a0_accs_result, + next_f_a1_accs_result, + next_xA0_power_result, + next_xA2_power_result + ) = + run_ACC_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs, + f_a1_accs, + xA0, + xA2, + xA0_power, + xA2_power, + next_a_num_coeff, + next_a_den_coeff, + next_b_num_coeff, + next_b_den_coeff, + 0 + ); + let next_f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 30808963433765998110074714258, + limb1: 6706184585891884013535342116, + limb2: 2042061178505947717, + limb3: 0 + }, + a_den: u384 { + limb0: 78019483234223392047399986470, + limb1: 44779490088590909616758779328, + limb2: 476764642837471437, + limb3: 0 + }, + b_num: u384 { + limb0: 23688121263111382210983361301, + limb1: 52280140532702717950590657618, + limb2: 1191886752708427522, + limb3: 0 + }, + b_den: u384 { + limb0: 19135515725509749782388544291, + limb1: 52396909026069950741400084648, + limb2: 2580854289756285308, + limb3: 0 + } + }; + + let next_f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 63411557572934585210177540957, + limb1: 14503239548061152056217755855, + limb2: 374065118833427589, + limb3: 0 + }, + a_den: u384 { + limb0: 24836411582707293744402409929, + limb1: 67686852375784657022872133023, + limb2: 1910386601568393159, + limb3: 0 + }, + b_num: u384 { + limb0: 51051616182486192110384745198, + limb1: 14482347880876559971871384720, + limb2: 976223590270110063, + limb3: 0 + }, + b_den: u384 { + limb0: 142446536857281040590132644, + limb1: 34932201872287348552210674411, + limb2: 1015785014968012746, + limb3: 0 + } + }; + + let next_xA0_power: u384 = u384 { + limb0: 44075197729202727530667257374, + limb1: 25092767447294075943880642846, + limb2: 370954766988097393, + limb3: 0 + }; + + let next_xA2_power: u384 = u384 { + limb0: 17829392197683674155933553512, + limb1: 44822392040537623475564856141, + limb2: 2770025443621462598, + limb3: 0 + }; + assert_eq!(next_f_a0_accs_result, next_f_a0_accs); + assert_eq!(next_f_a1_accs_result, next_f_a1_accs); + assert_eq!(next_xA0_power_result, next_xA0_power); + assert_eq!(next_xA2_power_result, next_xA2_power); + } + + + #[test] + fn test_run_ADD_EC_POINT_circuit_BLS12_381() { + let p: G1Point = G1Point { + x: u384 { + limb0: 12875407038990063061628700034, + limb1: 25033933193506348906088482406, + limb2: 1823331722497262066456451357, + limb3: 6604230986040125537844944638 + }, + y: u384 { + limb0: 26638281648743243479381974620, + limb1: 22326581668532872379125961844, + limb2: 69293571505496601526114705217, + limb3: 6704695418355896300620047860 + } + }; + + let q: G1Point = G1Point { + x: u384 { + limb0: 28765586392982865289008667021, + limb1: 75046504195749649273445159422, + limb2: 60751416629908160919025511613, + limb3: 2338144822313237663375753863 + }, + y: u384 { + limb0: 19346375897247670342864009388, + limb1: 54027869929152963906375829689, + limb2: 47046536620844573968083555972, + limb3: 6041093272305266754594556219 + } + }; + + let (r_result) = run_ADD_EC_POINT_circuit(p, q, 1); + let r: G1Point = G1Point { + x: u384 { + limb0: 31283346705253657118389816881, + limb1: 70171886285897530921320001411, + limb2: 58253503732716673534618492523, + limb3: 1464574464513963277821927457 + }, + y: u384 { + limb0: 45184039913936445247613811195, + limb1: 42722242019564988590184854508, + limb2: 38184525525705115168170238692, + limb3: 7120141904745954606121753411 + } + }; + assert_eq!(r_result, r); + } + + + #[test] + fn test_run_ADD_EC_POINT_circuit_BN254() { + let p: G1Point = G1Point { + x: u384 { + limb0: 38128859801821715256649374396, + limb1: 24786117657263552426232126063, + limb2: 572509101272353298, + limb3: 0 + }, + y: u384 { + limb0: 37756010677368974818184730130, + limb1: 73957050073687763043103620926, + limb2: 3020155982118805993, + limb3: 0 + } + }; + + let q: G1Point = G1Point { + x: u384 { + limb0: 63314342017339320422970882655, + limb1: 13997162768002931416456204394, + limb2: 2538442321033240546, + limb3: 0 + }, + y: u384 { + limb0: 44010778514703578787352720968, + limb1: 72952826293633259921434670571, + limb2: 2986924236004579438, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let (r_result) = run_ADD_EC_POINT_circuit(p, q, 0); + let r: G1Point = G1Point { + x: u384 { + limb0: 75305423221040578200953077116, + limb1: 832313931183756826830246841, + limb2: 2231136249080500033, + limb3: 0 + }, + y: u384 { + limb0: 17259010355531170206393473013, + limb1: 50755733036493923234206796873, + limb2: 1683017369454101010, + limb3: 0 + } + }; + assert_eq!(r_result, r); } #[test] fn test_run_DOUBLE_EC_POINT_circuit_BLS12_381() { - let input = array![ + let p: G1Point = G1Point { + x: u384 { + limb0: 53201722009518044555307082091, + limb1: 26182850778364290173584345611, + limb2: 9082985586092171798576086462, + limb3: 2084374856198844811858663259 + }, + y: u384 { + limb0: 51886784475864541116635883746, + limb1: 62035932232041883870749760628, + limb2: 12492049999768513336754604933, + limb3: 4394375882336316738076748308 + } + }; + + let A_weirstrass: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let (r_result) = run_DOUBLE_EC_POINT_circuit(p, A_weirstrass, 1); + let r: G1Point = G1Point { + x: u384 { + limb0: 52801209862070083900761052907, + limb1: 24378733725315305851389977888, + limb2: 19067271398967530173083992422, + limb3: 3730713727070623480657215589 + }, + y: u384 { + limb0: 77613487060203594703641215278, + limb1: 67102371626988986346855039891, + limb2: 24336370853912611161482144046, + limb3: 190034365233135648884944196 + } + }; + assert_eq!(r_result, r); + } + + + #[test] + fn test_run_DOUBLE_EC_POINT_circuit_BN254() { + let p: G1Point = G1Point { + x: u384 { + limb0: 60560778576565062309466296994, + limb1: 44170652868564955715381828788, + limb2: 1045034824854055803, + limb3: 0 + }, + y: u384 { + limb0: 41767294739936930185340814487, + limb1: 53310733056225888426673919700, + limb2: 936318755319797418, + limb3: 0 + } + }; + + let A_weirstrass: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let (r_result) = run_DOUBLE_EC_POINT_circuit(p, A_weirstrass, 0); + let r: G1Point = G1Point { + x: u384 { + limb0: 20967046187375045694021543651, + limb1: 38022320345279303713894724950, + limb2: 2926745554410149490, + limb3: 0 + }, + y: u384 { + limb0: 76298873595898171174636962047, + limb1: 37441345285275686030650352179, + limb2: 259212382702286577, + limb3: 0 + } + }; + assert_eq!(r_result, r); + } + + + #[test] + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit_BLS12_381() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 7583328894958836472689261456, + limb1: 23995865134773481226042240427, + limb2: 63478017613684307128330244549, + limb3: 465853556340900511023207144 + }, + y: u384 { + limb0: 21356761267284286476218331659, + limb1: 73182300382538380670716259875, + limb2: 24004053148595986095787300223, + limb3: 1022001039698887202091521156 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 79029124468210850465870597326, + limb1: 75140792944319733023209253791, + limb2: 42093390057118540119052572179, + limb3: 606518660342947232036779274 + }, + y: u384 { + limb0: 44414617103315706325286783695, + limb1: 66318307486276839929230289785, + limb2: 55167842879295115445151139563, + limb3: 1634264047067373269877374575 + } + }; + + let coeff0: u384 = u384 { + limb0: 58730436280971129538423813519, + limb1: 19897324256127475360933650989, + limb2: 24116796458902841012958318566, + limb3: 4063790723355910080844289468 + }; + + let coeff2: u384 = u384 { + limb0: 2993190523304409550412932749, + limb1: 13553940758264748173523256973, + limb2: 54355150871207218923970903132, + limb3: 7918207502505106887190889135 + }; + + let log_div_a_num: Span = array![ + u384 { + limb0: 77045150093437199561876682613, + limb1: 63247810549753043747824592935, + limb2: 45322351653447410223048358586, + limb3: 4891241564897686133014575236 + }, u384 { - limb0: 59993145362510832463963941446, - limb1: 24093260381820070467875359559, - limb2: 7664095297330292033859842374, - limb3: 1594063512469875549599004872 + limb0: 49616765702940610815673434313, + limb1: 30983336537290843698603394424, + limb2: 68000082468172739504683525935, + limb3: 6735570505808929410455319391 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 10755738364987529307384484837, + limb1: 47424080954943794970182125181, + limb2: 44668170795920675695082189575, + limb3: 411775674055255699216064733 }, u384 { - limb0: 33576405834226714838700397072, - limb1: 19109806014962667324703690329, - limb2: 48993055774894028472456981736, - limb3: 4139717787125758448256353972 + limb0: 74075366540320784004279194557, + limb1: 45901111491814875426965294020, + limb2: 11056244753771885820499269497, + limb3: 1848821835838869900975009596 + }, + u384 { + limb0: 1483797698072156512478727902, + limb1: 27276796206714531879437399722, + limb2: 60549614635777558349423897566, + limb3: 5825147675425241565654114497 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 29122809252277220054000063647, + limb1: 29103957579290275626226096329, + limb2: 78143372271151155558685637529, + limb3: 6787205099077257704993852800 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_DOUBLE_EC_POINT_circuit(input, 1); - let exp = array![ u384 { - limb0: 6525088909606839605246043827, - limb1: 16542261013743505285701806308, - limb2: 65143067225854220899819657322, - limb3: 4828985442979386055503344831 + limb0: 5127215115757810441247982977, + limb1: 28593107642171724789447702460, + limb2: 45568633039957397606573258935, + limb3: 1488628575882954060993118356 }, u384 { - limb0: 68378118528657894197845811815, - limb1: 22043262988598989471653792412, - limb2: 25239935902906465557239002507, - limb3: 3851126098992526465940689310 + limb0: 41544852851071536982002373132, + limb1: 10690239667602887455029393258, + limb2: 40056190273901790560895741554, + limb3: 1104740673718121061161636698 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 46168775291129622906430448332, + limb1: 49174190409785741241747568928, + limb2: 13111914892901844165005383698, + limb3: 4634489426994256239540617855 + }, + u384 { + limb0: 14651105791937006148379740973, + limb1: 28552790313455794321272600344, + limb2: 11861619440276751017934021007, + limb3: 7834141835042731797038955420 + }, + u384 { + limb0: 35464068568113085230973736790, + limb1: 29644601032237693127650457879, + limb2: 21239007568751521325653049117, + limb3: 3484280708079790606737295977 + }, + u384 { + limb0: 32802292381907600413177143846, + limb1: 15823925868741025030511585232, + limb2: 36423797732402664118035652490, + limb3: 4227913601559714836560741706 + }, + u384 { + limb0: 46476941897652146523272430059, + limb1: 60637876526449722671128730265, + limb2: 10813098114750570157480288434, + limb3: 4052176282537828063744703996 + }, + u384 { + limb0: 44970782327975554560280922237, + limb1: 7504749009073105970898744732, + limb2: 78909737051083213042363736038, + limb3: 6188261761555933459261274855 + } + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 1 + ); + let res: u384 = u384 { + limb0: 77827560147760129965629779634, + limb1: 65612201965488062574129661709, + limb2: 10931349107081260327699080751, + limb3: 5965783541631010229032091089 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_DOUBLE_EC_POINT_circuit_BN254() { - let input = array![ + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit_BN254() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 40148766616263035635840333009, + limb1: 46474846459933975019459911928, + limb2: 2470655728952642587, + limb3: 0 + }, + y: u384 { + limb0: 21537482342478193065340640997, + limb1: 40177993449419617772957987144, + limb2: 1250679888354201219, + limb3: 0 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 30823735281157389256209543712, + limb1: 19847866653076010386205779801, + limb2: 2591716463645850631, + limb3: 0 + }, + y: u384 { + limb0: 76161780491498106238776533197, + limb1: 50778725087196949720068307515, + limb2: 1606868050735217786, + limb3: 0 + } + }; + + let coeff0: u384 = u384 { + limb0: 74898788220810224024822405784, + limb1: 35009367531731238551044390234, + limb2: 3284164467375196939, + limb3: 0 + }; + + let coeff2: u384 = u384 { + limb0: 28090742850908769527384262520, + limb1: 61051006903507127804053417947, + limb2: 826123398259764642, + limb3: 0 + }; + + let log_div_a_num: Span = array![ + u384 { + limb0: 14794237793914580203825001254, + limb1: 77746575381799877451713667420, + limb2: 1199297585036842103, + limb3: 0 + }, + u384 { + limb0: 7116618687170970882165043068, + limb1: 10317443627241611822001871482, + limb2: 689679177778202091, + limb3: 0 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 31001666614092081990723748281, + limb1: 41561029444172340142595266045, + limb2: 2406332089639105853, + limb3: 0 + }, + u384 { + limb0: 45928170697383674157136595572, + limb1: 39032180734333527280233756481, + limb2: 2956998425360848720, + limb3: 0 + }, + u384 { + limb0: 72647567559691066767355592945, + limb1: 28313574455853548884130432525, + limb2: 1495684346430252400, + limb3: 0 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 38540080312249748070424599174, + limb1: 26562863849074228394866673420, + limb2: 877967472997105922, + limb3: 0 + }, + u384 { + limb0: 57954547034597705093744137517, + limb1: 55882246706301200147329236607, + limb2: 1715824789860391444, + limb3: 0 + }, + u384 { + limb0: 55275162859819575949303201786, + limb1: 64738939897155674525545892679, + limb2: 2924760851437642345, + limb3: 0 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 42323523345775160595175624498, + limb1: 5862638532664225004255696984, + limb2: 573895368452184552, + limb3: 0 + }, + u384 { + limb0: 48039078213954386823895538352, + limb1: 9483252545001263778693678687, + limb2: 422116173579439317, + limb3: 0 + }, u384 { - limb0: 14851398790425281408725747707, - limb1: 54165005602420261392867141973, - limb2: 145287008867519146, + limb0: 77684532510750867207844101566, + limb1: 47972982863049221836870333236, + limb2: 897392360999745655, limb3: 0 }, u384 { - limb0: 64053397048797885251156030001, - limb1: 34360415572814481112505250496, - limb2: 630702696590238794, + limb0: 14654986812089486663978722625, + limb1: 37968801859256819202234140283, + limb2: 3353411595474065306, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_DOUBLE_EC_POINT_circuit(input, 0); - let exp = array![ u384 { - limb0: 64738051925517883470757500090, - limb1: 74489092163442293378499844594, - limb2: 1888842806392784043, + limb0: 74234344814779244185063897755, + limb1: 43118771910670269873180488372, + limb2: 2862012233304857365, limb3: 0 }, u384 { - limb0: 61882520224793610057118644897, - limb1: 51600441633547976350293086647, - limb2: 2850111636632650310, + limb0: 20592975280186094583652543261, + limb1: 5702184612159354371419393353, + limb2: 1388401297071074456, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 0 + ); + let res: u384 = u384 { + limb0: 34274908065456138543612886707, + limb1: 40709557787971075893842667357, + limb2: 3454714656220187162, + limb3: 0 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit_BLS12_381() { - let input = array![ + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit_BLS12_381() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 65767048862188894000880605195, + limb1: 37534452217635903559608298170, + limb2: 58180994003131892199361724239, + limb3: 5078765531492571287458606084 + }, + y: u384 { + limb0: 64246926876373679213975432056, + limb1: 12690130362744280704764922450, + limb2: 23556261097436500272783865001, + limb3: 452536755869646735778726332 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 54862404535087871815357405032, + limb1: 67503468372694447312203147827, + limb2: 28111716523619362390979032720, + limb3: 7484365428015675707046981596 + }, + y: u384 { + limb0: 78022090284692562586867737247, + limb1: 73764645971838121016101973484, + limb2: 26993018956584650067795467161, + limb3: 4300951883010802285627173656 + } + }; + + let coeff0: u384 = u384 { + limb0: 53532230052431160482256072373, + limb1: 73349623192491526085785572767, + limb2: 37624412445827650158888211983, + limb3: 2344766373122814366232550839 + }; + + let coeff2: u384 = u384 { + limb0: 38083203350872957721690776707, + limb1: 28863323375216826176563820008, + limb2: 61148298492018667540447579125, + limb3: 1957739006883122080707665727 + }; + + let log_div_a_num: Span = array![ + u384 { + limb0: 24558429725501122402824819678, + limb1: 68342697813896506535660598425, + limb2: 9654576325383816539580605054, + limb3: 4449419614608327995090571407 + }, u384 { - limb0: 43841242362053459684090785305, - limb1: 64240255443488604587374821128, - limb2: 62374824215224853082901276642, - limb3: 3430396176849037064580626027 + limb0: 68758036188588496868104646286, + limb1: 56891258595389737155916225187, + limb2: 1408531604035569123486374745, + limb3: 4532148950439698131066013996 }, u384 { - limb0: 14795524108603081055843032705, - limb1: 61594660931365678498565157644, - limb2: 31476263509966268363435484884, - limb3: 5801018881769889249070624680 + limb0: 55118746527527852686024124923, + limb1: 16401455574156521911685578456, + limb2: 68356218296824579607395147997, + limb3: 4274633836826767384269480656 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 37207096201433968482887965473, + limb1: 63363061334648502844886171306, + limb2: 58983605035591813724277703872, + limb3: 6510798269055198746020224502 + }, + u384 { + limb0: 27331451642951025804547581919, + limb1: 11290408363496075061178534039, + limb2: 39513673746779885991039965221, + limb3: 7026518597061253491006183919 + }, + u384 { + limb0: 19102404456994819588605793834, + limb1: 36598782241760553575219661742, + limb2: 75008771170587373912728886483, + limb3: 1810475945971433314583134829 + }, + u384 { + limb0: 74610124760961754812477629140, + limb1: 58377991344230990131790349664, + limb2: 58791772470354736399436051453, + limb3: 5215668431180415388089886330 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 68446193742335393103502843782, + limb1: 24489951206429553575321595129, + limb2: 11937728545212543206473989888, + limb3: 3043633768618361479769065920 }, u384 { - limb0: 72181972195416164195345326146, - limb1: 63673113199459344708055087488, - limb2: 35543558094683217749894530541, - limb3: 5998994623843089936411013246 + limb0: 27500370927060974449436176169, + limb1: 45709591675001960052223002937, + limb2: 12611881827017711348035166380, + limb3: 1252741210600307690466672089 }, u384 { - limb0: 67881050017810763600865571352, - limb1: 8898457633503693906605515203, - limb2: 59407007050452817875359089909, - limb3: 29726280058791523002213605 + limb0: 43948655267847633428523537973, + limb1: 64098478544670958175717141502, + limb2: 27054787921471140642372181164, + limb3: 6015500424179645355722665708 }, u384 { - limb0: 73817756250123608230764455319, - limb1: 65759471872075335618784711602, - limb2: 42230562009807371284121866825, - limb3: 5531882691531171699098511008 + limb0: 46950086666011485177431786799, + limb1: 19814746698209126702265054217, + limb2: 43218602751870738958780960164, + limb3: 7174346422794958966058494771 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 11904566295323965385403362114, + limb1: 9986855602182309707838076955, + limb2: 28921975690744242248405216063, + limb3: 3689819613064055325765335341 }, u384 { - limb0: 37792171835193238017808722513, - limb1: 79052609589392826466178763377, - limb2: 51112107438967302768310466512, - limb3: 3457290828953570698204716284 + limb0: 40909585418941611689912040087, + limb1: 72843418030114205336704153134, + limb2: 64002727902485385509362189132, + limb3: 5338714747924693295334618134 }, u384 { - limb0: 44913346415415193260941275379, - limb1: 12463380603984557499685059891, - limb2: 8152966891038729248051251604, - limb3: 6676165400853797752563222140 + limb0: 56511832214648574483122896254, + limb1: 48948480134880266575529786400, + limb2: 16736011681533189035513036360, + limb3: 5495837588287940286021134583 }, u384 { - limb0: 18096062505878242703387918579, - limb1: 203498347241549738566467938, - limb2: 68368239133153753602248282483, - limb3: 455378985045918642455531453 + limb0: 55035795486934388231748583316, + limb1: 32608796974892492723105506831, + limb2: 7171966635098953791864187580, + limb3: 7186019043680078440958258514 }, u384 { - limb0: 30342759941037994388194955379, - limb1: 14178745655674493063562262412, - limb2: 67936976597592666962873319852, - limb3: 7953670477608813919732602453 + limb0: 34483334433821763113694168530, + limb1: 16106282905813707710782261535, + limb2: 41380576554605698964309903892, + limb3: 7078346790967887486358951501 }, u384 { - limb0: 58681592574590638774032038256, - limb1: 17787935975239186632826170304, - limb2: 32979245100565703294504246764, - limb3: 3168484127393396634401731885 + limb0: 76150993900916235157900039913, + limb1: 64335514309225783328886852074, + limb2: 28756481183620185941632902755, + limb3: 6285267001457104347005350571 }, u384 { - limb0: 6170849151853539503012653401, - limb1: 9459916376982993164991213145, - limb2: 71459129173163831485366911303, - limb3: 2210317728927929159537912836 + limb0: 79021865442540334634863477409, + limb1: 18497443262091280994972764093, + limb2: 16799814604529470286869836524, + limb3: 5607079376244643758395550033 + } + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 1 + ); + let res: u384 = u384 { + limb0: 1796994533811096489092080494, + limb1: 15779093703550958270341160034, + limb2: 19422510478301347858927052822, + limb3: 646169933846028905286379664 + }; + assert_eq!(res_result, res); + } + + + #[test] + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit_BN254() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 3636555079963102501892527788, + limb1: 52006742040801998052484378944, + limb2: 3162220113988809833, + limb3: 0 }, + y: u384 { + limb0: 21062701446761812807006463558, + limb1: 17848105974468817471197934249, + limb2: 1375301049194764590, + limb3: 0 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 34783326805436326333945577803, + limb1: 41388841398860147980780662671, + limb2: 28618089295067099, + limb3: 0 + }, + y: u384 { + limb0: 67237513623925518976819596804, + limb1: 51223730934775618345943155728, + limb2: 2095740029227068279, + limb3: 0 + } + }; + + let coeff0: u384 = u384 { + limb0: 62884373561056291920603020388, + limb1: 26268149660478049885105057237, + limb2: 631865055005170855, + limb3: 0 + }; + + let coeff2: u384 = u384 { + limb0: 74927920881351490685071244293, + limb1: 54762055536472718786476825349, + limb2: 567132222870126647, + limb3: 0 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 77755617143852009941738526899, - limb1: 31764539320310237713412520421, - limb2: 36848556728080127032713095604, - limb3: 7660645068258413493714438620 + limb0: 66419072860110050339869820619, + limb1: 45141714820742065952512633064, + limb2: 3217559834104654130, + limb3: 0 }, u384 { - limb0: 25931451033492414976385080403, - limb1: 36187160353237884000276405383, - limb2: 15898807053542266727563936919, - limb3: 7769383187976185666158852563 + limb0: 76577893561800932074888244242, + limb1: 62483154821447055814624866535, + limb2: 729608530089971552, + limb3: 0 }, u384 { - limb0: 49336765146084121130048487433, - limb1: 29177642521004522530456337437, - limb2: 39088059805565237823362633348, - limb3: 7684002363095845199059810797 + limb0: 40295453289252839295368126301, + limb1: 51413807683524257252659823198, + limb2: 1792296000252955367, + limb3: 0 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 19880933925577897152525432424, + limb1: 54732617916798524637621653282, + limb2: 2111940998382683850, + limb3: 0 }, u384 { - limb0: 71340467633755259940219860030, - limb1: 63063521205150311407306886776, - limb2: 505307660245121265920156293, - limb3: 236795733043188210586458834 + limb0: 26614051192530018189186683291, + limb1: 43125433639120527991266879770, + limb2: 621828703510853011, + limb3: 0 }, u384 { - limb0: 27446513174394839845547916662, - limb1: 54941625103216522139181847952, - limb2: 75345211080808886447157286582, - limb3: 7516070292820032529547637467 + limb0: 75514686386904432448194031521, + limb1: 48339926940835590207610357019, + limb2: 3105525320639471085, + limb3: 0 }, u384 { - limb0: 67265183983479375960272605345, - limb1: 24363503251417312230150175803, - limb2: 41976227902008152972947384106, - limb3: 4157654687621112832935688511 + limb0: 75021609102054288987421711364, + limb1: 67642975409787310927882119548, + limb2: 610330270066730084, + limb3: 0 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 30741892565845760404528223343, + limb1: 65672443567475252421635917125, + limb2: 372269656135498629, + limb3: 0 }, u384 { - limb0: 4745376637116532048405043903, - limb1: 11279989295633601330432025693, - limb2: 7370329896385946009027402569, - limb3: 2292393283743136608077810742 + limb0: 15236331609649488866924815407, + limb1: 12682826686433224834405519535, + limb2: 1028857084617842001, + limb3: 0 }, u384 { - limb0: 41179567842552912655777309102, - limb1: 70954994507766005171299948346, - limb2: 77212185377988988310384255573, - limb3: 5751673737567079236967486935 + limb0: 3706268753334235950603414369, + limb1: 5061594938817017066124061895, + limb2: 3235172318550209024, + limb3: 0 }, u384 { - limb0: 10578056732552701320470445062, - limb1: 31243728407906463024764981526, - limb2: 44987393412080654169984735014, - limb3: 6560526836423357238680339743 + limb0: 41798649402294191906248074676, + limb1: 71942329400551128942659750399, + limb2: 2785354068451146667, + limb3: 0 } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit(input, 1); - let exp = array![ + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 64099216478858599863310237669, + limb1: 77182244161772445466351224287, + limb2: 1914483419438017757, + limb3: 0 + }, + u384 { + limb0: 78184053005800223115117981229, + limb1: 75230906188879501586958994545, + limb2: 1925310095113267403, + limb3: 0 + }, u384 { - limb0: 69150440884776464509805210617, - limb1: 54308803248596749988098758151, - limb2: 62245147033224538712863470546, - limb3: 4877088602094363064461316595 + limb0: 41859880883168051933292168851, + limb1: 15089790425756061617928280001, + limb2: 2805563635729988690, + limb3: 0 + }, + u384 { + limb0: 69217987206139527826383454812, + limb1: 54551758949173673132118713167, + limb2: 840346734038087871, + limb3: 0 + }, + u384 { + limb0: 67655947212642963726507798811, + limb1: 49726692784924059127858766612, + limb2: 100744595785321916, + limb3: 0 + }, + u384 { + limb0: 35888629229617088004824999264, + limb1: 9172988570062838870103379281, + limb2: 1182845696508826919, + limb3: 0 + }, + u384 { + limb0: 41267218447368985898299939181, + limb1: 51097464328089926730815951184, + limb2: 530848132391008118, + limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 0 + ); + let res: u384 = u384 { + limb0: 20283816950282402479515032885, + limb1: 1276425155692095747129076835, + limb2: 3446911725191841057, + limb3: 0 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit_BN254() { - let input = array![ + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit_BLS12_381() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 74030770910997380809928801067, + limb1: 72870080271422360238772842985, + limb2: 35332984386744009571551879383, + limb3: 213117707751331445367042061 + }, + y: u384 { + limb0: 53911856427670238980127554068, + limb1: 47598882184083941743928375155, + limb2: 64469875182187854453896945401, + limb3: 4710791057645923943273563152 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 9382021819409651063148689085, + limb1: 18016552063903564748945195561, + limb2: 32546583337437134217571882382, + limb3: 1876280894767790922122346829 + }, + y: u384 { + limb0: 17039220970301599246975031449, + limb1: 4712133905483429955536263540, + limb2: 252058361399094932752293537, + limb3: 5435335018421901824913512718 + } + }; + + let coeff0: u384 = u384 { + limb0: 17632551922464131811238072914, + limb1: 12593775649135027097051712668, + limb2: 73832140458294252783978741095, + limb3: 3572109152464814668621958321 + }; + + let coeff2: u384 = u384 { + limb0: 17530848419114014704737826365, + limb1: 10048650392297785556763940622, + limb2: 27415000093256223375397880278, + limb3: 4356312786196187608735053950 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 13268259472981868365421112389, - limb1: 46352131756625236806836889929, - limb2: 2843863423214240149, - limb3: 0 + limb0: 62505647863352096926662303463, + limb1: 7662952973292534722750046066, + limb2: 11819334322330838424606312378, + limb3: 2228144000998654854136880212 }, u384 { - limb0: 76737231855177948808203514245, - limb1: 54634224157169326523931280027, - limb2: 609293085769401994, + limb0: 10926904322282820847706390438, + limb1: 45182068785185827134676054734, + limb2: 37761923604613353371701557318, + limb3: 2328601210277656834509591410 + }, + u384 { + limb0: 19609363213726272674414457324, + limb1: 64623442223733833178221935997, + limb2: 13839342760447473857713462593, + limb3: 1010285289685609669771462635 + }, + u384 { + limb0: 15994045547115158217586200975, + limb1: 37712177793605455750901464997, + limb2: 37949689568867541480607656110, + limb3: 4483360040641239178141238925 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 47751076890492997424778896023, + limb1: 45158898588446714307151412146, + limb2: 34068755536928411790602903133, + limb3: 1655406669862454914709205631 + }, + u384 { + limb0: 47264448029119937476921761400, + limb1: 8708733859256235966098767032, + limb2: 48215692544544501482302062863, + limb3: 6756407073149860618835829093 + }, + u384 { + limb0: 21908364541332061992697578757, + limb1: 35340861620182570595707588062, + limb2: 77637270239381904164352190365, + limb3: 3916549285729575534585079457 + }, + u384 { + limb0: 45898171511413672372932753935, + limb1: 28548016344158474816179781599, + limb2: 33785855249417352047592175280, + limb3: 7445903263701933392069999204 + }, + u384 { + limb0: 35893455273938352309107615221, + limb1: 2080646700516431058346219020, + limb2: 30263546600258042597952466309, + limb3: 2708085524016270248720043216 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 3459226470770777809730037651, + limb1: 3521799239736851097521099371, + limb2: 51786206015678820515596664525, + limb3: 7575258638946376416989219168 + }, + u384 { + limb0: 49160664602046435964785293661, + limb1: 69036182821263326465350473092, + limb2: 49929859459179433735872323690, + limb3: 973011804790503889155143481 + }, + u384 { + limb0: 59767581910396035802124702410, + limb1: 16816425500136253702812516731, + limb2: 32631880372008947478762200427, + limb3: 997437003020617104963749911 + }, + u384 { + limb0: 16170890331099353878348031414, + limb1: 41987460868189397116651864065, + limb2: 5954707858792147804249629551, + limb3: 1288156010025796053068522766 + }, + u384 { + limb0: 74016182581385052958198151027, + limb1: 5257464847259323752304478529, + limb2: 69226420135741979532223718098, + limb3: 1172952122986783618438994043 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 69116238475054280746352657554, + limb1: 33304670868753677946402592534, + limb2: 64351075069538312587227091978, + limb3: 365776845916897694131175296 + }, + u384 { + limb0: 55248761476452341723828038140, + limb1: 12293956483460203526708774625, + limb2: 58754719300948559412338253396, + limb3: 1375008475364259274254964916 + }, + u384 { + limb0: 24300686353668847428332719991, + limb1: 38014631825699413785961682855, + limb2: 47251032500406031276512661332, + limb3: 4167966723124564055768198087 + }, + u384 { + limb0: 50704064528320123503506606737, + limb1: 18328329858539334651902821560, + limb2: 23679380924341780085679280360, + limb3: 4967409425445932931684662208 + }, + u384 { + limb0: 73263438150749671104119509678, + limb1: 57283302427702266423321493523, + limb2: 68349986252946238723149811727, + limb3: 2697427346029370939638037315 + }, + u384 { + limb0: 30153976504965215982943491419, + limb1: 25350399447970833472518361392, + limb2: 65788099606275616882529504563, + limb3: 945438427330809830625164736 + }, + u384 { + limb0: 15457273367721198620101569167, + limb1: 32372676642390061355626449664, + limb2: 12981191522992192054561334015, + limb3: 4143290004629368981031116766 + }, + u384 { + limb0: 68694010858285961426496213143, + limb1: 21754144885013154319689718197, + limb2: 28882572635855842335400376167, + limb3: 655357640203230020680299384 + } + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 1 + ); + let res: u384 = u384 { + limb0: 40253013248657078199561468996, + limb1: 576757340187103649310802047, + limb2: 33128776915581077661975437225, + limb3: 2264493704705425408907739265 + }; + assert_eq!(res_result, res); + } + + + #[test] + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit_BN254() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 50856419053858407715966739414, + limb1: 34425437744508680919790030278, + limb2: 3281703676259823627, + limb3: 0 + }, + y: u384 { + limb0: 34165780966617237114827658811, + limb1: 14157494819384016169227211930, + limb2: 2638569629760286652, + limb3: 0 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 73235677144903878850189826972, + limb1: 65834203744362665442113831233, + limb2: 2432335405087577852, limb3: 0 }, + y: u384 { + limb0: 61302751785256451920898767404, + limb1: 57900798207103215347751754776, + limb2: 510979647399546275, + limb3: 0 + } + }; + + let coeff0: u384 = u384 { + limb0: 18926594921877902213758803518, + limb1: 22171130911848535840675118249, + limb2: 533113395777468169, + limb3: 0 + }; + + let coeff2: u384 = u384 { + limb0: 11789905667864267216113783162, + limb1: 34787431084162724474295026005, + limb2: 1992818134334709100, + limb3: 0 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 32588232865761331317945543626, - limb1: 42920692865198747596796644719, - limb2: 1292288524620745949, + limb0: 44237499188219561716965821951, + limb1: 29068321073993617097620523996, + limb2: 2616983273233811050, limb3: 0 }, u384 { - limb0: 22109629374835879147832829060, - limb1: 77111384800343837264156671167, - limb2: 3063898201025651161, + limb0: 3327941640918447977403253171, + limb1: 76154340205481000024933075760, + limb2: 2802044260424746491, limb3: 0 }, u384 { - limb0: 24107147632521216287129241473, - limb1: 46679700613611998209717953614, - limb2: 2329384646076374441, + limb0: 56438787601403580141325896583, + limb1: 36339134672395207067442779593, + limb2: 2008115423737826107, limb3: 0 }, u384 { - limb0: 34705519720342937325384114955, - limb1: 7544545746441526561568429662, - limb2: 321838271172728463, + limb0: 42619109157011030380406953397, + limb1: 29756427779698272461891325345, + limb2: 1342164311720450935, + limb3: 0 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 11965288496913229204009981023, + limb1: 26740381750208847421560634035, + limb2: 1693417900677054029, limb3: 0 }, u384 { - limb0: 54240729226336754529891271225, - limb1: 60872072766243616304862081407, - limb2: 257968258960322105, + limb0: 26799399022844720180326536220, + limb1: 2825709733994950568492654075, + limb2: 1243412673254409927, limb3: 0 }, u384 { - limb0: 2543242936061279358354121977, - limb1: 31783549287040172917293284174, - limb2: 305241059133926046, + limb0: 14228335690190514799848884079, + limb1: 57730452658079174027488182234, + limb2: 1395822044601651686, limb3: 0 }, u384 { - limb0: 74705003839443619688298510508, - limb1: 56879028618946847021972239934, - limb2: 980566852076747479, + limb0: 26028092557699137744351401945, + limb1: 8608252081711461107372788449, + limb2: 2586371792171060451, limb3: 0 }, u384 { - limb0: 31345188335193998570564539413, - limb1: 50931972522891471604441323597, - limb2: 658878908941684905, + limb0: 37957144974302941991426166046, + limb1: 39434591554061410561806218322, + limb2: 174434171504126794, + limb3: 0 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 58212970743282169726523508188, + limb1: 12332980192462000635087583498, + limb2: 768104795456191077, limb3: 0 }, u384 { - limb0: 19539844265600609273886224350, - limb1: 42702180300091913904288405785, - limb2: 3444993136106080444, + limb0: 29755827658352229821663292064, + limb1: 78554703376256060102591498247, + limb2: 400855940499081980, limb3: 0 }, u384 { - limb0: 49711396943153995822956410677, - limb1: 53913276305137721624552051841, - limb2: 2750451209395678440, + limb0: 6708214298706075286435957397, + limb1: 17514076504261263985432773778, + limb2: 1774631670371577349, limb3: 0 }, u384 { - limb0: 30234994542158251909307390480, - limb1: 37082732317122305754957358281, - limb2: 1159442963746785705, + limb0: 46339656966918220197016248105, + limb1: 17212599077166632154236671478, + limb2: 385828622097463605, limb3: 0 }, u384 { - limb0: 68197993831314783171983742905, - limb1: 53897604287461337563561928239, - limb2: 528276659766376889, + limb0: 78313794566333946292624619618, + limb1: 46366537921589010624955118549, + limb2: 768219788298160435, + limb3: 0 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 71543879203571184504048880471, + limb1: 59614311822361137145238510546, + limb2: 930121350344520021, limb3: 0 }, u384 { - limb0: 42543172544982570052857664023, - limb1: 60894664981146960725259421456, - limb2: 1568782484594102931, + limb0: 17104913831185493009514731615, + limb1: 8289618182855331407667405192, + limb2: 2114033962512689696, limb3: 0 }, u384 { - limb0: 34445652327236331720596696809, - limb1: 257120338022751237048174282, - limb2: 3330061854342727628, + limb0: 43289575798982591282833437677, + limb1: 8298855205574663293831046320, + limb2: 2749673857108068302, limb3: 0 }, u384 { - limb0: 20867829993853018589638419949, - limb1: 60368865098254360087322536075, - limb2: 2341268480058990900, + limb0: 11757619356668888688405851737, + limb1: 50576370329908438454647915835, + limb2: 1951844819685858248, limb3: 0 }, u384 { - limb0: 68969586761391561090281896559, - limb1: 66683915952894400650221431918, - limb2: 2341181818185855399, + limb0: 39506853045469557056557666931, + limb1: 69300794907239421869097720635, + limb2: 2503264995772838862, limb3: 0 }, u384 { - limb0: 42018946958951763195093848207, - limb1: 47453279052251022910409565149, - limb2: 2253296117258904635, + limb0: 17332990945355737742538566964, + limb1: 55902894981161597246855971135, + limb2: 3445108781106250088, limb3: 0 }, u384 { - limb0: 4589304846514288715766513407, - limb1: 44950647632290901991879197353, - limb2: 363202783876958070, + limb0: 62128076719890833771235312473, + limb1: 30027878234381547235596397026, + limb2: 1357598950990550926, limb3: 0 - } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit(input, 0); - let exp = array![ + }, u384 { - limb0: 11700412489472584404906732428, - limb1: 7017305906384258990996142651, - limb2: 2188885089417606049, + limb0: 63941514833161185630774327756, + limb1: 63378238159955251401717592303, + limb2: 2382064037537721377, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 0 + ); + let res: u384 = u384 { + limb0: 25383102035936540363761097664, + limb1: 9285330303478073459034036981, + limb2: 3413067269632576702, + limb3: 0 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit_BLS12_381() { - let input = array![ + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit_BLS12_381() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 43165186690971047560311708381, + limb1: 69917515310259397080114460258, + limb2: 20394762378384094161904970392, + limb3: 4222285109988260429586839512 + }, + y: u384 { + limb0: 43285662375831402482400778207, + limb1: 48879202687908768173306266272, + limb2: 4100500076510934582371919056, + limb3: 5459623500106549711382236508 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 1373675024443218656325893331, + limb1: 31053564592595310707404278793, + limb2: 13330855748347886480343185276, + limb3: 3106190604025412660535424586 + }, + y: u384 { + limb0: 64506774694992841008139080625, + limb1: 39412839001481924145197617233, + limb2: 23099520114894680353887403496, + limb3: 3686191629990135809261256203 + } + }; + + let coeff0: u384 = u384 { + limb0: 18576700323940639157485601256, + limb1: 70981406061094947898122715548, + limb2: 74443420867489229448657163806, + limb3: 1065541839327058890252772653 + }; + + let coeff2: u384 = u384 { + limb0: 10882451445033789762918705450, + limb1: 59997043538183169019635781983, + limb2: 67547598261196281708809119931, + limb3: 6904919142843347521171393047 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 60496054216794627907230883847, - limb1: 61531619852785734994828031727, - limb2: 39570610369239161867772003339, - limb3: 5359885371985722808745182284 + limb0: 64028141673307812555223566243, + limb1: 21126490056480020626846435772, + limb2: 30918762893938642159593046477, + limb3: 245725871741041374975102778 }, u384 { - limb0: 55978050899771680915421509269, - limb1: 20462354923328373145661101232, - limb2: 40002096590721721009002242104, - limb3: 3144109407828011100147314035 + limb0: 62330338029423412496024706882, + limb1: 33716663198078541915875724976, + limb2: 33827156916522587369966676453, + limb3: 3761533852198246395553511273 }, u384 { - limb0: 69366444930671093997631557939, - limb1: 6389788789772898712115050332, - limb2: 17307784731118680092022161416, - limb3: 40768416743364839609168258 + limb0: 73243097072286306572800791064, + limb1: 75437708324936351502965177558, + limb2: 1123668982341118334134880831, + limb3: 350911528660749289271831729 }, u384 { - limb0: 22497279753562664145434202668, - limb1: 60386529417454953343223531453, - limb2: 75088256275539322718177877, - limb3: 1250337252585059137435895456 + limb0: 48836062851493724024987896278, + limb1: 18744478960593497574895814400, + limb2: 68088412227359826052813168972, + limb3: 4211186181426771329323694298 }, u384 { - limb0: 30957467822565004701889134690, - limb1: 10508725227063415207534086273, - limb2: 63475809437467638138399163432, - limb3: 3410768704590173371839257043 - }, + limb0: 23124626316359900677101984069, + limb1: 73103433387629399026277172836, + limb2: 50536436095979029689679785312, + limb3: 1456507416663684358942367285 + } + ] + .span(); + + let log_div_a_den: Span = array![ u384 { - limb0: 52001922848060176808540064098, - limb1: 31738402110962243170210078849, - limb2: 31201437160781594938206481223, - limb3: 319679280150480155137692892 + limb0: 19524314450822527329497564280, + limb1: 70908906485605465790186705542, + limb2: 35002619754538527134808343764, + limb3: 7212893300244950935021814958 }, u384 { - limb0: 5917347804205769420250736244, - limb1: 10783891381854403309469486300, - limb2: 46325343455327234567189427004, - limb3: 1046383683688273545515082947 + limb0: 30187116140319496974912862001, + limb1: 48799470798753569389336700409, + limb2: 51668570527759383170487341079, + limb3: 1655248224282238163164773051 }, u384 { - limb0: 36924690380590967862976608918, - limb1: 9565749738680690558728698969, - limb2: 76426236609734878917236513267, - limb3: 4475569969601403289527962120 + limb0: 38695727774643509759953756866, + limb1: 17126375216654223283413846690, + limb2: 68159746454656712574471549378, + limb3: 938019970927493419520858982 }, u384 { - limb0: 20996090809411546440115503396, - limb1: 7163880851292165933199279562, - limb2: 54354864813683854307720002356, - limb3: 6979058360657268536196008059 + limb0: 49814761337857653975061997140, + limb1: 67275263087720024936888562079, + limb2: 44298718131932898230174584856, + limb3: 3186117696183744775673821990 }, u384 { - limb0: 35827067536715676292544348083, - limb1: 43585067484812994337723055170, - limb2: 36606837810431653954207504286, - limb3: 7861510954675653030454925708 + limb0: 58430584158846741026080282444, + limb1: 25245680165387615629998818017, + limb2: 78421505021122680314575527994, + limb3: 857881252721704264314864561 }, u384 { - limb0: 947325183894885814892067358, - limb1: 61874025028763116286065085742, - limb2: 10356328394643466366004856520, - limb3: 3967170132682034132995856554 + limb0: 75844527636037548442201950558, + limb1: 46379609936348424644016896851, + limb2: 14695681396320810545968202622, + limb3: 7692526044345365657645297247 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 59378131572103455961175517342, + limb1: 55808192543544592862447852362, + limb2: 68678398609668437002709395420, + limb3: 2978175072802498965141806417 }, u384 { - limb0: 49937316515061285623366883991, - limb1: 6658289289666790543342233751, - limb2: 20505884212309692175204166690, - limb3: 742637117585841045972490592 + limb0: 42145476866416089225354984960, + limb1: 4330545704645134294977064338, + limb2: 45344372948240479100413782848, + limb3: 6621663855108047960368046401 }, u384 { - limb0: 26268088921910470497576988578, - limb1: 74655165590840111721485302034, - limb2: 13309475840591605532939502444, - limb3: 4289772931201045569880712598 + limb0: 64351998269330256232691803832, + limb1: 64318413114071263899404704554, + limb2: 48438382570386753447379819564, + limb3: 5195337556525424482696534362 }, u384 { - limb0: 22172361885597528058522837674, - limb1: 11775793557395009521987735059, - limb2: 49056220142367616538349848865, - limb3: 6410334770850698483171735342 + limb0: 29664041058092961469921300538, + limb1: 5285980666757143594718071424, + limb2: 42523071728521032734343793405, + limb3: 7258519357538542310305261189 }, u384 { - limb0: 32641384981592063353943753503, - limb1: 37952740471532231441661150929, - limb2: 22166137323503418555850576640, - limb3: 4151900611327085766794627615 + limb0: 12164800029416215335299577246, + limb1: 32867488546962500085874239205, + limb2: 19896716127516382156212910620, + limb3: 6204886798574107078918662465 }, u384 { - limb0: 70089392902290126982618262179, - limb1: 19739518692767069416071703067, - limb2: 63554302996753127300981661331, - limb3: 193415565121207755944564106 + limb0: 52391896317815037768168024882, + limb1: 8803023274489797136583137175, + limb2: 56309197846896651023794986111, + limb3: 7826206923877451394407937457 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 7897438533363568857874672851, + limb1: 66250301347808051994700389267, + limb2: 30255629545301289661070704087, + limb3: 4044759229396296089747754939 }, u384 { - limb0: 61949749587453403001623514656, - limb1: 38004516660137147237050316229, - limb2: 38400265330758997095668352206, - limb3: 5601937306886132012848160434 + limb0: 75906342119350169619458182248, + limb1: 33730279642446571396203195621, + limb2: 11180052238657403612612166225, + limb3: 6285120259310007705890799075 }, u384 { - limb0: 30770735046537759660141500473, - limb1: 2064921156230435128443880958, - limb2: 17352567509445626353173001695, - limb3: 8028678616239976086914494065 + limb0: 43264629198570518863064010733, + limb1: 72407269251548227379565248645, + limb2: 14935285505642613887456089787, + limb3: 7882442472631512258057233282 }, u384 { - limb0: 4642075577178335597235685631, - limb1: 37370687283300325309437702344, - limb2: 60755496049358214252410232813, - limb3: 2305164445725669914889440298 + limb0: 74145408479393214750289035988, + limb1: 17431498364682868199822761649, + limb2: 57312691130570348363810232350, + limb3: 4044175930849623451381377296 }, u384 { - limb0: 7933459682592082500819271317, - limb1: 19106093050569165904094138192, - limb2: 64672773040040426273431559439, - limb3: 7299490094363373731631236492 + limb0: 42772810005318944661768652636, + limb1: 15590402383752320998704693882, + limb2: 44036747589447627060742987962, + limb3: 546270077974573836650002957 }, u384 { - limb0: 66965298965771569064876393725, - limb1: 18741511684061559311908234319, - limb2: 63874554805216446065278933982, - limb3: 3553216006864289057115239594 + limb0: 23322832688108859044772399466, + limb1: 33925894869330820421611849483, + limb2: 54774771899660228275798792954, + limb3: 6860967141537636341842744542 }, u384 { - limb0: 78277916509034314249914029264, - limb1: 76882035263351195442112525123, - limb2: 24485707356574611790861865501, - limb3: 375974721461996055111485899 + limb0: 8180433722233846113276826286, + limb1: 18263761769620988804436683631, + limb2: 21296152914339763094002639050, + limb3: 4955802473365182050273334235 }, u384 { - limb0: 18430320993837076618076167040, - limb1: 1578858175917430512009253525, - limb2: 54152067805937494428832892, - limb3: 6082096186212988915211338958 + limb0: 22062101326248438963738967678, + limb1: 15471588330549963945434935132, + limb2: 59926227748979981662152323421, + limb3: 5803474454340310615429123769 }, u384 { - limb0: 10338447293859088791413926764, - limb1: 14059819414854158758910360599, - limb2: 66891076716614965935073474464, - limb3: 589813710671499342754576843 + limb0: 61923664243190382334500654334, + limb1: 19564630540317843168975393922, + limb2: 12730877225579453547549887747, + limb3: 4468238513650587045294874142 } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit(input, 1); - let exp = array![ - u384 { - limb0: 67125973487036301729081121576, - limb1: 67067346472218439998724380615, - limb2: 43749532206529297295258947757, - limb3: 7412785537965395872713593480 - } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 1 + ); + let res: u384 = u384 { + limb0: 76539844859838743713384262922, + limb1: 6268610119141610121057002242, + limb2: 41790163228452064756497269787, + limb3: 5859254972929823052723913943 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit_BN254() { - let input = array![ - u384 { - limb0: 72352229351541557974185256159, - limb1: 109695862189705609719928842, - limb2: 586385101556276692, + fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit_BN254() { + let A0: G1Point = G1Point { + x: u384 { + limb0: 55668785107385345975752051280, + limb1: 64883914332629146444197111757, + limb2: 3389193101876737875, + limb3: 0 + }, + y: u384 { + limb0: 51423999903897577686947789751, + limb1: 5183952842749797492611248045, + limb2: 359714847378698731, + limb3: 0 + } + }; + + let A2: G1Point = G1Point { + x: u384 { + limb0: 44072274133839950303252629486, + limb1: 64525881541802110150723770773, + limb2: 2983494767123261625, limb3: 0 }, + y: u384 { + limb0: 27810531813873559107007780312, + limb1: 75043292133600441181275178414, + limb2: 3192437768491137341, + limb3: 0 + } + }; + + let coeff0: u384 = u384 { + limb0: 10609285974367965880368994737, + limb1: 59765436325149099051264815070, + limb2: 839820320230654168, + limb3: 0 + }; + + let coeff2: u384 = u384 { + limb0: 57435018450721878992032589945, + limb1: 56158962864896780296006864635, + limb2: 1210721556463011116, + limb3: 0 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 67992600012982420926133220046, - limb1: 23077548885373181195572604447, - limb2: 2828225239011667775, + limb0: 51980303238257340939075389625, + limb1: 29419149037721018532034165792, + limb2: 1762736554193168628, limb3: 0 }, u384 { - limb0: 53667012199774782546845025478, - limb1: 13988392951643632014579812896, - limb2: 2855263762372963376, + limb0: 60042776488008117419880722474, + limb1: 6049712153568245481145035953, + limb2: 1966269248594059195, limb3: 0 }, u384 { - limb0: 44657725054425516182046824655, - limb1: 11558627534921529854849092531, - limb2: 652105213504402783, + limb0: 16329307157267357311241895640, + limb1: 71395564642020900531805318618, + limb2: 1926949878923970758, limb3: 0 }, u384 { - limb0: 1840421064017092026928335363, - limb1: 27948250785264884498918334154, - limb2: 1068426233884146722, + limb0: 38204894262933024875592342121, + limb1: 77028297798340164216119503244, + limb2: 2801276035461103669, limb3: 0 }, u384 { - limb0: 72458689863252062882649001148, - limb1: 57036135675129203477209168166, - limb2: 2976109614092192022, + limb0: 14417063359116162959087224381, + limb1: 45181177729831640333313431426, + limb2: 1534242523443380315, + limb3: 0 + } + ] + .span(); + + let log_div_a_den: Span = array![ + u384 { + limb0: 33106758832017106593895347638, + limb1: 70510013012226003162572674973, + limb2: 2776081437219283200, limb3: 0 }, u384 { - limb0: 10172219962658913022154488244, - limb1: 75017080977665226557673008652, - limb2: 761513689810464176, + limb0: 53363638359990400134671871630, + limb1: 64197668598527049072889414785, + limb2: 1626872940959679097, limb3: 0 }, u384 { - limb0: 57831097157244995651582775035, - limb1: 56485637013277440733112642140, - limb2: 1840027204273873818, + limb0: 48469481536116538599742143463, + limb1: 36356404449337761124562374339, + limb2: 467996245412698471, limb3: 0 }, u384 { - limb0: 51488644415329370925019831230, - limb1: 71274770803685296705510079601, - limb2: 2082112336717404596, + limb0: 11992589081199988514061300214, + limb1: 47402229920671397129896176339, + limb2: 611979743651034203, limb3: 0 }, u384 { - limb0: 17802357378338648940166652311, - limb1: 1666505890335566830781071452, - limb2: 2554512134891071074, + limb0: 8342157188030492896997505177, + limb1: 51418464347089486288707415102, + limb2: 899157108623096734, limb3: 0 }, u384 { - limb0: 17447419136232834430860315795, - limb1: 56080937434418198093665616470, - limb2: 271507322399880886, + limb0: 61514321690367231113489247420, + limb1: 8794082332401772384053866233, + limb2: 277442843723388983, + limb3: 0 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 37014479358602183893993967274, + limb1: 73992410814615679596704876862, + limb2: 2999773476450883682, limb3: 0 }, u384 { - limb0: 71734764027497687440959466964, - limb1: 26179242522752084688581078523, - limb2: 2371126598316569875, + limb0: 72238916972117140272551967038, + limb1: 23277513766764053423386836857, + limb2: 3439322102752682523, limb3: 0 }, u384 { - limb0: 53001879985015283259353718573, - limb1: 42722513826086271939214843879, - limb2: 3335874891481034863, + limb0: 14984222068724942946017071379, + limb1: 31059530731656514522994603031, + limb2: 1713617869122566164, limb3: 0 }, u384 { - limb0: 45242695156380974609575304310, - limb1: 19252224704182182869429558083, - limb2: 2181202683696566687, + limb0: 74022047303277785982704653841, + limb1: 20233789422716363622468824175, + limb2: 122929110412205450, limb3: 0 }, u384 { - limb0: 15085828163067877367322517405, - limb1: 52209992599600172477278698580, - limb2: 1633909151565962963, + limb0: 52806453983716513022545318079, + limb1: 69394147900438600148709986176, + limb2: 1059097841874136265, limb3: 0 }, u384 { - limb0: 37001506145532468353282582033, - limb1: 4291883352266323174688581548, - limb2: 3013531520861314659, + limb0: 64919098044389771697189686960, + limb1: 49709947946535787933782952169, + limb2: 2316970353702107704, + limb3: 0 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 33284631820784061601209716285, + limb1: 74909083127844480788536082182, + limb2: 671878480678009236, limb3: 0 }, u384 { - limb0: 19700584396745388153764221534, - limb1: 42488934677374555174315232256, - limb2: 646476748448880253, + limb0: 44844167694643577857231315651, + limb1: 6657705289327963379468068188, + limb2: 483141536571039728, limb3: 0 }, u384 { - limb0: 22068620180697579185898549089, - limb1: 69283915317002778409893284629, - limb2: 347651441635828348, + limb0: 35392693917830988380623340209, + limb1: 33039689813208976084348677152, + limb2: 2290277515286470798, limb3: 0 }, u384 { - limb0: 68243106492345335480105108532, - limb1: 7757128702044682744238220654, - limb2: 3007487481293790040, + limb0: 76236704126680070464657036953, + limb1: 20011919312715580846535499773, + limb2: 1625633272058550811, limb3: 0 }, u384 { - limb0: 66236929673530884233645586901, - limb1: 7389038283343813755265297320, - limb2: 3475207490854347497, + limb0: 28462980010160556092527025322, + limb1: 27368980853969169741822569763, + limb2: 820454272470516698, limb3: 0 }, u384 { - limb0: 4645575212695119035598803845, - limb1: 170766220800888265123408008, - limb2: 1800502560172094280, + limb0: 77193861551429763154225988651, + limb1: 28981858341369669693974093771, + limb2: 2751281296214683942, limb3: 0 }, u384 { - limb0: 62120472738151456561021868284, - limb1: 22599772358810472611047161037, - limb2: 3212461292401604586, + limb0: 16477718064252151028071803271, + limb1: 52212823863210503242987590063, + limb2: 3376222138707704498, limb3: 0 }, u384 { - limb0: 78865510699530816999690257603, - limb1: 52438847471388457525305827726, - limb2: 2244375768231156426, + limb0: 9759968469496453740635485369, + limb1: 23234685153225415835212540078, + limb2: 3179602911160127548, limb3: 0 }, u384 { - limb0: 23507616024573787281496785879, - limb1: 4633523845333701238548283116, - limb2: 3392988848811485376, + limb0: 47921014619946634484315551373, + limb1: 11241481142989006382248553109, + limb2: 2093927154673692725, limb3: 0 } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit(input, 0); - let exp = array![ - u384 { - limb0: 56149420417655143552764995406, - limb1: 59978217342842349576011470883, - limb2: 3373506507271656045, + ] + .span(); + + let (res_result) = run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit( + A0, A2, coeff0, coeff2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 0 + ); + let res: u384 = u384 { + limb0: 41224817083161208159053381458, + limb1: 1477753262266382275975380999, + limb2: 183623896991182508, + limb3: 0 + }; + assert_eq!(res_result, res); + } + + + #[test] + fn test_run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit_BLS12_381() { + let f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 42271408514907683370518582092, + limb1: 14396112118311311694672865421, + limb2: 73021132189690225677253128861, + limb3: 1048550636737098170061806412 + }, + a_den: u384 { + limb0: 20303182462314789564649187944, + limb1: 4977046164711247374833454931, + limb2: 29284724587724128201714478486, + limb3: 1478375517602823137596723108 + }, + b_num: u384 { + limb0: 53564469164459051657762941437, + limb1: 32576147524319959113051814711, + limb2: 38808799870087519220815163588, + limb3: 2616364045448869513294551625 + }, + b_den: u384 { + limb0: 53208008738795411778691224452, + limb1: 16508421892486818019881466929, + limb2: 29073454590936142509934208962, + limb3: 3136837029253294661723679724 + } + }; + + let f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 68208468221357365382743023196, + limb1: 16113920624525914013554852373, + limb2: 78015269508817691586389582412, + limb3: 6441687755236137217566165141 + }, + a_den: u384 { + limb0: 57956437528449004511724155667, + limb1: 52836025426460305704757577324, + limb2: 9190032983906381011009169118, + limb3: 6288974341851372922204073724 + }, + b_num: u384 { + limb0: 16959443513509557303687662045, + limb1: 6782782958067228623161607648, + limb2: 18652085059780072590525908281, + limb3: 7665421399096715323414994435 + }, + b_den: u384 { + limb0: 50514724484581989291399566572, + limb1: 71277649175615385679950490834, + limb2: 12386173778644937752477465303, + limb3: 5157326700574666717676617699 + } + }; + + let yA0: u384 = u384 { + limb0: 59575162492125636541485549440, + limb1: 50799233065043704230843701664, + limb2: 241741852192371553246115751, + limb3: 4390031635852628168389271869 + }; + + let yA2: u384 = u384 { + limb0: 15649206260542250993424966033, + limb1: 43033760513471438345556853487, + limb2: 49782425448450166101884571353, + limb3: 6798152211613935112448481331 + }; + + let coeff_A0: u384 = u384 { + limb0: 24162973061342599419346993478, + limb1: 61309776783894135378589284391, + limb2: 76602683038046597135468289049, + limb3: 3467158119872887846242941153 + }; + + let coeff_A2: u384 = u384 { + limb0: 67432242477464238976461199936, + limb1: 47112979755842005795579719056, + limb2: 20921084387966758251738094780, + limb3: 6460334415612278233574008456 + }; + + let (res_result) = run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs, f_a1_accs, yA0, yA2, coeff_A0, coeff_A2, 1 + ); + let res: u384 = u384 { + limb0: 77731549246874363306461661032, + limb1: 63679870086771379532368437702, + limb2: 63028366636436485111043615542, + limb3: 653251983679609111687188036 + }; + assert_eq!(res_result, res); + } + + + #[test] + fn test_run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit_BN254() { + let f_a0_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 58280446892782192859377038916, + limb1: 40953080295398762391344997717, + limb2: 1773985397188630470, + limb3: 0 + }, + a_den: u384 { + limb0: 27249764037930567846218172537, + limb1: 19011748802343590489610636458, + limb2: 1410321390223264461, + limb3: 0 + }, + b_num: u384 { + limb0: 5731185999004768069004731831, + limb1: 39241751224020400654597717087, + limb2: 2020834351272407995, + limb3: 0 + }, + b_den: u384 { + limb0: 64095796044230917814179259865, + limb1: 39105593325256618226441303393, + limb2: 2029642705291974621, + limb3: 0 + } + }; + + let f_a1_accs: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 6455272549092671826509519312, + limb1: 65463462261161940834466898863, + limb2: 709257394876839757, + limb3: 0 + }, + a_den: u384 { + limb0: 38822865599411371039404195807, + limb1: 66588022967208120556755172040, + limb2: 1286642042344041850, + limb3: 0 + }, + b_num: u384 { + limb0: 47906885162578058538164730737, + limb1: 50258883807440287578679063824, + limb2: 1256897600197499811, + limb3: 0 + }, + b_den: u384 { + limb0: 9406778144477039479288656734, + limb1: 56403056411038013192065792670, + limb2: 795867129819795335, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let yA0: u384 = u384 { + limb0: 58781081570818241434142697606, + limb1: 33931014974790147367144790947, + limb2: 229525276486120494, + limb3: 0 + }; + + let yA2: u384 = u384 { + limb0: 51117769816528266524923650677, + limb1: 76942385322032925123146780840, + limb2: 2604066695098047042, + limb3: 0 + }; + + let coeff_A0: u384 = u384 { + limb0: 53469669196190738206678920457, + limb1: 43309084602205469172728579506, + limb2: 1301266048600613581, + limb3: 0 + }; + + let coeff_A2: u384 = u384 { + limb0: 65901976594455383272796456465, + limb1: 5132969593710279245653947797, + limb2: 1418178523824501187, + limb3: 0 + }; + + let (res_result) = run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit( + f_a0_accs, f_a1_accs, yA0, yA2, coeff_A0, coeff_A2, 0 + ); + let res: u384 = u384 { + limb0: 17148880327411391378206614289, + limb1: 7362917175057308169844650417, + limb2: 376579925199716583, + limb3: 0 + }; + assert_eq!(res_result, res); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit_BLS12_381() { - let input = array![ + fn test_run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit_BLS12_381() { + let xA0: u384 = u384 { + limb0: 6210046568564226032541208774, + limb1: 31366727136021378885085918549, + limb2: 49925458758641884641919295920, + limb3: 1441464553579516803637197434 + }; + + let xA2: u384 = u384 { + limb0: 56258951507108720113815726715, + limb1: 24441917448919747271948601114, + limb2: 44951314097778979520718801861, + limb3: 4815015057564019798444854528 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 72760998883449091149937441771, - limb1: 21799115456472667259088848348, - limb2: 18093308432641166571953276813, - limb3: 7474509786715543554740175447 + limb0: 48584540078443168847451735286, + limb1: 54623667447823607479651605422, + limb2: 52754475164594155363525584740, + limb3: 2217121426499620907169003223 }, u384 { - limb0: 18568083059267431098794435162, - limb1: 56054121190334040926346579969, - limb2: 70142048487786816544466224608, - limb3: 3120400755846491416320989737 + limb0: 3509646953493546455335968282, + limb1: 28377025265953310667455869879, + limb2: 67932517346257342899638093795, + limb3: 2863972352210674288491767607 }, u384 { - limb0: 36748355101792542484939135636, - limb1: 55862876098882738471339268708, - limb2: 69787559107053596606012408124, - limb3: 2193680074847360319431644522 + limb0: 61167003318164758015914710473, + limb1: 67952024586398202530696823107, + limb2: 34477046274830489121500992180, + limb3: 4905186559274787093392101982 }, u384 { - limb0: 67178456715103861143048689732, - limb1: 43264715172298749383509115771, - limb2: 45207824928811352908365188878, - limb3: 1447361342121276061096237789 + limb0: 65087853520896742076133370523, + limb1: 57731661826547070798977776087, + limb2: 37457283337925852102721294449, + limb3: 1528405518152763465799825455 }, u384 { - limb0: 64577279908721386174794789181, - limb1: 24907108233454494342466945937, - limb2: 67908111770168902057747159494, - limb3: 1994725789710580726331558872 + limb0: 6344455894065058999421513308, + limb1: 76408511067119718759827293380, + limb2: 36078869033374480975867845999, + limb3: 7063006732685810807796313783 }, u384 { - limb0: 21871730784553316576434950652, - limb1: 56202904434260642162509897076, - limb2: 22825280702436729203895731307, - limb3: 4865002098046641712899338761 - }, + limb0: 73642699226173251177232726966, + limb1: 153093432215530225840134318, + limb2: 39065217515938826988366952780, + limb3: 2883871503658441656059568580 + } + ] + .span(); + + let log_div_a_den: Span = array![ u384 { - limb0: 68189260662558153477366937782, - limb1: 5746545669548060694591138760, - limb2: 74626845220763029329559135537, - limb3: 5803627964964290928411015764 + limb0: 54199747261734630097113781797, + limb1: 74175391682687870333370896162, + limb2: 5538750469960644257132186369, + limb3: 2085254727890494248865792175 }, u384 { - limb0: 23908298603854518433034878604, - limb1: 77315647957576627474484567987, - limb2: 75163245493069305002155191458, - limb3: 6330983676320406590079802170 + limb0: 77735393985802253590713426664, + limb1: 27867213086285639966374638160, + limb2: 11466720957048582816848528487, + limb3: 4770536589068349725772393272 }, u384 { - limb0: 51433359944212393700415632258, - limb1: 56028803026860032023718362118, - limb2: 54949515655979808097747044564, - limb3: 6077879426740409369525802739 + limb0: 5099497905033299758211782831, + limb1: 44797628104370347625472444756, + limb2: 10731180887662674351963878969, + limb3: 5204813563846424413575540003 }, u384 { - limb0: 17686674048232355211437951826, - limb1: 64527712955412260762175948946, - limb2: 24309040432143254626251298850, - limb3: 2916757735801575256638298165 + limb0: 6424415750015539551999299858, + limb1: 336314705731102706893713482, + limb2: 46300711495617005168594687082, + limb3: 6668929189443698681991140452 }, u384 { - limb0: 57743937535221270498258839327, - limb1: 55618838948399163629915984853, - limb2: 31025861287790800140530213365, - limb3: 7633934417334254822694270272 + limb0: 71355009610885168679324013008, + limb1: 23909838630567568388570160712, + limb2: 55578836447830561028228089345, + limb3: 459213579616700199633725942 }, u384 { - limb0: 2565625325185230080191122291, - limb1: 25211740988660702817566910719, - limb2: 76655757371937296099830212884, - limb3: 6334754770572764971339577774 + limb0: 61040362146433004083819844141, + limb1: 7257754017407416582674802251, + limb2: 29743740455198348944654581816, + limb3: 2078538771761084077370041928 }, u384 { - limb0: 74212052866143791354856597164, - limb1: 26237865948560622423822957557, - limb2: 18855980204032897641702412826, - limb3: 3164359735401159457495354440 + limb0: 60375912085372234586006975480, + limb1: 12563630257594957592161588716, + limb2: 17195688857120241604535604023, + limb3: 2167950011965939442205082499 + } + ] + .span(); + + let log_div_b_num: Span = array![ + u384 { + limb0: 52144287777238114509798836599, + limb1: 63510619300248595428902552392, + limb2: 26296018614694695603906408174, + limb3: 711809303195370418743417193 }, u384 { - limb0: 70142296522414031281204145019, - limb1: 65098754930523037147146773222, - limb2: 50634931589877877188794960003, - limb3: 3325101673121088961000930254 + limb0: 52211325999951158962226509102, + limb1: 71072897838146636591452903567, + limb2: 18093036843645968723774375556, + limb3: 3977076293236353785977746202 }, u384 { - limb0: 21012294365728636844673226467, - limb1: 54919067362214587532625960584, - limb2: 20334537087735252513690681260, - limb3: 7134630623758607583482094765 + limb0: 20926956347428121717371229307, + limb1: 39167973702580879200974338043, + limb2: 73931421140987771804125842665, + limb3: 1484058777916331965415752268 }, u384 { - limb0: 43260475469718456486356799164, - limb1: 65664853888660161622342813507, - limb2: 68457151091686200214546271935, - limb3: 7509280335008960300696957392 + limb0: 57445862264436883147005423381, + limb1: 41390949042004739784811118143, + limb2: 77644488020290889109489418623, + limb3: 5290117841942491865296992395 }, u384 { - limb0: 12886976524388451785367994000, - limb1: 63318716991772148875701752458, - limb2: 23365067570925703507485123576, - limb3: 2586083534537305091630945533 + limb0: 69513087544810953073841529100, + limb1: 62162880911692143874423856153, + limb2: 40785395577884217937351308794, + limb3: 5185859564447180790525020311 }, u384 { - limb0: 7376513018071596959638714157, - limb1: 78061614724362819960498810336, - limb2: 38246348411941524597680624152, - limb3: 4271619388109816389470677683 + limb0: 14682042323034463933939933721, + limb1: 8017626049779495126315098747, + limb2: 69458594678563595559297832057, + limb3: 2518095019042531763189647466 }, u384 { - limb0: 55237613803053228775908232936, - limb1: 73331495372468222532108570610, - limb2: 21016440078298361658532139927, - limb3: 2945313380354027487850459538 + limb0: 24985860576774460604370372961, + limb1: 1340834478975055899509824165, + limb2: 2625504717648492795833838351, + limb3: 7868451162675615375146853142 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 8878201068795142160987708636, + limb1: 64601439170827553953848125390, + limb2: 76926423991386813855122803354, + limb3: 2819829916792690773213149690 }, u384 { - limb0: 3932525030958027086582773483, - limb1: 43548760452300846246942555487, - limb2: 12168648380009916449494709345, - limb3: 37787608488790655080073144 + limb0: 4564921427879793319223494995, + limb1: 8448234367804894448472819878, + limb2: 20982351743978657551564628278, + limb3: 7636029264776670039065027691 }, u384 { - limb0: 23336611144902354034992059797, - limb1: 49524807343031121413784923928, - limb2: 15819868032809983940305074587, - limb3: 2049563058355173548656697912 + limb0: 77327534125681170775259418623, + limb1: 58799396636027713162390332626, + limb2: 10695659750691371741041111241, + limb3: 3667300216936875257472481775 }, u384 { - limb0: 23119685745786444708415514781, - limb1: 37520132512170000727658230787, - limb2: 24430272835174852208046981124, - limb3: 4664007946374922456718486493 + limb0: 22169091740652787885613017918, + limb1: 561305495775730961846808566, + limb2: 26577495029113835893127935971, + limb3: 749893059359583788881600801 }, u384 { - limb0: 52372989059525912160221098700, - limb1: 50853893748824685616158954515, - limb2: 14647799525565763895044069351, - limb3: 3777650148330258044018176878 + limb0: 42300368557468181639453904579, + limb1: 12816291217720245058877262811, + limb2: 49001010808670926191958200438, + limb3: 5479236131009814999137589659 }, u384 { - limb0: 35317956037616787345837726609, - limb1: 34839825434652449351049937864, - limb2: 17924759845035124888429267419, - limb3: 5588027564529014563175844639 + limb0: 75780736278525312131732800705, + limb1: 60341850856133427522636637635, + limb2: 4635370242855441537546401758, + limb3: 2131534916452135004432463825 }, u384 { - limb0: 59598208049049563435480094995, - limb1: 7661571267936587783644900246, - limb2: 27237959379534127513560214041, - limb3: 4099925164915135700938319122 + limb0: 71312498493826879170995335379, + limb1: 1949919922263504932659085206, + limb2: 33593943677901085986550411528, + limb3: 6408742349028922710301753127 }, u384 { - limb0: 68682419463365306209464187112, - limb1: 45375100620501870089432556039, - limb2: 37733385749381356428918526321, - limb3: 3909953041194240936801047136 + limb0: 30725170511976440801341992659, + limb1: 70158530836372615678944532181, + limb2: 64936192179739830216981969791, + limb3: 1875632686408204864460826024 }, u384 { - limb0: 9529711529043345246188615707, - limb1: 35576593308901046269539147030, - limb2: 77989667559084082161783000019, - limb3: 2098458495270831050315222973 + limb0: 5416441650074344389735515789, + limb1: 66436954800048167066356196460, + limb2: 15318443593956385032213790664, + limb3: 8003705200892113318032210576 }, u384 { - limb0: 66084853748912315779251299764, - limb1: 25333164350881196743777913630, - limb2: 72428320775747153895761804183, - limb3: 861878056560279115845735205 + limb0: 29925452837584511339814435065, + limb1: 71781451021120638292092266438, + limb2: 62304929999554921948177070664, + limb3: 6122962266117534665966812562 } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit(input, 1); - let exp = array![ - u384 { - limb0: 49947855263014921995659587960, - limb1: 36379035630600189095985257755, - limb2: 7621805622580998446107130818, - limb3: 3852240263722057852491640157 + ] + .span(); + + let (A0_evals_result, A2_evals_result, xA0_power_result, xA2_power_result) = + run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit( + xA0, xA2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 1 + ); + let A0_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 64902187493294033540768325715, + limb1: 15950601108647667513772229416, + limb2: 57582136022964311648992012000, + limb3: 7375733385644613798201618293 + }, + a_den: u384 { + limb0: 34299130683631952299852156585, + limb1: 40894805946249410471625316459, + limb2: 72085593839231940090594501666, + limb3: 2844432858194609384226692458 + }, + b_num: u384 { + limb0: 30965429968535519044995426836, + limb1: 71191706862005207051662581366, + limb2: 68079069706087038979064394209, + limb3: 6973004489314339681238199594 + }, + b_den: u384 { + limb0: 11819077986061901816222206247, + limb1: 675335603754996456902551061, + limb2: 60520652336668462467378697703, + limb3: 5891773308810639172940317845 + } + }; + + let A2_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 27682765710887954439632305488, + limb1: 45003753610584698958149877541, + limb2: 57271656978382498394085898860, + limb3: 5904333526878782933283361578 + }, + a_den: u384 { + limb0: 55368691062503216513365937705, + limb1: 45151857154300304305285509271, + limb2: 72526468335663814700554045707, + limb3: 7519291077826291285011034943 + }, + b_num: u384 { + limb0: 48199038388326707756835222963, + limb1: 47016055677800560635405192190, + limb2: 10697647853687460502626282948, + limb3: 6474945206711153780479066282 + }, + b_den: u384 { + limb0: 77562492683072098261096568722, + limb1: 28573949915445840183324952506, + limb2: 13031065762642707134833732938, + limb3: 1241827870533733864750134498 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let xA0_power: u384 = u384 { + limb0: 10463696390670101974292313964, + limb1: 30429263133734304747496569650, + limb2: 30097597178977969005762279654, + limb3: 210814577139448243452821427 + }; + + let xA2_power: u384 = u384 { + limb0: 7591104035111200908915915917, + limb1: 37048947165078362429020124923, + limb2: 73856301685358249969714604322, + limb3: 6525251288239246219286750560 + }; + assert_eq!(A0_evals_result, A0_evals); + assert_eq!(A2_evals_result, A2_evals); + assert_eq!(xA0_power_result, xA0_power); + assert_eq!(xA2_power_result, xA2_power); } #[test] - fn test_run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit_BN254() { - let input = array![ + fn test_run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit_BN254() { + let xA0: u384 = u384 { + limb0: 27290109391410081994834815136, + limb1: 20458204772210031427067932888, + limb2: 128833153829831623, + limb3: 0 + }; + + let xA2: u384 = u384 { + limb0: 28699599091218773155358035566, + limb1: 76130904368364903419070344253, + limb2: 1366657658541174289, + limb3: 0 + }; + + let log_div_a_num: Span = array![ u384 { - limb0: 60560709830483091375804020284, - limb1: 43197816287652788845584008834, - limb2: 952729612994221368, + limb0: 75912296863312730401649691488, + limb1: 25906352713099587006356180921, + limb2: 2734819241107495919, limb3: 0 }, u384 { - limb0: 10492971140459274210700811770, - limb1: 44513061576255265500981326083, - limb2: 1067917977423273551, + limb0: 8127259587956589804165142205, + limb1: 24383457645184196255582101314, + limb2: 1736709905580689390, limb3: 0 }, u384 { - limb0: 39116622780220397755667403458, - limb1: 22352500441126699540646417604, - limb2: 3063271674606767109, + limb0: 74924361437787663200903105702, + limb1: 17653415259453100103746680659, + limb2: 2344269640586117778, limb3: 0 }, u384 { - limb0: 37270314562710266601265233496, - limb1: 70170752127981054059805844972, - limb2: 859714678417469440, + limb0: 59806045210262725526458903870, + limb1: 29509473950301411060749892432, + limb2: 3058449503229513201, limb3: 0 }, u384 { - limb0: 7623391984462887236582266015, - limb1: 42491402479383729878308216988, - limb2: 3452782009672681354, + limb0: 10476641705282468463695587695, + limb1: 31200143367046477848573954088, + limb2: 3238185370473636732, limb3: 0 }, u384 { - limb0: 64559904209742266183304320555, - limb1: 69704337930866810693557616486, - limb2: 3299664043155415477, + limb0: 33449238538863374300517019804, + limb1: 28091463497917425999984431614, + limb2: 1143967936971895084, limb3: 0 - }, + } + ] + .span(); + + let log_div_a_den: Span = array![ u384 { - limb0: 67559430074253106794595011940, - limb1: 4506464022247638802529509883, - limb2: 2341945580717447970, + limb0: 29255477601507623507580626137, + limb1: 41928122072257155865494509888, + limb2: 1735985052116826459, limb3: 0 }, u384 { - limb0: 9498395769183164685220205206, - limb1: 45134336288613177510213742987, - limb2: 2669792903937128468, + limb0: 33056007753616374312162015845, + limb1: 71405358686088291453851846899, + limb2: 2035124994221506231, limb3: 0 }, u384 { - limb0: 49072459003494725393436534870, - limb1: 52082467902580653677531159892, - limb2: 2606649103654554636, + limb0: 23238543001322742099746534628, + limb1: 7214238052564246677276106122, + limb2: 855274996560611601, limb3: 0 }, u384 { - limb0: 74055059530330231771921454741, - limb1: 53061158448153114658671266402, - limb2: 1448917347914504333, + limb0: 21943843819857678654134323775, + limb1: 47976285835987914057491836775, + limb2: 709640853520246060, limb3: 0 }, u384 { - limb0: 31357385428746531424018531805, - limb1: 51141841383992554608876666149, - limb2: 2108576180504140738, + limb0: 35348783784662968277035659241, + limb1: 14687371388926487293352672332, + limb2: 1944767865010002573, limb3: 0 }, u384 { - limb0: 59568841990531844953896713482, - limb1: 738046613222001001099970651, - limb2: 2864591434320851751, + limb0: 19645230072419461733827279082, + limb1: 26968307988203981880869251219, + limb2: 2413519660120413979, limb3: 0 }, u384 { - limb0: 78918891441719414915281368514, - limb1: 42595786019864910729645154069, - limb2: 2332981375169284075, + limb0: 36637903275957912864540282263, + limb1: 6853188419381636462799427520, + limb2: 3481984702531289841, limb3: 0 - }, + } + ] + .span(); + + let log_div_b_num: Span = array![ u384 { - limb0: 73940426017474097647230135471, - limb1: 5450208962476772138591757465, - limb2: 1126563023504792259, + limb0: 146030076227949400334384815, + limb1: 35580446869557986432712590466, + limb2: 2130648967995028332, limb3: 0 }, u384 { - limb0: 12497991859429624369378841554, - limb1: 43038160816172651229416840480, - limb2: 1395114064909906243, + limb0: 23654370222835508320059369112, + limb1: 77548724462177553720355393920, + limb2: 1388850589227609364, limb3: 0 }, u384 { - limb0: 78216661607741669574274640364, - limb1: 41906999438047143355081431569, - limb2: 3079975387921428976, + limb0: 12377111439852444926837178951, + limb1: 59528278038927077385096984381, + limb2: 426825584089232782, limb3: 0 }, u384 { - limb0: 9145201159815867598203053839, - limb1: 58820309865218752061636884055, - limb2: 716876953711284375, + limb0: 60220520864918782001528250178, + limb1: 43079585957269161858761144926, + limb2: 1869139898994399990, limb3: 0 }, u384 { - limb0: 47919555913202845524736646361, - limb1: 27165775241744433059614937901, - limb2: 3170520892864132107, + limb0: 77961711457252601247294545729, + limb1: 21397815731389161869616404765, + limb2: 3082859848769689614, limb3: 0 }, u384 { - limb0: 7312637792304348806296256704, - limb1: 65707725566676067595956811555, - limb2: 203314316937823219, + limb0: 20328030822406169353743584227, + limb1: 70557575839523426311564389084, + limb2: 3274134364868627524, limb3: 0 }, u384 { - limb0: 61094359288010675957661195982, - limb1: 77627591411109742420212671904, - limb2: 745165346533507101, + limb0: 72000520137764837462644246783, + limb1: 6754932813977657815572878489, + limb2: 324919404285612167, + limb3: 0 + } + ] + .span(); + + let log_div_b_den: Span = array![ + u384 { + limb0: 41185501208956454960575889511, + limb1: 41441081333085364229295923751, + limb2: 969737703267252736, limb3: 0 }, u384 { - limb0: 43708626113706013141793591071, - limb1: 44439620535069455225037692732, - limb2: 515927216987158182, + limb0: 32547285568714278926809579196, + limb1: 43066301929325963142500830262, + limb2: 3419228804722594027, limb3: 0 }, u384 { - limb0: 69966896750444602556632215137, - limb1: 11809297346016666377576163689, - limb2: 166150464296701499, + limb0: 62445849303983111602915185101, + limb1: 35047735588588409803790043474, + limb2: 2620511921441247591, limb3: 0 }, u384 { - limb0: 46151162575772561405597189355, - limb1: 34051211886365655982861863138, - limb2: 192901580404573442, + limb0: 12444365308571306300689465460, + limb1: 9548407978382876998078855381, + limb2: 1850284698872659933, limb3: 0 }, u384 { - limb0: 71224651109362605387179230439, - limb1: 77025323316292258909086735111, - limb2: 183982628697211185, + limb0: 11054951090793082353328578268, + limb1: 23686152292513057062841929406, + limb2: 2915099647978735914, limb3: 0 }, u384 { - limb0: 16643977945356356981949983936, - limb1: 52839909067565107751874718774, - limb2: 1631054796495564483, + limb0: 32888196795532285724015500385, + limb1: 38731333929415952739291070501, + limb2: 2313070265335517856, limb3: 0 }, u384 { - limb0: 70048367821558724187387179708, - limb1: 77155317606823885789624872003, - limb2: 3456355443560131626, + limb0: 51661077824120714546854244402, + limb1: 35175858496736535724116618844, + limb2: 658601457667862308, limb3: 0 }, u384 { - limb0: 73746832228116322001147796294, - limb1: 53075510893070141178755025066, - limb2: 3389854563291057351, + limb0: 4152021204302326432509857790, + limb1: 17090619335270315747726354131, + limb2: 1638999484934011960, limb3: 0 }, u384 { - limb0: 21138526233002691845902124138, - limb1: 55560982282160920599510200465, - limb2: 1764162309832058791, + limb0: 508918245973802653761934510, + limb1: 9202518011885788722949307490, + limb2: 17249403076200518, limb3: 0 - } - ]; - let got = run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit(input, 0); - let exp = array![ + }, u384 { - limb0: 2416167632796175225590722157, - limb1: 48551152508610380532404214460, - limb2: 2551930387880968103, + limb0: 59548990623035107422698481953, + limb1: 15148768562330170180113945047, + limb2: 2001558943410647470, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); - } - + ] + .span(); - #[test] - fn test_run_IS_ON_CURVE_G1_G2_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 3881018809921271934541826864, - limb1: 64593930856761652403104488417, - limb2: 51687612831028480094434490859, - limb3: 6451395243134363385557637476 + let (A0_evals_result, A2_evals_result, xA0_power_result, xA2_power_result) = + run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit( + xA0, xA2, log_div_a_num, log_div_a_den, log_div_b_num, log_div_b_den, 0 + ); + let A0_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 74037956619719218159549545727, + limb1: 8499628927385777706825871287, + limb2: 324981415238014309, + limb3: 0 }, - u384 { - limb0: 73771732899400505226642774976, - limb1: 77292648387036829692092888319, - limb2: 67705688267726945654399135199, - limb3: 843100134544885894591661870 + a_den: u384 { + limb0: 15380202336538040303009249000, + limb1: 51992279251305427622342876813, + limb2: 2254836442867049731, + limb3: 0 }, - u384 { - limb0: 66609547339788937829063625846, - limb1: 64502230214108702476017876154, - limb2: 62551902897932773703424157198, - limb3: 200159311825981504095706053 + b_num: u384 { + limb0: 50405096265545450426112274787, + limb1: 16751363170559432961445271799, + limb2: 2515413418878441317, + limb3: 0 }, - u384 { - limb0: 58203289413273329398830008060, - limb1: 10708502072587145958307542236, - limb2: 62245259645274544392753755759, - limb3: 3547280536548719816039237904 + b_den: u384 { + limb0: 1035602185887654477767517454, + limb1: 17350564691950392823542201248, + limb2: 695180571329552589, + limb3: 0 + } + }; + + let A2_evals: FunctionFeltEvaluations = FunctionFeltEvaluations { + a_num: u384 { + limb0: 27984242891080319737422820064, + limb1: 70459093132793228698553141495, + limb2: 2729857507380205981, + limb3: 0 }, - u384 { - limb0: 11874497649279717125574075734, - limb1: 76725924308597637572217578237, - limb2: 72943459051995571486494287251, - limb3: 2666709455792795377086696533 + a_den: u384 { + limb0: 74341429909358964645477719435, + limb1: 42118907297821551193759978990, + limb2: 2882409449471177801, + limb3: 0 }, - u384 { - limb0: 77799268205487882445330517287, - limb1: 10556565736115980790216886046, - limb2: 56292284761257825999332855736, - limb3: 3148537045961255164390913973 + b_num: u384 { + limb0: 8419389438224182868896304556, + limb1: 26813412074092926457112676932, + limb2: 2532246290770814272, + limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_IS_ON_CURVE_G1_G2_circuit(input, 1); - let exp = array![ - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + b_den: u384 { + limb0: 71758308160409097247063747887, + limb1: 22434174062286101109838048002, + limb2: 3382667580317365356, + limb3: 0 + } + }; + + let xA0_power: u384 = u384 { + limb0: 35843924950317277134702964905, + limb1: 39347112850905874100238885252, + limb2: 918821032765845819, + limb3: 0 + }; + + let xA2_power: u384 = u384 { + limb0: 74702301996156906931342402798, + limb1: 19137614285120830185895774782, + limb2: 2360770325090495545, + limb3: 0 + }; + assert_eq!(A0_evals_result, A0_evals); + assert_eq!(A2_evals_result, A2_evals); + assert_eq!(xA0_power_result, xA0_power); + assert_eq!(xA2_power_result, xA2_power); + } + + + #[test] + fn test_run_IS_ON_CURVE_G1_G2_circuit_BLS12_381() { + let p: G1Point = G1Point { + x: u384 { + limb0: 46706571765956834237956044675, + limb1: 21071548932965993517679544958, + limb2: 63088171608313565047035281560, + limb3: 583501615451560598771570574 + }, + y: u384 { + limb0: 31535595461224325559383171522, + limb1: 19779723463599699491052634388, + limb2: 67706574956172288067559165016, + limb3: 879075777356640452634108283 + } + }; + + let q: G2Point = G2Point { + x0: u384 { + limb0: 47837949294783728318374736614, + limb1: 58261748940919076050102374728, + limb2: 39232996742252933316448149762, + limb3: 2314525803145132837087697143 + }, + x1: u384 { + limb0: 47676155659479947194844013071, + limb1: 36346678414599632621205670133, + limb2: 7037347297487389790110409195, + limb3: 311353638324422075418771830 + }, + y0: u384 { + limb0: 63901942634575512646468896532, + limb1: 18887555207295220095855463067, + limb2: 24801194390196266031126834343, + limb3: 1983292358201868009950242958 + }, + y1: u384 { + limb0: 66496766513552587160552112528, + limb1: 3008376668367883050557359700, + limb2: 66116940471546115968881653930, + limb3: 7411712140303150979112406458 + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let b20: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let b21: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let (zero_check_0_result, zero_check_1_result, zero_check_2_result) = + run_IS_ON_CURVE_G1_G2_circuit( + p, q, a, b, b20, b21, 1 + ); + let zero_check_0: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_1: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_2: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_0_result, zero_check_0); + assert_eq!(zero_check_1_result, zero_check_1); + assert_eq!(zero_check_2_result, zero_check_2); } #[test] fn test_run_IS_ON_CURVE_G1_G2_circuit_BN254() { - let input = array![ - u384 { - limb0: 72303579505629692943460764225, - limb1: 64383731061350301183472899978, - limb2: 89326107581585284, - limb3: 0 - }, - u384 { - limb0: 2656445009483745034477298029, - limb1: 40135187278221230646314852042, - limb2: 748615905220004737, + let p: G1Point = G1Point { + x: u384 { + limb0: 28610756795125421341789836686, + limb1: 867082125726060679479563787, + limb2: 517675042607557601, limb3: 0 }, - u384 { - limb0: 42079130131667592628129761030, - limb1: 60081133978822882519077118249, - limb2: 2876942460693786388, - limb3: 0 - }, - u384 { - limb0: 73767780233257603821087361087, - limb1: 51865286289539495173932594223, - limb2: 1030923927894331265, + y: u384 { + limb0: 36882700424042850430562664053, + limb1: 63811137145513906528257638731, + limb2: 2919654018211177231, limb3: 0 - }, - u384 { - limb0: 53907605619747425403594570682, - limb1: 79164282061086811078259526201, - limb2: 651114202088725253, + } + }; + + let q: G2Point = G2Point { + x0: u384 { + limb0: 3153729208240962009983500478, + limb1: 40550523289894208045731503372, + limb2: 1084946966667758900, limb3: 0 }, - u384 { - limb0: 72347515962958596214393340424, - limb1: 71402752684547027195259763041, - limb2: 176111217446792037, + x1: u384 { + limb0: 68880333305383555718983970599, + limb1: 67893486303700750840295828244, + limb2: 105039074904354629, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 3, limb1: 0, limb2: 0, limb3: 0 }, - u384 { - limb0: 27810052284636130223308486885, - limb1: 40153378333836448380344387045, - limb2: 3104278944836790958, + y0: u384 { + limb0: 24042802651694448496166439628, + limb1: 16645378487191828916630937066, + limb2: 757214260369138307, limb3: 0 }, - u384 { - limb0: 70926583776874220189091304914, - limb1: 63498449372070794915149226116, - limb2: 42524369107353300, + y1: u384 { + limb0: 73170982836049039157350892353, + limb1: 7425931233989092027273176614, + limb2: 81769889353580197, limb3: 0 } - ]; - let got = run_IS_ON_CURVE_G1_G2_circuit(input, 0); - let exp = array![ - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b: u384 = u384 { limb0: 3, limb1: 0, limb2: 0, limb3: 0 }; + + let b20: u384 = u384 { + limb0: 27810052284636130223308486885, + limb1: 40153378333836448380344387045, + limb2: 3104278944836790958, + limb3: 0 + }; + + let b21: u384 = u384 { + limb0: 70926583776874220189091304914, + limb1: 63498449372070794915149226116, + limb2: 42524369107353300, + limb3: 0 + }; + + let (zero_check_0_result, zero_check_1_result, zero_check_2_result) = + run_IS_ON_CURVE_G1_G2_circuit( + p, q, a, b, b20, b21, 0 + ); + let zero_check_0: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_1: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_2: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_0_result, zero_check_0); + assert_eq!(zero_check_1_result, zero_check_1); + assert_eq!(zero_check_2_result, zero_check_2); } #[test] fn test_run_IS_ON_CURVE_G1_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 54315213640199676388484165664, - limb1: 64615415478039789431052978499, - limb2: 38289215076037097073681034912, - limb3: 2766009169873783676650746428 - }, - u384 { - limb0: 36163206015648980324790509040, - limb1: 76871435785270656253319980793, - limb2: 50183367621085513992950798907, - limb3: 6507713653583326966784429613 - }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_IS_ON_CURVE_G1_circuit(input, 1); - let exp = array![u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + let p: G1Point = G1Point { + x: u384 { + limb0: 17564266934605299855822610573, + limb1: 50198698710541599701136206773, + limb2: 34036089961288892525655927724, + limb3: 4442424905039454268724687265 + }, + y: u384 { + limb0: 12040449229476942965584002276, + limb1: 51377377766659944516165422963, + limb2: 53515021902729268805145735579, + limb3: 356850841752104041781197947 + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let (zero_check_result) = run_IS_ON_CURVE_G1_circuit(p, a, b, 1); + let zero_check: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_result, zero_check); } #[test] fn test_run_IS_ON_CURVE_G1_circuit_BN254() { - let input = array![ - u384 { - limb0: 52644011630690813522148617426, - limb1: 77877746910620474679324982432, - limb2: 488734493197095745, + let p: G1Point = G1Point { + x: u384 { + limb0: 10963338319382868633705196911, + limb1: 47121869529842916575828973009, + limb2: 546547428558054340, limb3: 0 }, - u384 { - limb0: 28626170957394882810848530650, - limb1: 21031546388754091774793504063, - limb2: 762300332427566472, + y: u384 { + limb0: 61794659804043923952658021753, + limb1: 71835376005474770439080422094, + limb2: 3287615896151516919, limb3: 0 - }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 3, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_IS_ON_CURVE_G1_circuit(input, 0); - let exp = array![u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b: u384 = u384 { limb0: 3, limb1: 0, limb2: 0, limb3: 0 }; + + let (zero_check_result) = run_IS_ON_CURVE_G1_circuit(p, a, b, 0); + let zero_check: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_result, zero_check); } #[test] - fn test_run_RHS_FINALIZE_ACC_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 61887017142914473275644872255, - limb1: 58069159593218796186366579742, - limb2: 61119004337032066715169330164, - limb3: 3317788482512211835665493383 - }, - u384 { - limb0: 41382289987431581744016102595, - limb1: 19919202319845217730294557086, - limb2: 51684320573642410086349200972, - limb3: 637082786619363188068467331 - }, - u384 { - limb0: 18860739372985077608702117557, - limb1: 1597339562471310782720133099, - limb2: 41999171353374307946274724142, - limb3: 6421250430828036230872829080 - }, - u384 { - limb0: 33531412186594188375450419478, - limb1: 61501478416996508496401873448, - limb2: 56243081304159867019996728910, - limb3: 3554071927697800872237178435 - }, - u384 { - limb0: 31733428187966668850473496906, - limb1: 29940719153222705894421166076, - limb2: 57705291141298402154268081267, - limb3: 7069208859630757260952725013 - }, - u384 { - limb0: 63285664815933159240534141829, - limb1: 68407573407485116259723203122, - limb2: 1356299378798219525379986798, - limb3: 1006125680322252358066580687 - } - ]; - let got = run_RHS_FINALIZE_ACC_circuit(input, 1); - let exp = array![ - u384 { - limb0: 65705911173912320345901936047, - limb1: 60702219827707070483185943298, - limb2: 48649405992156815700574841248, - limb3: 4595269416342216134155663990 + fn test_run_IS_ON_CURVE_G2_circuit_BLS12_381() { + let p: G2Point = G2Point { + x0: u384 { + limb0: 64881592413091416687078558238, + limb1: 19518258141337761496482490367, + limb2: 33231141266022101244155856946, + limb3: 4625146693117872657470299757 + }, + x1: u384 { + limb0: 35579312178133858856861960446, + limb1: 27884491798851879092994773017, + limb2: 44305637564309654505023120892, + limb3: 4066475203517568804151101476 + }, + y0: u384 { + limb0: 32810783144623114968661508608, + limb1: 13797236876990102053773715180, + limb2: 6716940154599378287763740748, + limb3: 1821033457768109755618432202 + }, + y1: u384 { + limb0: 17823320023165485199857944615, + limb1: 72240172101096947300324564285, + limb2: 75259141057546570123969821663, + limb3: 295351730220377715821559634 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b20: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let b21: u384 = u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }; + + let (zero_check_0_result, zero_check_1_result) = run_IS_ON_CURVE_G2_circuit( + p, a, b20, b21, 1 + ); + let zero_check_0: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_1: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_0_result, zero_check_0); + assert_eq!(zero_check_1_result, zero_check_1); } #[test] - fn test_run_RHS_FINALIZE_ACC_circuit_BN254() { - let input = array![ - u384 { - limb0: 48260330286441674708424697259, - limb1: 42318920684542540519119384547, - limb2: 1128991126786149844, + fn test_run_IS_ON_CURVE_G2_circuit_BN254() { + let p: G2Point = G2Point { + x0: u384 { + limb0: 20327502423815408938443636277, + limb1: 34883481233784974488228836322, + limb2: 2208072115582449063, limb3: 0 }, - u384 { - limb0: 7938632032443998648511649961, - limb1: 17356141526537130956730385433, - limb2: 1071065699868464167, + x1: u384 { + limb0: 21646904630757137888313408794, + limb1: 68601244667221384891181276448, + limb2: 511797177109400272, limb3: 0 }, - u384 { - limb0: 37619741555986601766966302341, - limb1: 43774217688409160760116850140, - limb2: 765995078829870260, + y0: u384 { + limb0: 19840162471593555304970554708, + limb1: 16766632680317987843754811088, + limb2: 54467295440720537, limb3: 0 }, - u384 { - limb0: 25465506521267819856047091585, - limb1: 36391637133555566268841396773, - limb2: 847591488136361640, + y1: u384 { + limb0: 58101386057589905723335529491, + limb1: 11726529671901099747471822727, + limb2: 1842652047096844660, limb3: 0 - }, - u384 { - limb0: 22807643629428285123183151353, - limb1: 55708330713379591852963876440, - limb2: 2683820433665504527, + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let b20: u384 = u384 { + limb0: 27810052284636130223308486885, + limb1: 40153378333836448380344387045, + limb2: 3104278944836790958, + limb3: 0 + }; + + let b21: u384 = u384 { + limb0: 70926583776874220189091304914, + limb1: 63498449372070794915149226116, + limb2: 42524369107353300, + limb3: 0 + }; + + let (zero_check_0_result, zero_check_1_result) = run_IS_ON_CURVE_G2_circuit( + p, a, b20, b21, 0 + ); + let zero_check_0: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let zero_check_1: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + assert_eq!(zero_check_0_result, zero_check_0); + assert_eq!(zero_check_1_result, zero_check_1); + } + + + #[test] + fn test_run_RHS_FINALIZE_ACC_circuit_BLS12_381() { + let acc: u384 = u384 { + limb0: 38157741182005799900184837164, + limb1: 21034546365543617462479199525, + limb2: 3746049627734751290374905709, + limb3: 2357835886399510165326018053 + }; + + let m: u384 = u384 { + limb0: 11356374310780364945260251406, + limb1: 62112023593808780121452856136, + limb2: 53066015316882389699382175946, + limb3: 5924233522996958176877005726 + }; + + let b: u384 = u384 { + limb0: 25796207199530035643538332337, + limb1: 29320810034753438950605948659, + limb2: 20971016232154145511367662385, + limb3: 4943994934408967740434654438 + }; + + let xA: u384 = u384 { + limb0: 38063656504223713435982820696, + limb1: 73014951734193334839374496489, + limb2: 9567661219474734034161053420, + limb3: 4407538340680793600617351221 + }; + + let Q_result: G1Point = G1Point { + x: u384 { + limb0: 10775465580624724323789472813, + limb1: 9239986989238181577480993255, + limb2: 15242563262099350368507780854, + limb3: 6940664962368958791336705021 + }, + y: u384 { + limb0: 71031002811457601953299610671, + limb1: 44393936195669730347789712107, + limb2: 57883879237603655085150977346, + limb3: 5794097063921577531414081325 + } + }; + + let (rhs_result) = run_RHS_FINALIZE_ACC_circuit(acc, m, b, xA, Q_result, 1); + let rhs: u384 = u384 { + limb0: 53470620556289164236164964190, + limb1: 25578890405596373910077891605, + limb2: 24215474126731079757985420055, + limb3: 774186665953038054567838611 + }; + assert_eq!(rhs_result, rhs); + } + + + #[test] + fn test_run_RHS_FINALIZE_ACC_circuit_BN254() { + let acc: u384 = u384 { + limb0: 47789288982153625936211091314, + limb1: 22790556483673439019797530023, + limb2: 422578445435456773, + limb3: 0 + }; + + let m: u384 = u384 { + limb0: 63564193557056427700519061379, + limb1: 3859985502446194295734397458, + limb2: 1682330943181674747, + limb3: 0 + }; + + let b: u384 = u384 { + limb0: 21880591190601213304220125238, + limb1: 18347763852893937204971538731, + limb2: 147454637293368614, + limb3: 0 + }; + + let xA: u384 = u384 { + limb0: 38981705189576391036754545370, + limb1: 38200451437623260512273298100, + limb2: 285869279439476269, + limb3: 0 + }; + + let Q_result: G1Point = G1Point { + x: u384 { + limb0: 25400260734572114057948715438, + limb1: 13567092499965229133149434143, + limb2: 2351498053255379660, limb3: 0 }, - u384 { - limb0: 17858926073002335585446583990, - limb1: 62282319402827862502223658486, - limb2: 641547017572429827, - limb3: 0 - } - ]; - let got = run_RHS_FINALIZE_ACC_circuit(input, 0); - let exp = array![ - u384 { - limb0: 43020444810219973869643857067, - limb1: 78487722760902767733668096942, - limb2: 2450254110215152594, + y: u384 { + limb0: 64112886788031393132256331831, + limb1: 68767686677431571826198867926, + limb2: 1330063957552371479, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + + let (rhs_result) = run_RHS_FINALIZE_ACC_circuit(acc, m, b, xA, Q_result, 0); + let rhs: u384 = u384 { + limb0: 37824128036192435284787862216, + limb1: 60273805252635637930144321149, + limb2: 106993060423381348, + limb3: 0 + }; + assert_eq!(rhs_result, rhs); } #[test] fn test_run_SLOPE_INTERCEPT_SAME_POINT_circuit_BLS12_381() { - let input = array![ - u384 { - limb0: 10010207970548938423340187084, - limb1: 7695130924251007745837131087, - limb2: 10527721448494185790979828754, - limb3: 2149731889427934112167082300 - }, - u384 { - limb0: 37908424340347145152672916671, - limb1: 40702460771288876327129173232, - limb2: 35345233775361055390801829118, - limb3: 6169516742962103203582227669 - }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_SLOPE_INTERCEPT_SAME_POINT_circuit(input, 1); - let exp = array![ - u384 { - limb0: 78849410085420736430300157562, - limb1: 8788679138520933549090517482, - limb2: 59451873475780250655343496866, - limb3: 5833740416966162252301903396 - }, - u384 { - limb0: 21675914025731754325157203463, - limb1: 7874374851252702876782445364, - limb2: 42239819010751327448395907278, - limb3: 4626427321528444424984045586 - }, - u384 { - limb0: 25443909781982522954719853322, - limb1: 49510209134068618526843056024, - limb2: 45213746093304262665924935879, - limb3: 2721658076122121951681203019 - }, - u384 { - limb0: 11180277778261171684704629184, - limb1: 18343088927615677118300462259, - limb2: 9594216486435462281493370043, - limb3: 1172307550991555583868494305 - }, - u384 { - limb0: 75155629151361031840445329950, - limb1: 22472539885849054517756914794, - limb2: 77364879924080831520412887399, - limb3: 220185985603050420176263820 - }, - u384 { - limb0: 27217601984882344894504770176, - limb1: 68767139843120141544149223570, - limb2: 115095602171498568942612897, - limb3: 4648512715843110276745108912 + let p: G1Point = G1Point { + x: u384 { + limb0: 57303175307189037764297937708, + limb1: 73106508321698251017485664038, + limb2: 36793121413931487827180057784, + limb3: 3266939425752615898574298090 + }, + y: u384 { + limb0: 18613945139075541652920345123, + limb1: 56611515683690161296536335302, + limb2: 21283575734373330014634889317, + limb3: 1412229885350243271775825786 + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let (mb_result) = run_SLOPE_INTERCEPT_SAME_POINT_circuit(p, a, 1); + let mb: SlopeInterceptOutput = SlopeInterceptOutput { + m_A0: u384 { + limb0: 65846997732454955595092043312, + limb1: 26627465443229855016669492136, + limb2: 28463554513647268440466197168, + limb3: 69976150926958678245773216 + }, + b_A0: u384 { + limb0: 46964243900178343949541445657, + limb1: 65963591892046693499592648615, + limb2: 51374162385112757859785454485, + limb3: 6308467601376506530696934513 + }, + x_A2: u384 { + limb0: 44507506887630250661091339020, + limb1: 55857783702891349760407812186, + limb2: 26520296244536592498519178701, + limb3: 7439232549821460768853231880 + }, + y_A2: u384 { + limb0: 40196357241977364833183346030, + limb1: 63482662936138720048287710924, + limb2: 50364001971291799943175786443, + limb3: 7339735993563594467193642894 + }, + coeff0: u384 { + limb0: 5387063649868152077233064558, + limb1: 74258815117388337125885546656, + limb2: 23193107587430871020743357538, + limb3: 5601919292082981525840403753 + }, + coeff2: u384 { + limb0: 32149393213486916074136878606, + limb1: 21003884230928627092546562382, + limb2: 45494161074400671733354913538, + limb3: 5461966990229064169348857320 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + assert_eq!(mb_result, mb); } #[test] fn test_run_SLOPE_INTERCEPT_SAME_POINT_circuit_BN254() { - let input = array![ - u384 { - limb0: 6754777447406199233880053248, - limb1: 29592157390458577971370257756, - limb2: 3000117645115658293, + let p: G1Point = G1Point { + x: u384 { + limb0: 1785535559409110691393306617, + limb1: 7597092814299530264289532476, + limb2: 878181267796675057, limb3: 0 }, - u384 { - limb0: 74292046482889929051988509288, - limb1: 63954496481719982841226773346, - limb2: 2481793984440015144, + y: u384 { + limb0: 48727289524028805321369454187, + limb1: 78638986380330519667851975673, + limb2: 1484979689236301097, limb3: 0 - }, - u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } - ]; - let got = run_SLOPE_INTERCEPT_SAME_POINT_circuit(input, 0); - let exp = array![ - u384 { - limb0: 28410243153404370084288088563, - limb1: 39482639662138611135709072649, - limb2: 763429169832334703, + } + }; + + let a: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + let (mb_result) = run_SLOPE_INTERCEPT_SAME_POINT_circuit(p, a, 0); + let mb: SlopeInterceptOutput = SlopeInterceptOutput { + m_A0: u384 { + limb0: 76540976842320287450430347706, + limb1: 60923805408749182380655088218, + limb2: 3075486977755850459, limb3: 0 }, - u384 { - limb0: 63347016304765991054776207810, - limb1: 25366636730535729198773503339, - limb2: 3045097332156004237, + b_A0: u384 { + limb0: 73189073861277227804485911093, + limb1: 37842561589438245231792258147, + limb2: 3419555488085548717, limb3: 0 }, - u384 { - limb0: 7029259507251224309510592606, - limb1: 4394235099959160960573638211, - limb2: 2360694219009690802, + x_A2: u384 { + limb0: 59926939870950637113741528741, + limb1: 17069599079331594437118205800, + limb2: 502224407897912239, limb3: 0 }, - u384 { - limb0: 10873665323371506257584653620, - limb1: 26056128684821873069202969974, - limb2: 190976246494716538, + y_A2: u384 { + limb0: 25758561730493458002295481710, + limb1: 28566268529224859488705341933, + limb2: 2741209599044821711, limb3: 0 }, - u384 { - limb0: 1010842944790402801638352442, - limb1: 36815218695260472920363455031, - limb2: 114829169171683136, + coeff0: u384 { + limb0: 42583975492174175219962759506, + limb1: 51578617680329020921599326557, + limb2: 3069107625101629141, limb3: 0 }, - u384 { - limb0: 55742525314635411403384754075, - limb1: 14892224453606490110825079477, - limb2: 2074969096309984395, + coeff2: u384 { + limb0: 1054190484187349089424642853, + limb1: 66001454459718233215712870201, + limb2: 405131936392898887, limb3: 0 } - ]; - assert_eq!(got.len(), exp.len()); - assert_eq!(got, exp); + }; + assert_eq!(mb_result, mb); } } diff --git a/src/cairo/src/definitions.cairo b/src/cairo/src/definitions.cairo index 25bcd69a..cd5ba520 100644 --- a/src/cairo/src/definitions.cairo +++ b/src/cairo/src/definitions.cairo @@ -1,5 +1,6 @@ use core::circuit::{u96, u384}; use garaga::basic_field_ops::{neg_mod_p}; +use core::result::Result; #[derive(Copy, Drop, Debug, PartialEq)] struct G1Point { @@ -7,6 +8,13 @@ struct G1Point { y: u384, } +trait G1PointTrait { + fn is_on_curve(self: @G1Point, curve_index: usize) -> bool; + fn is_infinity(self: @G1Point) -> bool; + fn update_hash_state( + self: @G1Point, s0: felt252, s1: felt252, s2: felt252 + ) -> (felt252, felt252, felt252); +} #[derive(Copy, Drop, Debug, PartialEq)] struct G2Point { @@ -16,6 +24,10 @@ struct G2Point { y1: u384, } +trait G2PointTrait { + fn is_on_curve(self: @G2Point, curve_index: usize) -> bool; +} + #[derive(Copy, Drop, Debug, PartialEq)] struct G1G2Pair { p: G1Point, @@ -215,6 +227,37 @@ fn get_b(curve_index: usize) -> u384 { return u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; } +fn get_b2(curve_index: usize) -> Result<(u384, u384), felt252> { + if curve_index == 0 { + return Result::Ok( + ( + u384 { + limb0: 27810052284636130223308486885, + limb1: 40153378333836448380344387045, + limb2: 3104278944836790958, + limb3: 0 + }, + u384 { + limb0: 70926583776874220189091304914, + limb1: 63498449372070794915149226116, + limb2: 42524369107353300, + limb3: 0 + } + ) + ); + } + if curve_index == 1 { + return Result::Ok( + ( + u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }, + u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 } + ) + ); + } else { + return Result::Err('Invalid curve index'); + } +} + // Returns a generator of the curve base field for a given curve index fn get_g(curve_index: usize) -> u384 { if curve_index == 0 { diff --git a/src/cairo/src/ec_ops.cairo b/src/cairo/src/ec_ops.cairo index 961390d8..e90cbab8 100644 --- a/src/cairo/src/ec_ops.cairo +++ b/src/cairo/src/ec_ops.cairo @@ -1,3 +1,4 @@ +use core::result::ResultTrait; use core::array::ArrayTrait; use core::circuit::{ RangeCheck96, AddMod, MulMod, u96, CircuitElement, CircuitInput, circuit_add, circuit_sub, @@ -5,9 +6,80 @@ use core::circuit::{ CircuitModulus, AddInputResultTrait, CircuitInputs, CircuitDefinition, CircuitData, CircuitInputAccumulator }; -use garaga::definitions::{get_a, get_b, get_p, get_g, get_min_one, G1Point}; +use garaga::definitions::{ + get_a, get_b, get_p, get_g, get_min_one, get_b2, G1Point, G1PointTrait, G2Point, G2PointTrait +}; use core::option::Option; use core::poseidon::hades_permutation; +use garaga::circuits::ec; +use garaga::utils; +use garaga::basic_field_ops::{sub_mod_p, neg_mod_p}; + +impl G1PointImpl of G1PointTrait { + fn is_on_curve(self: @G1Point, curve_index: usize) -> bool { + let (check) = ec::run_IS_ON_CURVE_G1_circuit( + *self, get_a(curve_index), get_b(curve_index), curve_index + ); + return (check == u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }); + } + fn is_infinity(self: @G1Point) -> bool { + return (*self.x == u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } + && *self.y == u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }); + } + fn update_hash_state( + self: @G1Point, s0: felt252, s1: felt252, s2: felt252 + ) -> (felt252, felt252, felt252) { + let base: felt252 = 79228162514264337593543950336; // 2**96 + let self = *self; + let in_1 = s0 + self.x.limb0.into() + base * self.x.limb1.into(); + let in_2 = s1 + self.x.limb2.into() + base * self.x.limb3.into(); + let (s0, s1, s2) = hades_permutation(in_1, in_2, s2); + let in_1 = s0 + self.y.limb0.into() + base * self.y.limb1.into(); + let in_2 = s1 + self.y.limb2.into() + base * self.y.limb3.into(); + let (s0, s1, s2) = hades_permutation(in_1, in_2, s2); + return (s0, s1, s2); + } +} + +impl G2PointImpl of G2PointTrait { + fn is_on_curve(self: @G2Point, curve_index: usize) -> bool { + let (b20, b21) = get_b2(curve_index).unwrap(); + let (check0, check1) = ec::run_IS_ON_CURVE_G2_circuit( + *self, get_a(curve_index), b20, b21, curve_index + ); + let zero = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + return (check0 == zero && check1 == zero); + } +} + +fn ec_safe_add(p: G1Point, q: G1Point, curve_index: usize) -> G1Point { + if p.is_infinity() { + return q; + } + if q.is_infinity() { + return p; + } + let modulus = get_p(curve_index); + let same_x = sub_mod_p(p.x, q.x, modulus) == u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + + if same_x { + let opposite_y = sub_mod_p( + p.y, neg_mod_p(q.y, modulus), modulus + ) == u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + if opposite_y { + return G1Point { + x: u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, + y: u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } + }; + } else { + let (res) = ec::run_DOUBLE_EC_POINT_circuit(p, get_a(curve_index), curve_index); + return res; + } + } else { + let (res) = ec::run_ADD_EC_POINT_circuit(p, q, curve_index); + return res; + } +} #[derive(Drop)] struct DerivePointFromXOutput { @@ -106,118 +178,342 @@ fn derive_ec_point_from_X( return G1Point { x: x_u384, y: y_last_attempt }; } -fn ec_add_unchecked(p1: G1Point, p2: G1Point, curve_index: usize) -> G1Point { - let in1 = CircuitElement::> {}; // px - let in2 = CircuitElement::> {}; // py - let in3 = CircuitElement::> {}; // qx - let in4 = CircuitElement::> {}; // qy - - let t0 = circuit_sub(in2, in4); - let t1 = circuit_sub(in1, in3); - let t2 = circuit_inverse(t1); - let t3 = circuit_mul(t0, t2); // slope - let t4 = circuit_mul(t3, t3); // slope^2 - - let t5 = circuit_sub(t4, in1); // slope^2 - px - let t6 = circuit_sub(t5, in3); // nx - - let t7 = circuit_sub(in1, t6); // px - nx - let t8 = circuit_mul(t3, t7); // slope * (px - nx) - let t9 = circuit_sub(t8, in2); // ny - - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) - .unwrap(); - let outputs = - match (t9,).new_inputs().next(p1.x).next(p1.y).next(p2.x).next(p2.y).done().eval(modulus) { - Result::Ok(outputs) => { outputs }, - Result::Err(_) => { panic!("Expected success") } - }; +// A function field element of the form : +// F(x,y) = a(x) + y b(x) +// Where a, b are rational functions of x. +// The rational functions are represented as polynomials in x with coefficients in F_p, starting +// from the constant term. +// No information about the degrees of the polynomials is stored here as they are derived +// implicitely from the MSM size. +#[derive(Drop, Debug, PartialEq)] +struct FunctionFelt { + a_num: Span, + a_den: Span, + b_num: Span, + b_den: Span, +} +#[derive(Drop, Debug, Copy, PartialEq)] +struct FunctionFeltEvaluations { + a_num: u384, + a_den: u384, + b_num: u384, + b_den: u384, +} - let x = outputs.get_output(t6); - let y = outputs.get_output(t9); +#[derive(Drop, Debug, Copy, PartialEq)] +struct SlopeInterceptOutput { + m_A0: u384, + b_A0: u384, + x_A2: u384, + y_A2: u384, + coeff0: u384, + coeff2: u384, +} - return G1Point { x: x, y: y }; +#[generate_trait] +impl FunctionFeltImpl of FunctionFeltTrait { + fn validate_degrees(self: @FunctionFelt, msm_size: usize) { + assert!((*self.a_num).len() == msm_size + 1, "a_num wrong degree for given msm size"); + assert!((*self.a_den).len() == msm_size + 2, "a_den wrong degree for given msm size"); + assert!((*self.b_num).len() == msm_size + 2, "b_num wrong degree for given msm size"); + assert!((*self.b_den).len() == msm_size + 5, "b_den wrong degree for given msm size"); + } + fn update_hash_state( + self: @FunctionFelt, s0: felt252, s1: felt252, s2: felt252 + ) -> (felt252, felt252, felt252) { + let (s0, s1, s2) = utils::hash_u384_transcript(*self.a_num, s0, s1, s2); + let (s0, s1, s2) = utils::hash_u384_transcript(*self.a_den, s0, s1, s2); + let (s0, s1, s2) = utils::hash_u384_transcript(*self.b_num, s0, s1, s2); + let (s0, s1, s2) = utils::hash_u384_transcript(*self.b_den, s0, s1, s2); + return (s0, s1, s2); + } } +fn msm_g1( + points: Span, + scalars: Span, + Q_low: G1Point, + Q_high: G1Point, + Q_high_shifted: G1Point, + SumDlogDivLow: FunctionFelt, + SumDlogDivHigh: FunctionFelt, + SumDlogDivHighShifted: FunctionFelt, + y_last_attempt: u384, + g_rhs_sqrt: Array, + curve_index: usize +) -> G1Point { + let n = scalars.len(); + assert!(n == points.len(), "scalars and points length mismatch"); + let b = get_b(curve_index); + assert!( + b != u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, + "b must be non-zero to correctly encode point at infinity" + ); -fn ec_add_unchecked2(mut input: Array, curve_index: usize) -> G1Point { - let in1 = CircuitElement::> {}; // px - let in2 = CircuitElement::> {}; // py - let in3 = CircuitElement::> {}; // qx - let in4 = CircuitElement::> {}; // qy + if n == 0 { + return G1Point { + x: u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }, + y: u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 } + }; + } + + // Check result points are either on curve or the point at infinity + assert!( + Q_low.is_on_curve(curve_index) || Q_low.is_infinity(), + "Q_low is neither on curve nor the point at infinity" + ); + assert!( + Q_high.is_on_curve(curve_index) || Q_high.is_infinity(), + "Q_high is neither on curve nor the point at infinity" + ); + assert!( + Q_high_shifted.is_on_curve(curve_index) || Q_high_shifted.is_infinity(), + "Q_high_shifted is neither on curve nor the point at infinity" + ); - let t0 = circuit_sub(in2, in4); - let t1 = circuit_sub(in1, in3); - let t2 = circuit_inverse(t1); - let t3 = circuit_mul(t0, t2); // slope - let t4 = circuit_mul(t3, t3); // slope^2 + // Validate the degrees of the functions field elements given the msm size + SumDlogDivLow.validate_degrees(n); + SumDlogDivHigh.validate_degrees(n); + SumDlogDivHighShifted.validate_degrees(n); - let t5 = circuit_sub(t4, in1); // slope^2 - px - let t6 = circuit_sub(t5, in3); // nx + // Hash everything to obtain a x coordinate. - let t7 = circuit_sub(in1, t6); // px - nx - let t8 = circuit_mul(t3, t7); // slope * (px - nx) - let t9 = circuit_sub(t8, in2); // ny + let (s0, s1, s2): (felt252, felt252, felt252) = ( + 'MSM' + curve_index.into() + n.into(), 0, 1 + ); // Init Sponge state - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) - .unwrap(); + let (s0, s1, s2) = SumDlogDivLow.update_hash_state(s0, s1, s2); + let (s0, s1, s2) = SumDlogDivHigh.update_hash_state(s0, s1, s2); + let (s0, s1, s2) = SumDlogDivHighShifted.update_hash_state(s0, s1, s2); - let mut circuit_inputs = (t9,).new_inputs(); + let mut s0 = s0; + let mut s1 = s1; + let mut s2 = s2; - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); + // Check input points are on curve and hash them at the same time. + for point in points { + assert!(point.is_on_curve(curve_index), "One of the points is not on curve"); + let (_s0, _s1, _s2) = point.update_hash_state(s0, s1, s2); + s0 = _s0; + s1 = _s1; + s2 = _s2; }; - let outputs = match circuit_inputs.done().eval(modulus) { - Result::Ok(outputs) => { outputs }, - Result::Err(_) => { panic!("Expected success") } + // Hash result points + let (s0, s1, s2) = Q_low.update_hash_state(s0, s1, s2); + let (s0, s1, s2) = Q_high.update_hash_state(s0, s1, s2); + let (s0, s1, s2) = Q_high_shifted.update_hash_state(s0, s1, s2); + + // Hash scalars + let mut s0 = s0; + let mut s1 = s1; + let mut s2 = s2; + for scalar in scalars { + let (_s0, _s1, _s2) = core::poseidon::hades_permutation( + s0 + (*scalar.low).into(), s1 + (*scalar.high).into(), s2 + ); + s0 = _s0; + s1 = _s1; + s2 = _s2; }; - let x = outputs.get_output(t6); - let y = outputs.get_output(t9); - return G1Point { x: x, y: y }; -} + let random_point: G1Point = derive_ec_point_from_X(s0, y_last_attempt, g_rhs_sqrt, curve_index); -fn get_add_ec_point_circuit(mut input: Array, curve_index: usize) -> Array { - // INPUT stack - let in0 = CircuitElement::> {}; - let in1 = CircuitElement::> {}; - let in2 = CircuitElement::> {}; - let in3 = CircuitElement::> {}; - let t0 = circuit_sub(in1, in3); - let t1 = circuit_sub(in0, in2); - let t2 = circuit_inverse(t1); - let t3 = circuit_mul(t0, t2); - let t4 = circuit_mul(t3, t3); - let t5 = circuit_sub(t4, in0); - let t6 = circuit_sub(t5, in2); - let t7 = circuit_sub(in0, t6); - let t8 = circuit_mul(t3, t7); - let t9 = circuit_sub(t8, in1); + // Get slope, intercept and other constant from random point + let (mb): (SlopeInterceptOutput,) = ec::run_SLOPE_INTERCEPT_SAME_POINT_circuit( + random_point, get_a(curve_index), curve_index + ); - let p = get_p(curve_index); - let modulus = TryInto::<_, CircuitModulus>::try_into([p.limb0, p.limb1, p.limb2, p.limb3]) - .unwrap(); + // Get positive and negative multiplicities of low and high part of scalars + let (epns_low, epns_high) = utils::u256_array_to_low_high_epns(scalars); + + // Hardcoded epns for 2^128 + let epns_shited: Array<(felt252, felt252, felt252, felt252)> = array![ + (5279154705627724249993186093248666011, 345561521626566187713367793525016877467, -1, -1) + ]; + + // Verify Q_low = sum(scalar_low * P for scalar_low,P in zip(scalars_low, points)) + zk_ecip_check(points, epns_low, Q_low, n, mb, SumDlogDivLow, random_point, curve_index); + // Verify Q_high = sum(scalar_high * P for scalar_high,P in zip(scalars_high, points)) + zk_ecip_check(points, epns_high, Q_high, n, mb, SumDlogDivHigh, random_point, curve_index); + // Verify Q_high_shifted = 2^128 * Q_high + zk_ecip_check( + points, epns_shited, Q_high_shifted, 1, mb, SumDlogDivHighShifted, random_point, curve_index + ); - let mut circuit_inputs = (t9,).new_inputs(); + // Return Q_low + Q_high_shifted = Q_low + 2^128 * Q_high = Σ(ki * Pi) + return ec_safe_add(Q_low, Q_high_shifted, curve_index); +} - while let Option::Some(val) = input.pop_front() { - circuit_inputs = circuit_inputs.next(val); - }; +fn zk_ecip_check( + points: Span, + epns: Array<(felt252, felt252, felt252, felt252)>, + Q_result: G1Point, + n: usize, + mb: SlopeInterceptOutput, + sum_dlog_div: FunctionFelt, + random_point: G1Point, + curve_index: usize +) { + let lhs = compute_lhs_ecip( + sum_dlog_div: sum_dlog_div, + A0: random_point, + A2: G1Point { x: mb.x_A2, y: mb.y_A2 }, + coeff0: mb.coeff0, + coeff2: mb.coeff2, + msm_size: n, + curve_index: curve_index + ); + let rhs = compute_rhs_ecip( + points: points, + m_A0: mb.m_A0, + b_A0: mb.b_A0, + x_A0: random_point.x, + epns: epns, + Q_result: Q_result, + curve_index: curve_index + ); + assert!(lhs == rhs, "LHS and RHS are not equal"); +} - let outputs = match circuit_inputs.done().eval(modulus) { - Result::Ok(outputs) => { outputs }, - Result::Err(_) => { panic!("Expected success") } +fn compute_lhs_ecip( + sum_dlog_div: FunctionFelt, + A0: G1Point, + A2: G1Point, + coeff0: u384, + coeff2: u384, + msm_size: usize, + curve_index: usize +) -> u384 { + let case = msm_size - 1; + let (res) = match case { + 0 => (ec::run_EVAL_FUNCTION_CHALLENGE_DUPL_1_circuit( + A0, + A2, + coeff0, + coeff2, + sum_dlog_div.a_num, + sum_dlog_div.a_den, + sum_dlog_div.b_num, + sum_dlog_div.b_den, + curve_index + )), + 1 => ec::run_EVAL_FUNCTION_CHALLENGE_DUPL_2_circuit( + A0, + A2, + coeff0, + coeff2, + sum_dlog_div.a_num, + sum_dlog_div.a_den, + sum_dlog_div.b_num, + sum_dlog_div.b_den, + curve_index + ), + 2 => ec::run_EVAL_FUNCTION_CHALLENGE_DUPL_3_circuit( + A0, + A2, + coeff0, + coeff2, + sum_dlog_div.a_num, + sum_dlog_div.a_den, + sum_dlog_div.b_num, + sum_dlog_div.b_den, + curve_index + ), + 3 => ec::run_EVAL_FUNCTION_CHALLENGE_DUPL_4_circuit( + A0, + A2, + coeff0, + coeff2, + sum_dlog_div.a_num, + sum_dlog_div.a_den, + sum_dlog_div.b_num, + sum_dlog_div.b_den, + curve_index + ), + _ => { + let (_f_A0, _f_A2, _xA0_power, _xA2_power) = + ec::run_INIT_FUNCTION_CHALLENGE_DUPL_5_circuit( + A0.x, + A2.x, + sum_dlog_div.a_num.slice(0, 5 + 1), + sum_dlog_div.a_den.slice(0, 5 + 2), + sum_dlog_div.b_num.slice(0, 5 + 2), + sum_dlog_div.b_den.slice(0, 5 + 5), + curve_index + ); + let mut f_A0 = _f_A0; + let mut f_A2 = _f_A2; + let mut xA0_power = _xA0_power; + let mut xA2_power = _xA2_power; + let mut i = 5; + while i != msm_size { + let (_f_A0, _f_A2, _xA0_power, _xA2_power) = + ec::run_ACC_FUNCTION_CHALLENGE_DUPL_circuit( + f_A0, + f_A2, + A0.x, + A2.x, + xA0_power, + xA2_power, + *sum_dlog_div.a_num.at(i + 1), + *sum_dlog_div.a_den.at(i + 2), + *sum_dlog_div.b_num.at(i + 2), + *sum_dlog_div.b_den.at(i + 5), + curve_index + ); + f_A0 = f_A0; + f_A2 = f_A2; + xA0_power = xA0_power; + xA2_power = xA2_power; + i += 1; + }; + ec::run_FINALIZE_FUNCTION_CHALLENGE_DUPL_circuit( + f_A0, f_A2, A0.y, A2.y, coeff0, coeff2, curve_index + ) + } }; - let o0 = outputs.get_output(t6); - let o1 = outputs.get_output(t9); - - let res = array![o0, o1]; return res; } +fn compute_rhs_ecip( + points: Span, + m_A0: u384, + b_A0: u384, + x_A0: u384, + epns: Array<(felt252, felt252, felt252, felt252)>, + Q_result: G1Point, + curve_index: usize +) -> u384 { + let mut basis_sum: u384 = u384 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + let mut i = 0; + let n = points.len(); + while i != n { + let (ep, en, sp, sn) = *epns.at(i); + let (_basis_sum) = ec::run_ACCUMULATE_EVAL_POINT_CHALLENGE_SIGNED_circuit( + basis_sum, + m_A0, + b_A0, + x_A0, + *points.at(i), + ep.into(), + en.into(), + utils::sign_to_u384(sp, curve_index), + utils::sign_to_u384(sn, curve_index), + curve_index + ); + basis_sum = _basis_sum; + i += 1; + }; + if Q_result.is_infinity() { + return basis_sum; + } else { + let (rhs) = ec::run_RHS_FINALIZE_ACC_circuit( + basis_sum, m_A0, b_A0, x_A0, Q_result, curve_index + ); + return rhs; + } +} #[cfg(test)] mod tests { @@ -230,128 +526,7 @@ mod tests { CircuitData, CircuitInputAccumulator }; - use super::{ - ec_add_unchecked, ec_add_unchecked2, get_add_ec_point_circuit, G1Point, - derive_ec_point_from_X - }; - - #[test] - fn test_ec_add_unchecked() { - let p1 = G1Point { - x: u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }, - y: u384 { limb0: 2, limb1: 0, limb2: 0, limb3: 0 } - }; - let p2 = G1Point { - x: u384 { - limb0: 6972010542290859298145161171, - limb1: 48130984231937642362735957673, - limb2: 217937391675185666, - limb3: 0 - }, - y: u384 { - limb0: 70354117060174814309938406084, - limb1: 71651066881622725552431866953, - limb2: 1580046089645096082, - limb3: 0 - } - }; - let p3 = ec_add_unchecked(p1, p2, 0); - assert_eq!( - p3, - G1Point { - x: u384 { - limb0: 6722715950901854229040049136, - limb1: 75516999847165085857686607943, - limb2: 534168702278167103, - limb3: 0 - }, - y: u384 { - limb0: 3593358890951276345950085729, - limb1: 26402767470382383152362316724, - limb2: 3078097915416712233, - limb3: 0 - } - } - ); - } - - #[test] - fn test_ec_add_unchecked2() { - let inputs = array![ - u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 2, limb1: 0, limb2: 0, limb3: 0 }, - u384 { - limb0: 6972010542290859298145161171, - limb1: 48130984231937642362735957673, - limb2: 217937391675185666, - limb3: 0 - }, - u384 { - limb0: 70354117060174814309938406084, - limb1: 71651066881622725552431866953, - limb2: 1580046089645096082, - limb3: 0 - } - ]; - - let p3 = ec_add_unchecked2(inputs, 0); - assert_eq!( - p3, - G1Point { - x: u384 { - limb0: 6722715950901854229040049136, - limb1: 75516999847165085857686607943, - limb2: 534168702278167103, - limb3: 0 - }, - y: u384 { - limb0: 3593358890951276345950085729, - limb1: 26402767470382383152362316724, - limb2: 3078097915416712233, - limb3: 0 - } - } - ); - } - - #[test] - fn test_ec_add_unchecked3() { - let inputs = array![ - u384 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }, - u384 { limb0: 2, limb1: 0, limb2: 0, limb3: 0 }, - u384 { - limb0: 6972010542290859298145161171, - limb1: 48130984231937642362735957673, - limb2: 217937391675185666, - limb3: 0 - }, - u384 { - limb0: 70354117060174814309938406084, - limb1: 71651066881622725552431866953, - limb2: 1580046089645096082, - limb3: 0 - } - ]; - - let p3 = get_add_ec_point_circuit(inputs, 0); - assert_eq!( - p3, - array![ - u384 { - limb0: 6722715950901854229040049136, - limb1: 75516999847165085857686607943, - limb2: 534168702278167103, - limb3: 0 - }, - u384 { - limb0: 3593358890951276345950085729, - limb1: 26402767470382383152362316724, - limb2: 3078097915416712233, - limb3: 0 - } - ] - ); - } + use super::{G1Point, derive_ec_point_from_X}; #[test] fn derive_ec_point_from_X_BN254_0() { @@ -743,3 +918,4 @@ mod tests { assert!(result.y == y); } } + diff --git a/src/cairo/src/utils.cairo b/src/cairo/src/utils.cairo index dc2ca9ad..89415979 100644 --- a/src/cairo/src/utils.cairo +++ b/src/cairo/src/utils.cairo @@ -90,6 +90,17 @@ pub fn neg_3_base_le(scalar: u128) -> Array { return digits; } +fn u256_array_to_low_high_epns( + scalars: Span +) -> (Array<(felt252, felt252, felt252, felt252)>, Array<(felt252, felt252, felt252, felt252)>) { + let mut epns_low: Array<(felt252, felt252, felt252, felt252)> = ArrayTrait::new(); + let mut epns_high: Array<(felt252, felt252, felt252, felt252)> = ArrayTrait::new(); + for scalar in scalars { + epns_low.append(scalar_to_base_neg3_le(*scalar.low)); + epns_high.append(scalar_to_base_neg3_le(*scalar.high)); + }; + return (epns_low, epns_high); +} // From a 128 bit scalar, returns the positive and negative multiplicities of the scalar in base // (-3) // scalar = sum(digits[i] * (-3)^i for i in [0, 81])