From 622d35a40693084d5a3d74f0caa6e539bc00454a Mon Sep 17 00:00:00 2001 From: Daniele Di Tullio Date: Tue, 1 Apr 2025 18:35:13 +0200 Subject: [PATCH 1/6] Fixed the Poseidon2 BabyBear gadget by considering the actual CircuitConfig --- field/src/fft.rs | 2 +- plonky2/src/gates/poseidon2_babybear.rs | 33 ++++++++++++--------- plonky2/src/hash/poseidon2_babybear.rs | 3 +- plonky2/src/recursion/recursive_verifier.rs | 2 +- rust-toolchain | 2 +- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/field/src/fft.rs b/field/src/fft.rs index 0e0843118..4cf94be43 100644 --- a/field/src/fft.rs +++ b/field/src/fft.rs @@ -226,7 +226,7 @@ mod tests { // "random", the last degree_padded-degree of them are zero. let coeffs = (0..degree) .map(|i| F::from_canonical_usize(i * 1337 % 100)) - .chain(core::iter::repeat(F::zero()).take(degree_padded - degree)) + .chain(core::iter::repeat_n(F::zero(), degree_padded - degree)) .collect::>(); assert_eq!(coeffs.len(), degree_padded); let coefficients = PolynomialCoeffs { coeffs }; diff --git a/plonky2/src/gates/poseidon2_babybear.rs b/plonky2/src/gates/poseidon2_babybear.rs index c6bda73d3..58f766937 100644 --- a/plonky2/src/gates/poseidon2_babybear.rs +++ b/plonky2/src/gates/poseidon2_babybear.rs @@ -52,21 +52,20 @@ const NON_ROUTED_WIRES_PER_OP: usize = SPONGE_CAPACITY + SPONGE_WIDTH * (N_FULL_ROUNDS_TOTAL - 1) + N_PARTIAL_ROUNDS; impl, const D: usize> Poseidon2BabyBearGate { - pub fn new() -> Self { - Self::new_from_config(&CircuitConfig::standard_recursion_config_bb_wide()) + fn new_with_num_ops(num_ops: usize) -> Self { + Self { + num_ops, + _phantom: PhantomData, + } } - - pub fn new_from_config(config: &CircuitConfig) -> Self { + pub fn new(config: &CircuitConfig) -> Self { if BabyBear::ORDER_U64 != F::ORDER_U64 { panic!("The Poseidon2 BabyBear gate can be used only for the BabyBear field!") } let wires_per_op = ROUTED_WIRES_PER_OP + NON_ROUTED_WIRES_PER_OP; let num_ops = (config.num_wires / wires_per_op).min(config.num_routed_wires / ROUTED_WIRES_PER_OP); - Self { - num_ops, - _phantom: PhantomData, - } + Self::new_with_num_ops(num_ops) } /***************** START ROUTED WIRES ***********************/ /// The wire index for the `i`th input to the permutation. @@ -160,7 +159,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us _src: &mut Buffer, _common_data: &CommonCircuitData, ) -> IoResult { - Ok(Poseidon2BabyBearGate::new()) + Ok(Poseidon2BabyBearGate::new(&_common_data.config)) } fn complete_wires( @@ -470,6 +469,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us .map(|op| { WitnessGeneratorRef::new( Poseidon2BabyBearGenerator:: { + num_ops: self.num_ops, row, op, _phantom: PhantomData, @@ -504,6 +504,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us #[derive(Debug, Default)] pub struct Poseidon2BabyBearGenerator, const D: usize> { + num_ops: usize, row: usize, op: usize, _phantom: PhantomData, @@ -542,7 +543,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us ))); debug_assert!(swap_value == F::zero() || swap_value == F::one()); - let gate = Poseidon2BabyBearGate::::new(); + let gate = Poseidon2BabyBearGate::::new_with_num_ops(self.num_ops); for i in 0..SPONGE_CAPACITY { let delta_i = swap_value * (state[i + SPONGE_CAPACITY] - state[i]); out_buffer.set_wire(local_wire(gate.wire_delta(self.op, i)), delta_i); @@ -620,9 +621,11 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us src: &mut Buffer, _common_data: &CommonCircuitData, ) -> IoResult { + let num_ops = src.read_usize()?; let row = src.read_usize()?; let op = src.read_usize()?; Ok(Self { + num_ops, row, op, _phantom: PhantomData, @@ -888,9 +891,9 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config_bb_wide(); - let mut builder = CircuitBuilder::new(config); + let mut builder = CircuitBuilder::new(config.clone()); type Gate = Poseidon2BabyBearGate; - let gate = Gate::new(); + let gate = Gate::new(&config); let (row, op) = builder.find_slot(gate, &[], &[]); let circuit = builder.build_prover::(); @@ -932,7 +935,8 @@ mod tests { #[test] fn low_degree() { type F = BabyBear; - let gate = Poseidon2BabyBearGate::::new(); + let gate = + Poseidon2BabyBearGate::::new(&CircuitConfig::standard_recursion_config_bb_wide()); test_low_degree::, 4, 8>(gate) } @@ -942,7 +946,8 @@ mod tests { type C = Poseidon2BabyBearConfig; const NUM_HASH_OUT_ELTS: usize = BABYBEAR_NUM_HASH_OUT_ELTS; type F = >::F; - let gate = Poseidon2BabyBearGate::::new(); + let gate = + Poseidon2BabyBearGate::::new(&CircuitConfig::standard_recursion_config_bb_wide()); test_eval_fns::(gate) } diff --git a/plonky2/src/hash/poseidon2_babybear.rs b/plonky2/src/hash/poseidon2_babybear.rs index 89b2a6cc9..b6e0282ce 100644 --- a/plonky2/src/hash/poseidon2_babybear.rs +++ b/plonky2/src/hash/poseidon2_babybear.rs @@ -189,7 +189,8 @@ impl AlgebraicHasher for Poseidon2BabyBearHash { F: RichField + HasExtension, >::Extension: TwoAdicField, { - let gate_type: Poseidon2BabyBearGate = Poseidon2BabyBearGate::::new(); + let gate_type: Poseidon2BabyBearGate = + Poseidon2BabyBearGate::::new(&builder.config); let (row, op) = builder.find_slot(gate_type.clone(), &[], &[]); let swap_wire = Poseidon2BabyBearGate::::wire_swap(op); diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index 7ef598947..41a38ec0b 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -677,7 +677,7 @@ where { builder.add_gate_to_gate_set(GateRef::new(PoseidonGate::new())) } BabyBear::ORDER_U64 => { - builder.add_gate_to_gate_set(GateRef::new(Poseidon2BabyBearGate::new())) + builder.add_gate_to_gate_set(GateRef::new(Poseidon2BabyBearGate::new(config))) } _ => panic!(), }; diff --git a/rust-toolchain b/rust-toolchain index 07ade694b..91a24ccfe 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly \ No newline at end of file +nightly-2025-03-12 \ No newline at end of file From 297a8887cad9e45e616873406c613e074f69d29c Mon Sep 17 00:00:00 2001 From: Daniele Di Tullio Date: Wed, 2 Apr 2025 12:23:43 +0200 Subject: [PATCH 2/6] Fixed cargo clippy and made Poseidon2BabyBear methods static --- field/src/prime_field_testing.rs | 2 +- plonky2/src/gates/poseidon2_babybear.rs | 161 +++++++++++++++++------- 2 files changed, 115 insertions(+), 48 deletions(-) diff --git a/field/src/prime_field_testing.rs b/field/src/prime_field_testing.rs index a00f7a0bf..812d3eb9b 100644 --- a/field/src/prime_field_testing.rs +++ b/field/src/prime_field_testing.rs @@ -147,7 +147,7 @@ macro_rules! test_prime_field_arithmetic { type F = $field; let (a, b) = ( - F::from_canonical_u64((F::ORDER_U64 + 1u64) / 2u64), + F::from_canonical_u64((F::ORDER_U64).div_ceil(2u64)), F::two(), ); let x = a * b; diff --git a/plonky2/src/gates/poseidon2_babybear.rs b/plonky2/src/gates/poseidon2_babybear.rs index 58f766937..70c05b1e5 100644 --- a/plonky2/src/gates/poseidon2_babybear.rs +++ b/plonky2/src/gates/poseidon2_babybear.rs @@ -58,13 +58,16 @@ impl, const D: usize> Poseidon2BabyBearGate _phantom: PhantomData, } } + fn num_ops(config: &CircuitConfig) -> usize { + let wires_per_op = ROUTED_WIRES_PER_OP + NON_ROUTED_WIRES_PER_OP; + (config.num_wires / wires_per_op).min(config.num_routed_wires / ROUTED_WIRES_PER_OP) + } + pub fn new(config: &CircuitConfig) -> Self { if BabyBear::ORDER_U64 != F::ORDER_U64 { panic!("The Poseidon2 BabyBear gate can be used only for the BabyBear field!") } - let wires_per_op = ROUTED_WIRES_PER_OP + NON_ROUTED_WIRES_PER_OP; - let num_ops = - (config.num_wires / wires_per_op).min(config.num_routed_wires / ROUTED_WIRES_PER_OP); + let num_ops = Self::num_ops(config); Self::new_with_num_ops(num_ops) } /***************** START ROUTED WIRES ***********************/ @@ -84,59 +87,59 @@ impl, const D: usize> Poseidon2BabyBearGate ROUTED_WIRES_PER_OP * op + 2 * SPONGE_WIDTH } - /************** *******************/ + /************** START NON-ROUTED WIRES *******************/ - const fn start_delta(&self, op: usize) -> usize { - self.num_ops * ROUTED_WIRES_PER_OP + op * NON_ROUTED_WIRES_PER_OP + const fn start_delta(num_ops: usize, op: usize) -> usize { + num_ops * ROUTED_WIRES_PER_OP + op * NON_ROUTED_WIRES_PER_OP } /// A wire which stores `swap * (input[i + SPONGE_CAPACITY] - input[i])`; used to compute the swapped inputs. - const fn wire_delta(&self, op: usize, i: usize) -> usize { + const fn wire_delta(num_ops: usize, op: usize, i: usize) -> usize { assert!(i < SPONGE_CAPACITY); - self.start_delta(op) + i + Self::start_delta(num_ops, op) + i } - const fn start_full_0(&self, op: usize) -> usize { - self.start_delta(op) + SPONGE_CAPACITY + const fn start_full_0(num_ops: usize, op: usize) -> usize { + Self::start_delta(num_ops, op) + SPONGE_CAPACITY } /// A wire which stores the input of the `i`-th S-box of the `round`-th round of the first set /// of full rounds. - const fn wire_full_sbox_0(&self, op: usize, round: usize, i: usize) -> usize { + const fn wire_full_sbox_0(num_ops: usize, op: usize, round: usize, i: usize) -> usize { debug_assert!( round != 0, "First round S-box inputs are not stored as wires" ); debug_assert!(round < HALF_N_FULL_ROUNDS); debug_assert!(i < SPONGE_WIDTH); - self.start_full_0(op) + SPONGE_WIDTH * (round - 1) + i + Self::start_full_0(num_ops, op) + SPONGE_WIDTH * (round - 1) + i } - const fn start_partial(&self, op: usize) -> usize { - self.start_full_0(op) + SPONGE_WIDTH * (HALF_N_FULL_ROUNDS - 1) + const fn start_partial(num_ops: usize, op: usize) -> usize { + Self::start_full_0(num_ops, op) + SPONGE_WIDTH * (HALF_N_FULL_ROUNDS - 1) } /// A wire which stores the input of the S-box of the `round`-th round of the partial rounds. - const fn wire_partial_sbox(&self, op: usize, round: usize) -> usize { + const fn wire_partial_sbox(num_ops: usize, op: usize, round: usize) -> usize { debug_assert!(round < N_PARTIAL_ROUNDS); - self.start_partial(op) + round + Self::start_partial(num_ops, op) + round } - const fn start_full_1(&self, op: usize) -> usize { - self.start_partial(op) + N_PARTIAL_ROUNDS + const fn start_full_1(num_ops: usize, op: usize) -> usize { + Self::start_partial(num_ops, op) + N_PARTIAL_ROUNDS } /// A wire which stores the input of the `i`-th S-box of the `round`-th round of the second set /// of full rounds. - const fn wire_full_sbox_1(&self, op: usize, round: usize, i: usize) -> usize { + const fn wire_full_sbox_1(num_ops: usize, op: usize, round: usize, i: usize) -> usize { debug_assert!(round < HALF_N_FULL_ROUNDS); debug_assert!(i < SPONGE_WIDTH); - self.start_full_1(op) + SPONGE_WIDTH * round + i + Self::start_full_1(num_ops, op) + SPONGE_WIDTH * round + i } /// End of wire indices, exclusive. - pub(crate) const fn end(&self, op: usize) -> usize { - self.start_full_1(op) + SPONGE_WIDTH * HALF_N_FULL_ROUNDS + pub(crate) const fn end(num_ops: usize, op: usize) -> usize { + Self::start_full_1(num_ops, op) + SPONGE_WIDTH * HALF_N_FULL_ROUNDS } } @@ -211,14 +214,16 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for i in 0..SPONGE_CAPACITY { let input_lhs = vars.local_wires[Self::wire_input(op, i)]; let input_rhs = vars.local_wires[Self::wire_input(op, i + SPONGE_CAPACITY)]; - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; constraints.push(swap * (input_rhs - input_lhs) - delta_i); } // Compute the possibly-swapped input layer. let mut state = [>::Extension::one(); SPONGE_WIDTH]; for i in 0..SPONGE_CAPACITY { - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; let input_lhs = Self::wire_input(op, i); let input_rhs = Self::wire_input(op, i + SPONGE_CAPACITY); state[i] = vars.local_wires[input_lhs] + delta_i; @@ -239,7 +244,13 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us add_rc(&mut state, r); if r > 0 { for i in 0..SPONGE_WIDTH { - let sbox_in = vars.local_wires[self.wire_full_sbox_0(op, r, i)]; + let sbox_in = vars.local_wires + [Poseidon2BabyBearGate::::wire_full_sbox_0( + self.num_ops, + op, + r, + i, + )]; constraints.push(state[i] - sbox_in); state[i] = sbox_in; } @@ -256,7 +267,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us // } for r in 0..N_PARTIAL_ROUNDS { state[0] += F::Extension::from_canonical_u32(INTERNAL_CONSTANTS[r]); - let sbox_in = vars.local_wires[self.wire_partial_sbox(op, r)]; + let sbox_in = vars.local_wires[Self::wire_partial_sbox(self.num_ops, op, r)]; constraints.push(state[0] - sbox_in); state[0] = sbox_in.exp_const_u64::(); permute_internal_mut(&mut state); @@ -272,8 +283,12 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for r in HALF_N_FULL_ROUNDS..N_FULL_ROUNDS_TOTAL { add_rc(&mut state, r); for i in 0..SPONGE_WIDTH { - let sbox_in = - vars.local_wires[self.wire_full_sbox_1(op, r - HALF_N_FULL_ROUNDS, i)]; + let sbox_in = vars.local_wires[Poseidon2BabyBearGate::::wire_full_sbox_1( + self.num_ops, + op, + r - HALF_N_FULL_ROUNDS, + i, + )]; constraints.push(state[i] - sbox_in); state[i] = sbox_in; } @@ -303,14 +318,16 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for i in 0..SPONGE_CAPACITY { let input_lhs = vars.local_wires[Self::wire_input(op, i)]; let input_rhs = vars.local_wires[Self::wire_input(op, i + SPONGE_CAPACITY)]; - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; yield_constr.one(swap * (input_rhs - input_lhs) - delta_i); } // Compute the possibly-swapped input layer. let mut state = [F::one(); SPONGE_WIDTH]; for i in 0..SPONGE_CAPACITY { - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; let input_lhs = Self::wire_input(op, i); let input_rhs = Self::wire_input(op, i + SPONGE_CAPACITY); state[i] = vars.local_wires[input_lhs] + delta_i; @@ -331,7 +348,13 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us add_rc(&mut state, r); if r > 0 { for i in 0..SPONGE_WIDTH { - let sbox_in = vars.local_wires[self.wire_full_sbox_0(op, r, i)]; + let sbox_in = vars.local_wires + [Poseidon2BabyBearGate::::wire_full_sbox_0( + self.num_ops, + op, + r, + i, + )]; yield_constr.one(state[i] - sbox_in); state[i] = sbox_in; } @@ -342,7 +365,8 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for r in 0..N_PARTIAL_ROUNDS { state[0] += F::from_canonical_u32(INTERNAL_CONSTANTS[r]); - let sbox_in = vars.local_wires[self.wire_partial_sbox(op, r)]; + let sbox_in = vars.local_wires + [Poseidon2BabyBearGate::::wire_partial_sbox(self.num_ops, op, r)]; yield_constr.one(state[0] - sbox_in); state[0] = sbox_in.exp_const_u64::(); permute_internal_mut(&mut state); @@ -353,8 +377,12 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for r in HALF_N_FULL_ROUNDS..N_FULL_ROUNDS_TOTAL { add_rc(&mut state, r); for i in 0..SPONGE_WIDTH { - let sbox_in = - vars.local_wires[self.wire_full_sbox_1(op, r - HALF_N_FULL_ROUNDS, i)]; + let sbox_in = vars.local_wires[Poseidon2BabyBearGate::::wire_full_sbox_1( + self.num_ops, + op, + r - HALF_N_FULL_ROUNDS, + i, + )]; yield_constr.one(state[i] - sbox_in); state[i] = sbox_in; } @@ -385,7 +413,8 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for i in 0..SPONGE_CAPACITY { let input_lhs = vars.local_wires[Self::wire_input(op, i)]; let input_rhs = vars.local_wires[Self::wire_input(op, i + SPONGE_CAPACITY)]; - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; let diff = builder.sub_extension(input_rhs, input_lhs); constraints.push(builder.mul_sub_extension(swap, diff, delta_i)); } @@ -394,7 +423,8 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us let one = builder.one_extension(); let mut state = [one; SPONGE_WIDTH]; for i in 0..SPONGE_CAPACITY { - let delta_i = vars.local_wires[self.wire_delta(op, i)]; + let delta_i = vars.local_wires + [Poseidon2BabyBearGate::::wire_delta(self.num_ops, op, i)]; let input_lhs = Self::wire_input(op, i); let input_rhs = Self::wire_input(op, i + SPONGE_CAPACITY); state[i] = builder.add_extension(vars.local_wires[input_lhs], delta_i); @@ -417,7 +447,13 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us add_rc_circuit(builder, &mut state, r); if r > 0 { for i in 0..SPONGE_WIDTH { - let sbox_in = vars.local_wires[self.wire_full_sbox_0(op, r, i)]; + let sbox_in = vars.local_wires + [Poseidon2BabyBearGate::::wire_full_sbox_0( + self.num_ops, + op, + r, + i, + )]; constraints.push(builder.sub_extension(state[i], sbox_in)); state[i] = sbox_in; } @@ -430,7 +466,8 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for r in 0..N_PARTIAL_ROUNDS { state[0] = builder .add_const_extension(state[0], F::from_canonical_u32(INTERNAL_CONSTANTS[r])); - let sbox_in = vars.local_wires[self.wire_partial_sbox(op, r)]; + let sbox_in = vars.local_wires + [Poseidon2BabyBearGate::::wire_partial_sbox(self.num_ops, op, r)]; constraints.push(builder.sub_extension(state[0], sbox_in)); state[0] = sbox_circuit(builder, sbox_in); permute_internal_mut_circuit(builder, &mut state); @@ -441,8 +478,12 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for r in HALF_N_FULL_ROUNDS..N_FULL_ROUNDS_TOTAL { add_rc_circuit(builder, &mut state, r); for i in 0..SPONGE_WIDTH { - let sbox_in = - vars.local_wires[self.wire_full_sbox_1(op, r - HALF_N_FULL_ROUNDS, i)]; + let sbox_in = vars.local_wires[Poseidon2BabyBearGate::::wire_full_sbox_1( + self.num_ops, + op, + r - HALF_N_FULL_ROUNDS, + i, + )]; constraints.push(builder.sub_extension(state[i], sbox_in)); state[i] = sbox_in; } @@ -481,7 +522,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us } fn num_wires(&self) -> usize { - self.end(self.num_ops - 1) + Poseidon2BabyBearGate::::end(self.num_ops, self.num_ops - 1) } fn num_constants(&self) -> usize { @@ -543,10 +584,16 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us ))); debug_assert!(swap_value == F::zero() || swap_value == F::one()); - let gate = Poseidon2BabyBearGate::::new_with_num_ops(self.num_ops); for i in 0..SPONGE_CAPACITY { let delta_i = swap_value * (state[i + SPONGE_CAPACITY] - state[i]); - out_buffer.set_wire(local_wire(gate.wire_delta(self.op, i)), delta_i); + out_buffer.set_wire( + local_wire(Poseidon2BabyBearGate::::wire_delta( + self.num_ops, + self.op, + i, + )), + delta_i, + ); } if swap_value == F::one() { @@ -565,7 +612,15 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us if r != 0 { for i in 0..SPONGE_WIDTH { - out_buffer.set_wire(local_wire(gate.wire_full_sbox_0(self.op, r, i)), state[i]); + out_buffer.set_wire( + local_wire(Poseidon2BabyBearGate::::wire_full_sbox_0( + self.num_ops, + self.op, + r, + i, + )), + state[i], + ); } } (0..SPONGE_WIDTH).for_each(|i| state[i] = state[i].exp_const_u64::()); @@ -579,7 +634,14 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us round_ctr += 1; state[0] += F::from_canonical_u32(INTERNAL_CONSTANTS[r]); - out_buffer.set_wire(local_wire(gate.wire_partial_sbox(self.op, r)), state[0]); + out_buffer.set_wire( + local_wire(Poseidon2BabyBearGate::::wire_partial_sbox( + self.num_ops, + self.op, + r, + )), + state[0], + ); state[0] = state[0].exp_const_u64::(); permute_internal_mut(&mut state); } @@ -589,7 +651,12 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us for i in 0..SPONGE_WIDTH { out_buffer.set_wire( - local_wire(gate.wire_full_sbox_1(self.op, r - HALF_N_FULL_ROUNDS, i)), + local_wire(Poseidon2BabyBearGate::::wire_full_sbox_1( + self.num_ops, + self.op, + r - HALF_N_FULL_ROUNDS, + i, + )), state[i], ) } @@ -621,7 +688,7 @@ impl, const D: usize, const NUM_HASH_OUT_ELTS: us src: &mut Buffer, _common_data: &CommonCircuitData, ) -> IoResult { - let num_ops = src.read_usize()?; + let num_ops = Poseidon2BabyBearGate::::num_ops(&_common_data.config); let row = src.read_usize()?; let op = src.read_usize()?; Ok(Self { From 36991aab43fc57ec0e8c45388d43b91611a25d10 Mon Sep 17 00:00:00 2001 From: Paolo Tagliaferri Date: Wed, 2 Apr 2025 15:47:06 +0200 Subject: [PATCH 3/6] [CI] Use `nightly-2025-03-12` for the `wasm` job --- .github/workflows/continuous-integration-workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index f4f232f35..c107aace7 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -61,8 +61,9 @@ jobs: uses: actions/checkout@v4 - name: Install nightly toolchain - uses: dtolnay/rust-toolchain@nightly + uses: dtolnay/rust-toolchain@master with: + toolchain: nightly-2025-03-12 targets: wasm32-unknown-unknown - name: Set up rust cache From 277855633cec7f979c9326c1ee3fc63990de204f Mon Sep 17 00:00:00 2001 From: Daniele Di Tullio Date: Thu, 3 Apr 2025 10:52:26 +0200 Subject: [PATCH 4/6] Toolchain reset to latest nightly. Because issue https://github.com/rust-lang/rust/issues/138937 was solved and merged. --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 91a24ccfe..bf867e0ae 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2025-03-12 \ No newline at end of file +nightly From fb4e449a940711f907966123b8a9d1bd3dd8c3cf Mon Sep 17 00:00:00 2001 From: Daniele Di Tullio Date: Thu, 3 Apr 2025 11:03:28 +0200 Subject: [PATCH 5/6] Cargo clippy fixes --- plonky2/src/gates/util.rs | 2 +- plonky2/src/util/strided_view.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plonky2/src/gates/util.rs b/plonky2/src/gates/util.rs index 44af8c2ef..1c2e3d8b4 100644 --- a/plonky2/src/gates/util.rs +++ b/plonky2/src/gates/util.rs @@ -41,7 +41,7 @@ impl<'a, P: PackedField> StridedConstraintConsumer<'a, P> { /// Emit one constraint. pub fn one(&mut self, constraint: P) { - if self.start != self.end { + if !core::ptr::eq(self.start, self.end) { // # Safety // The checks in `new` guarantee that this points to valid space. unsafe { diff --git a/plonky2/src/util/strided_view.rs b/plonky2/src/util/strided_view.rs index ebd8c10f1..32bb554b6 100644 --- a/plonky2/src/util/strided_view.rs +++ b/plonky2/src/util/strided_view.rs @@ -203,7 +203,7 @@ impl<'a, P: PackedField> Iterator for PackedStridedViewIter<'a, P> { "start and end pointers should be separated by a multiple of stride" ); - if self.start != self.end { + if !core::ptr::eq(self.start, self.end) { let res = unsafe { &*self.start.cast() }; // See comment in `PackedStridedView`. Below will point more than one byte past the end // of the buffer if the offset is not 0 and we've reached the end. @@ -224,7 +224,7 @@ impl DoubleEndedIterator for PackedStridedViewIter<'_, P> { "start and end pointers should be separated by a multiple of stride" ); - if self.start != self.end { + if !core::ptr::eq(self.start, self.end) { // See comment in `PackedStridedView`. `self.end` starts off pointing more than one byte // past the end of the buffer unless `offset` is 0. self.end = self.end.wrapping_sub(self.stride); From 5fc8cdf1f3a995a18928181da056f6410398c550 Mon Sep 17 00:00:00 2001 From: Paolo Tagliaferri Date: Thu, 3 Apr 2025 11:41:15 +0200 Subject: [PATCH 6/6] [CI] Restored nightly toolchain --- .github/workflows/continuous-integration-workflow.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index c107aace7..f57e508de 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -61,9 +61,8 @@ jobs: uses: actions/checkout@v4 - name: Install nightly toolchain - uses: dtolnay/rust-toolchain@master + uses: dtolnay/rust-toolchain@nightly with: - toolchain: nightly-2025-03-12 targets: wasm32-unknown-unknown - name: Set up rust cache @@ -89,9 +88,7 @@ jobs: uses: actions/checkout@v4 - name: Install nightly toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly-2024-02-01 + uses: dtolnay/rust-toolchain@nightly - name: Set up rust cache uses: Swatinem/rust-cache@v2