diff --git a/benches/hashing.rs b/benches/hashing.rs index c229972e..5669e50b 100644 --- a/benches/hashing.rs +++ b/benches/hashing.rs @@ -19,7 +19,7 @@ pub(crate) fn bench_gmimc, const WIDTH: usize>(c: &mut Criterion pub(crate) fn bench_poseidon, const WIDTH: usize>(c: &mut Criterion) where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { c.bench_function(&format!("poseidon<{}, {}>", type_name::(), WIDTH), |b| { b.iter_batched( diff --git a/src/field/packed_avx2/mod.rs b/src/field/packed_avx2/mod.rs index 20eecba7..eddbb5c9 100644 --- a/src/field/packed_avx2/mod.rs +++ b/src/field/packed_avx2/mod.rs @@ -34,7 +34,7 @@ mod tests { fn test_add() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); let b_arr = test_vals_b::(); @@ -52,7 +52,7 @@ mod tests { fn test_mul() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); let b_arr = test_vals_b::(); @@ -70,7 +70,7 @@ mod tests { fn test_square() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); @@ -86,7 +86,7 @@ mod tests { fn test_neg() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); @@ -102,7 +102,7 @@ mod tests { fn test_sub() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); let b_arr = test_vals_b::(); @@ -120,7 +120,7 @@ mod tests { fn test_interleave_is_involution() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let a_arr = test_vals_a::(); let b_arr = test_vals_b::(); @@ -144,7 +144,7 @@ mod tests { fn test_interleave() where - [(); PackedPrimeField::::WIDTH]:, + [(); PackedPrimeField::::WIDTH]: , { let in_a: [F; 4] = [ F::from_noncanonical_u64(00), diff --git a/src/gadgets/hash.rs b/src/gadgets/hash.rs index db4cb1e8..99da9e1e 100644 --- a/src/gadgets/hash.rs +++ b/src/gadgets/hash.rs @@ -15,7 +15,7 @@ impl, const D: usize> CircuitBuilder { pub fn permute(&mut self, inputs: [Target; W]) -> [Target; W] where F: GMiMC + Poseidon, - [(); W - 1]:, + [(); W - 1]: , { // We don't want to swap any inputs, so set that wire to 0. let _false = self._false(); @@ -31,7 +31,7 @@ impl, const D: usize> CircuitBuilder { ) -> [Target; W] where F: GMiMC + Poseidon, - [(); W - 1]:, + [(); W - 1]: , { match HASH_FAMILY { HashFamily::GMiMC => self.gmimc_permute_swapped(inputs, swap), @@ -88,7 +88,7 @@ impl, const D: usize> CircuitBuilder { ) -> [Target; W] where F: Poseidon, - [(); W - 1]:, + [(); W - 1]: , { let gate_type = PoseidonGate::::new(); let gate = self.add_gate(gate_type, vec![]); diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index 398c516f..58c827c1 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -6,37 +6,6 @@ use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; impl, const D: usize> CircuitBuilder { - /// Finds the last available random access gate with the given `vec_size` or add one if there aren't any. - /// Returns `(g,i)` such that there is a random access gate with the given `vec_size` at index - /// `g` and the gate's `i`-th random access is available. - fn find_random_access_gate(&mut self, vec_size: usize) -> (usize, usize) { - let (gate, i) = self - .free_random_access - .get(&vec_size) - .copied() - .unwrap_or_else(|| { - let gate = self.add_gate( - RandomAccessGate::new_from_config(&self.config, vec_size), - vec![], - ); - (gate, 0) - }); - - // Update `free_random_access` with new values. - if i < RandomAccessGate::::max_num_copies( - self.config.num_routed_wires, - self.config.num_wires, - vec_size, - ) - 1 - { - self.free_random_access.insert(vec_size, (gate, i + 1)); - } else { - self.free_random_access.remove(&vec_size); - } - - (gate, i) - } - /// Checks that a `Target` matches a vector at a non-deterministic index. /// Note: `access_index` is not range-checked. pub fn random_access(&mut self, access_index: Target, claimed_element: Target, v: Vec) { diff --git a/src/gates/poseidon.rs b/src/gates/poseidon.rs index 6e1eb69a..1f5f746d 100644 --- a/src/gates/poseidon.rs +++ b/src/gates/poseidon.rs @@ -26,7 +26,7 @@ pub struct PoseidonGate< const D: usize, const WIDTH: usize, > where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { _phantom: PhantomData, } @@ -34,7 +34,7 @@ pub struct PoseidonGate< impl + Poseidon, const D: usize, const WIDTH: usize> PoseidonGate where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { pub fn new() -> Self { PoseidonGate { @@ -91,7 +91,7 @@ where impl + Poseidon, const D: usize, const WIDTH: usize> Gate for PoseidonGate where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { fn id(&self) -> String { format!("{:?}", self, WIDTH) @@ -396,7 +396,7 @@ struct PoseidonGenerator< const D: usize, const WIDTH: usize, > where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { gate_index: usize, _phantom: PhantomData, @@ -405,7 +405,7 @@ struct PoseidonGenerator< impl + Poseidon, const D: usize, const WIDTH: usize> SimpleGenerator for PoseidonGenerator where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { fn dependencies(&self) -> Vec { (0..WIDTH) diff --git a/src/gates/poseidon_mds.rs b/src/gates/poseidon_mds.rs index a127df68..8a42b588 100644 --- a/src/gates/poseidon_mds.rs +++ b/src/gates/poseidon_mds.rs @@ -21,7 +21,7 @@ pub struct PoseidonMdsGate< const D: usize, const WIDTH: usize, > where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { _phantom: PhantomData, } @@ -29,7 +29,7 @@ pub struct PoseidonMdsGate< impl + Poseidon, const D: usize, const WIDTH: usize> PoseidonMdsGate where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { pub fn new() -> Self { PoseidonMdsGate { @@ -116,7 +116,7 @@ where impl + Poseidon, const D: usize, const WIDTH: usize> Gate for PoseidonMdsGate where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { fn id(&self) -> String { format!("{:?}", self, WIDTH) @@ -207,7 +207,7 @@ where #[derive(Clone, Debug)] struct PoseidonMdsGenerator where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { gate_index: usize, } @@ -215,7 +215,7 @@ where impl + Poseidon, const D: usize, const WIDTH: usize> SimpleGenerator for PoseidonMdsGenerator where - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { fn dependencies(&self) -> Vec { (0..WIDTH) diff --git a/src/hash/poseidon.rs b/src/hash/poseidon.rs index 9e4dd7f4..9a52060c 100644 --- a/src/hash/poseidon.rs +++ b/src/hash/poseidon.rs @@ -147,7 +147,7 @@ pub const ALL_ROUND_CONSTANTS: [u64; MAX_WIDTH * N_ROUNDS] = [ pub trait Poseidon: PrimeField where // magic to get const generic expressions to work - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { // Total number of round constants required: width of the input // times number of rounds. @@ -634,7 +634,7 @@ pub(crate) mod test_helpers { test_vectors: Vec<([u64; WIDTH], [u64; WIDTH])>, ) where F: Poseidon, - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { for (input_, expected_output_) in test_vectors.into_iter() { let mut input = [F::ZERO; WIDTH]; @@ -652,7 +652,7 @@ pub(crate) mod test_helpers { pub(crate) fn check_consistency() where F: Poseidon, - [(); WIDTH - 1]:, + [(); WIDTH - 1]: , { let mut input = [F::ZERO; WIDTH]; for i in 0..WIDTH { diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index 33709e32..c063aa85 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -77,7 +77,7 @@ pub struct CircuitBuilder, const D: usize> { /// Memoized results of `arithmetic_extension` calls. pub(crate) arithmetic_results: HashMap, ExtensionTarget>, - batched_gates: BatchedGates + batched_gates: BatchedGates, } impl, const D: usize> CircuitBuilder { @@ -295,7 +295,7 @@ impl, const D: usize> CircuitBuilder { return target; } - let (gate, instance) = self.batched_gates.constant_gate_instance(); + let (gate, instance) = self.constant_gate_instance(); let target = Target::wire(gate, instance); self.gate_instances[gate].constants[instance] = c; @@ -748,6 +748,10 @@ pub struct BatchedGates, const D: usize> { /// these constants with gate index `g` and already using `i` arithmetic operations. pub(crate) free_arithmetic: HashMap<(F, F), (usize, usize)>, + /// A map `(c0, c1) -> (g, i)` from constants `vec_size` to an available arithmetic gate using + /// these constants with gate index `g` and already using `i` random accesses. + pub(crate) free_random_access: HashMap, + /// `current_switch_gates[chunk_size - 1]` contains None if we have no switch gates with the value /// chunk_size, and contains `(g, i, c)`, if the gate `g`, at index `i`, already contains `c` copies /// of switches @@ -767,6 +771,7 @@ impl, const D: usize> BatchedGates { pub fn new() -> Self { Self { free_arithmetic: HashMap::new(), + free_random_access: HashMap::new(), current_switch_gates: Vec::new(), current_u32_arithmetic_gate: None, current_u32_subtraction_gate: None, @@ -807,6 +812,40 @@ impl, const D: usize> CircuitBuilder { (gate, i) } + /// Finds the last available random access gate with the given `vec_size` or add one if there aren't any. + /// Returns `(g,i)` such that there is a random access gate with the given `vec_size` at index + /// `g` and the gate's `i`-th random access is available. + pub(crate) fn find_random_access_gate(&mut self, vec_size: usize) -> (usize, usize) { + let (gate, i) = self + .batched_gates + .free_random_access + .get(&vec_size) + .copied() + .unwrap_or_else(|| { + let gate = self.add_gate( + RandomAccessGate::new_from_config(&self.config, vec_size), + vec![], + ); + (gate, 0) + }); + + // Update `free_random_access` with new values. + if i < RandomAccessGate::::max_num_copies( + self.config.num_routed_wires, + self.config.num_wires, + vec_size, + ) - 1 + { + self.batched_gates + .free_random_access + .insert(vec_size, (gate, i + 1)); + } else { + self.batched_gates.free_random_access.remove(&vec_size); + } + + (gate, i) + } + pub(crate) fn find_switch_gate( &mut self, chunk_size: usize, @@ -825,7 +864,7 @@ impl, const D: usize> CircuitBuilder { let (gate, gate_index, next_copy) = match self.batched_gates.current_switch_gates[chunk_size - 1].clone() { None => { - let gate = SwitchGate::::new_from_config(self.config.clone(), chunk_size); + let gate = SwitchGate::::new_from_config(&self.config, chunk_size); let gate_index = self.add_gate(gate.clone(), vec![]); (gate, gate_index, 0) } @@ -885,23 +924,23 @@ impl, const D: usize> CircuitBuilder { /// Returns the gate index and copy index of a free `ConstantGate` slot, potentially adding a /// new `ConstantGate` if needed. fn constant_gate_instance(&mut self) -> (usize, usize) { - if self.free_constant.is_none() { + if self.batched_gates.free_constant.is_none() { let num_consts = self.config.constant_gate_size; // We will fill this `ConstantGate` with zero constants initially. // These will be overwritten by `constant` as the gate instances are filled. let gate = self.add_gate(ConstantGate { num_consts }, vec![F::ZERO; num_consts]); - self.free_constant = Some((gate, 0)); + self.batched_gates.free_constant = Some((gate, 0)); } - let (gate, instance) = self.free_constant.unwrap(); + let (gate, instance) = self.batched_gates.free_constant.unwrap(); if instance + 1 < self.config.constant_gate_size { - self.free_constant = Some((gate, instance + 1)); + self.batched_gates.free_constant = Some((gate, instance + 1)); } else { - self.free_constant = None; + self.batched_gates.free_constant = None; } (gate, instance) } - + /// Fill the remaining unused arithmetic operations with zeros, so that all /// `ArithmeticExtensionGenerator`s are run. fn fill_arithmetic_gates(&mut self) {