From 5b81006e9aec8ce6cec5e0b0f8ce4dc6e23d0872 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 18 Oct 2021 17:11:59 +0200 Subject: [PATCH] Fill random access gates to make sure all generators are run --- src/gadgets/random_access.rs | 6 +++--- src/gates/random_access.rs | 2 +- src/plonk/circuit_builder.rs | 23 +++++++++++++++++++++++ src/plonk/recursive_verifier.rs | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index 54db3ec9..f8c3acab 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -9,7 +9,7 @@ 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_acces_gate(&mut self, vec_size: usize) -> (usize, usize) { + fn find_random_access_gate(&mut self, vec_size: usize) -> (usize, usize) { let (gate, i) = self .free_random_access .get(&vec_size) @@ -36,7 +36,7 @@ impl, const D: usize> CircuitBuilder { (gate, i) } - /// Checks that an `ExtensionTarget` matches a vector at a non-deterministic index. + /// 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) { let vec_size = v.len(); @@ -44,7 +44,7 @@ impl, const D: usize> CircuitBuilder { if vec_size == 1 { return self.connect(claimed_element, v[0]); } - let (gate_index, copy) = self.find_random_acces_gate(vec_size); + let (gate_index, copy) = self.find_random_access_gate(vec_size); let dummy_gate = RandomAccessGate::::new_from_config(&self.config, vec_size); v.iter().enumerate().for_each(|(i, &val)| { diff --git a/src/gates/random_access.rs b/src/gates/random_access.rs index 925aa3ea..191f66e3 100644 --- a/src/gates/random_access.rs +++ b/src/gates/random_access.rs @@ -212,7 +212,7 @@ impl, const D: usize> Gate for RandomAccessGa } fn num_constraints(&self) -> usize { - self.num_copies * self.vec_size * 3 + 3 * self.num_copies * self.vec_size } } diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index 96433bce..4b392be9 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -18,6 +18,7 @@ use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate}; use crate::gates::gate_tree::Tree; use crate::gates::noop::NoopGate; use crate::gates::public_input::PublicInputGate; +use crate::gates::random_access::RandomAccessGate; use crate::gates::switch::SwitchGate; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget}; use crate::hash::hashing::hash_n_to_hash; @@ -535,6 +536,27 @@ impl, const D: usize> CircuitBuilder { } } + /// Fill the remaining unused random access operations with zeros, so that all + /// `RandomAccessGenerator`s are run. + fn fill_random_access_gates(&mut self) { + let zero = self.zero(); + let remaining_random_access_gates = self + .free_random_access + .clone() + .into_iter() + .collect::>(); + for (vec_size, (_, i)) in remaining_random_access_gates { + let max_copies = RandomAccessGate::::max_num_copies( + self.config.num_routed_wires, + self.config.num_wires, + vec_size, + ); + for _ in i..max_copies { + self.random_access(zero, zero, vec![zero; vec_size]); + } + } + } + /// Fill the remaining unused switch gates with dummy values, so that all /// `SwitchGenerator` are run. fn fill_switch_gates(&mut self) { @@ -574,6 +596,7 @@ impl, const D: usize> CircuitBuilder { let start = Instant::now(); self.fill_arithmetic_gates(); + self.fill_random_access_gates(); self.fill_switch_gates(); // Hash the public inputs, and route them to a `PublicInputGate` which will enforce that diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index 130baa09..f9bda416 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -398,7 +398,7 @@ mod tests { fn test_size_optimized_recursion() -> Result<()> { init_logger(); type F = GoldilocksField; - const D: usize = 4; + const D: usize = 2; let normal_config = CircuitConfig::standard_recursion_config(); let final_config = CircuitConfig {