diff --git a/hydra/garaga/modulo_circuit_structs.py b/hydra/garaga/modulo_circuit_structs.py index 1a6a7ff1..245b6689 100644 --- a/hydra/garaga/modulo_circuit_structs.py +++ b/hydra/garaga/modulo_circuit_structs.py @@ -1015,22 +1015,45 @@ def extract_from_circuit_output( ) -> str: raise NotImplementedError("Never used in practice") + def serialize_input_signature(self) -> str: + bits = self.bits + if bits <= 288: + return f"{self.name}:MillerLoopResultScalingFactor" + else: + return f"{self.name}:MillerLoopResultScalingFactor" + def dump_to_circuit_input(self) -> str: code = "" + bits = self.bits + if bits <= 288: + next_fn = "next_u288" + else: + next_fn = "next_2" for mem_name in self.members_names: - code += f"circuit_inputs = circuit_inputs.next_2({self.name}.{mem_name});\n" + code += ( + f"circuit_inputs = circuit_inputs.{next_fn}({self.name}.{mem_name});\n" + ) return code 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))])}}}" + bits = self.bits + if bits <= 288: + curve_id = 0 + else: + curve_id = 1 + raw_struct = f"{self.__class__.__name__}{{{','.join([f'{self.members_names[i]}: {int_to_u2XX(self.elmts[i].value, curve_id=curve_id)}' for i in range(len(self))])}}}" if raw: return raw_struct else: return f"let {self.name}:{self.__class__.__name__} = {raw_struct};\n" def _serialize_to_calldata(self) -> list[int]: - return io.bigint_split_array(self.elmts, prepend_length=False) + bits = self.bits + if bits <= 288: + return io.bigint_split_array(self.elmts, n_limbs=3, prepend_length=False) + else: + return io.bigint_split_array(self.elmts, n_limbs=4, prepend_length=False) def __len__(self) -> int: if self.elmts is not None: diff --git a/src/src/circuits/multi_pairing_check.cairo b/src/src/circuits/multi_pairing_check.cairo index 494975b5..b0acf040 100644 --- a/src/src/circuits/multi_pairing_check.cairo +++ b/src/src/circuits/multi_pairing_check.cairo @@ -2213,7 +2213,7 @@ fn run_BLS12_381_MP_CHECK_INIT_BIT_3P_2F_circuit( return (Q0, new_lhs); } fn run_BLS12_381_MP_CHECK_PREPARE_LAMBDA_ROOT_circuit( - lambda_root_inverse: E12D, z: u384, scaling_factor: MillerLoopResultScalingFactor + lambda_root_inverse: E12D, z: u384, scaling_factor: MillerLoopResultScalingFactor ) -> (u384, u384, u384) { // CONSTANT stack let in0 = CE::> {}; // 0x0 @@ -5334,7 +5334,7 @@ fn run_BN254_MP_CHECK_INIT_BIT_3P_2F_circuit( fn run_BN254_MP_CHECK_PREPARE_LAMBDA_ROOT_circuit( lambda_root: E12D, z: u384, - scaling_factor: MillerLoopResultScalingFactor, + scaling_factor: MillerLoopResultScalingFactor, c_inv: E12D, c_0: u384 ) -> (u384, u384, u384, u384, u384, u384, u384) { @@ -5678,12 +5678,12 @@ fn run_BN254_MP_CHECK_PREPARE_LAMBDA_ROOT_circuit( circuit_inputs = circuit_inputs.next_u288(lambda_root.w10); // in55 circuit_inputs = circuit_inputs.next_u288(lambda_root.w11); // in56 circuit_inputs = circuit_inputs.next_2(z); // in57 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w0); // in58 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w2); // in59 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w4); // in60 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w6); // in61 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w8); // in62 - circuit_inputs = circuit_inputs.next_2(scaling_factor.w10); // in63 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w0); // in58 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w2); // in59 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w4); // in60 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w6); // in61 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w8); // in62 + circuit_inputs = circuit_inputs.next_u288(scaling_factor.w10); // in63 circuit_inputs = circuit_inputs.next_u288(c_inv.w0); // in64 circuit_inputs = circuit_inputs.next_u288(c_inv.w1); // in65 circuit_inputs = circuit_inputs.next_u288(c_inv.w2); // in66 diff --git a/src/src/definitions.cairo b/src/src/definitions.cairo index fbb14622..43a15fc8 100644 --- a/src/src/definitions.cairo +++ b/src/src/definitions.cairo @@ -556,13 +556,13 @@ impl E12DSerde288 of Serde> { } #[derive(Copy, Drop, Debug, PartialEq, Serde)] -struct MillerLoopResultScalingFactor { - w0: u384, - w2: u384, - w4: u384, - w6: u384, - w8: u384, - w10: u384, +struct MillerLoopResultScalingFactor { + w0: T, + w2: T, + w4: T, + w6: T, + w8: T, + w10: T, } #[derive(Copy, Drop, Debug, PartialEq, Serde)] struct E12DMulQuotient { diff --git a/src/src/groth16.cairo b/src/src/groth16.cairo index 7c1045a0..85669393 100644 --- a/src/src/groth16.cairo +++ b/src/src/groth16.cairo @@ -253,7 +253,7 @@ fn multi_pairing_check_bn254_3P_2F_with_extra_miller_loop_result( let (s0, s1, s2) = hashing::hash_G1G2Pair(pair2, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u288(mpcheck_hint.lambda_root, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u288(mpcheck_hint.lambda_root_inverse, s0, s1, s2); - let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor(mpcheck_hint.w, s0, s1, s2); + let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor_u288(mpcheck_hint.w, s0, s1, s2); // Hash Ris to obtain base random coefficient c0 let (s0, s1, s2) = hashing::hash_E12D_u288_transcript(mpcheck_hint.Ris, s0, s1, s2); @@ -514,7 +514,7 @@ fn multi_pairing_check_bls12_381_3P_2F_with_extra_miller_loop_result( let (s0, s1, s2) = hashing::hash_G1G2Pair(pair1, s0, s1, s2); let (s0, s1, s2) = hashing::hash_G1G2Pair(pair2, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u384(hint.lambda_root_inverse, s0, s1, s2); - let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor(hint.w, s0, s1, s2); + let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor_u384(hint.w, s0, s1, s2); // Hash Ris to obtain base random coefficient c0 let (s0, s1, s2) = hashing::hash_E12D_u384_transcript(hint.Ris, s0, s1, s2); let mut c_i: u384 = s1.into(); diff --git a/src/src/pairing_check.cairo b/src/src/pairing_check.cairo index 32bf416b..b7fae0dc 100644 --- a/src/src/pairing_check.cairo +++ b/src/src/pairing_check.cairo @@ -41,7 +41,7 @@ use garaga::basic_field_ops::{compute_yInvXnegOverY_BN254, compute_yInvXnegOverY struct MPCheckHintBN254 { lambda_root: E12D, lambda_root_inverse: E12D, - w: MillerLoopResultScalingFactor, + w: MillerLoopResultScalingFactor, Ris: Span>, big_Q: Array, } @@ -49,7 +49,7 @@ struct MPCheckHintBN254 { #[derive(Drop, Serde)] struct MPCheckHintBLS12_381 { lambda_root_inverse: E12D, - w: MillerLoopResultScalingFactor, + w: MillerLoopResultScalingFactor, Ris: Span>, big_Q: Array, } @@ -70,7 +70,7 @@ fn multi_pairing_check_bn254_2P_2F( let (s0, s1, s2) = hashing::hash_G1G2Pair(pair1, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u288(hint.lambda_root, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u288(hint.lambda_root_inverse, s0, s1, s2); - let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor(hint.w, s0, s1, s2); + let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor_u288(hint.w, s0, s1, s2); // Hash Ris to obtain base random coefficient c0 let (s0, s1, s2) = hashing::hash_E12D_u288_transcript(hint.Ris, s0, s1, s2); let mut c_i: u384 = s1.into(); @@ -233,7 +233,7 @@ fn multi_pairing_check_bls12_381_2P_2F( let (s0, s1, s2) = hashing::hash_G1G2Pair(pair0, s0, s1, s2); let (s0, s1, s2) = hashing::hash_G1G2Pair(pair1, s0, s1, s2); let (s0, s1, s2) = hashing::hash_E12D_u384(hint.lambda_root_inverse, s0, s1, s2); - let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor(hint.w, s0, s1, s2); + let (s0, s1, s2) = hashing::hash_MillerLoopResultScalingFactor_u384(hint.w, s0, s1, s2); // Hash Ris to obtain base random coefficient c0 let (s0, s1, s2) = hashing::hash_E12D_u384_transcript(hint.Ris, s0, s1, s2); diff --git a/src/src/tests/pairing_tests.cairo b/src/src/tests/pairing_tests.cairo index 39d9fbf9..2a582fb5 100644 --- a/src/src/tests/pairing_tests.cairo +++ b/src/src/tests/pairing_tests.cairo @@ -4097,12 +4097,12 @@ mod pairing_tests { } }, w: MillerLoopResultScalingFactor { - w0: u384 { limb0: 0x1, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w2: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w4: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w6: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w8: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w10: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 } + w0: u288 { limb0: 0x1, limb1: 0x0, limb2: 0x0 }, + w2: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w4: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w6: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w8: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w10: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 } }, Ris: array![ E12D { @@ -11917,12 +11917,12 @@ mod pairing_tests { } }, w: MillerLoopResultScalingFactor { - w0: u384 { limb0: 0x1, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w2: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w4: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w6: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w8: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, - w10: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 } + w0: u288 { limb0: 0x1, limb1: 0x0, limb2: 0x0 }, + w2: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w4: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w6: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w8: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 }, + w10: u288 { limb0: 0x0, limb1: 0x0, limb2: 0x0 } }, Ris: array![ E12D { diff --git a/src/src/utils/hashing.cairo b/src/src/utils/hashing.cairo index c54fa3b8..f8711137 100644 --- a/src/src/utils/hashing.cairo +++ b/src/src/utils/hashing.cairo @@ -177,8 +177,8 @@ pub fn hash_E12D_u288( // Apply sponge construction to a MillerLoopResultScalingFactor element from an initial state (s0, // s1, s2) -pub fn hash_MillerLoopResultScalingFactor( - elmt: MillerLoopResultScalingFactor, mut s0: felt252, mut s1: felt252, mut s2: felt252 +pub fn hash_MillerLoopResultScalingFactor_u384( + elmt: MillerLoopResultScalingFactor, mut s0: felt252, mut s1: felt252, mut s2: felt252 ) -> (felt252, felt252, felt252) { let base: felt252 = 79228162514264337593543950336; // 2**96 @@ -203,6 +203,32 @@ pub fn hash_MillerLoopResultScalingFactor( return (_s0, _s1, _s2); } +pub fn hash_MillerLoopResultScalingFactor_u288( + elmt: MillerLoopResultScalingFactor, mut s0: felt252, mut s1: felt252, mut s2: felt252 +) -> (felt252, felt252, felt252) { + let base: felt252 = 79228162514264337593543950336; // 2**96 + + let in_1 = s0 + elmt.w0.limb0.into() + base * elmt.w0.limb1.into(); + let in_2 = s1 + elmt.w0.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, s2); + let in_1 = _s0 + elmt.w2.limb0.into() + base * elmt.w2.limb1.into(); + let in_2 = _s1 + elmt.w2.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, _s2); + let in_1 = _s0 + elmt.w4.limb0.into() + base * elmt.w4.limb1.into(); + let in_2 = _s1 + elmt.w4.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, _s2); + let in_1 = _s0 + elmt.w6.limb0.into() + base * elmt.w6.limb1.into(); + let in_2 = _s1 + elmt.w6.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, _s2); + let in_1 = _s0 + elmt.w8.limb0.into() + base * elmt.w8.limb1.into(); + let in_2 = _s1 + elmt.w8.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, _s2); + let in_1 = _s0 + elmt.w10.limb0.into() + base * elmt.w10.limb1.into(); + let in_2 = _s1 + elmt.w10.limb2.into(); + let (_s0, _s1, _s2) = hades_permutation(in_1, in_2, _s2); + return (_s0, _s1, _s2); +} + // Apply sponge construction to a sequence of E12D elements from an initial state (s0, s1, s2) pub fn hash_E12D_u384_transcript( transcript: Span>, mut s0: felt252, mut s1: felt252, mut s2: felt252