diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index 5e6cb07a..3ca39d43 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -6,7 +6,7 @@ use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::generator::{ConstantGenerator, WitnessGenerator}; +use crate::iop::generator::WitnessGenerator; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, @@ -95,16 +95,9 @@ impl, const D: usize> Gate for ConstantGate { self.num_consts } - fn extra_constants(&self, gate_index: usize) -> Vec> { + fn extra_constant_wires(&self) -> Vec<(usize, usize)> { (0..self.num_consts) - .map(|i| { - ConstantGenerator::new( - gate_index, - self.const_input(i), - self.wire_output(i), - F::ZERO, - ) - }) + .map(|i| (self.const_input(i), self.wire_output(i))) .collect() } } diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 969e3abd..861b67c0 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -12,7 +12,7 @@ use crate::gates::selectors::UNUSED_SELECTOR; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::generator::{ConstantGenerator, WitnessGenerator}; +use crate::iop::generator::WitnessGenerator; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, @@ -181,8 +181,12 @@ pub trait Gate, const D: usize>: 'static + Send + S .len() } - /// Extra constants (i.e. constants that are not used in the gate's core functionality) generated by the gate. - fn extra_constants(&self, _gate_index: usize) -> Vec> { + /// Enables gates to store some "routed constants", if they have both unused constants and + /// unused routed wires. + /// + /// Each entry in the returned `Vec` has the form `(constant_index, wire_index)`. `wire_index` + /// must correspond to a *routed* wire. + fn extra_constant_wires(&self) -> Vec<(usize, usize)> { vec![] } } diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 384d2ee9..5b4935d9 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -10,9 +10,7 @@ use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::generator::{ - ConstantGenerator, GeneratedValues, SimpleGenerator, WitnessGenerator, -}; +use crate::iop::generator::{GeneratedValues, SimpleGenerator, WitnessGenerator}; use crate::iop::target::Target; use crate::iop::wire::Wire; use crate::iop::witness::{PartitionWitness, Witness}; @@ -77,17 +75,17 @@ impl, const D: usize> RandomAccessGate { (2 + self.vec_size()) * copy + 2 + i } - fn num_ram_wires(&self) -> usize { + fn start_extra_constants(&self) -> usize { (2 + self.vec_size()) * self.num_copies } fn wire_extra_constant(&self, i: usize) -> usize { debug_assert!(i < self.num_extra_constants); - self.num_ram_wires() + i + self.start_extra_constants() + i } pub fn num_routed_wires(&self) -> usize { - self.num_ram_wires() + self.num_extra_constants + self.start_extra_constants() + self.num_extra_constants } /// An intermediate wire where the prover gives the (purported) binary decomposition of the @@ -255,9 +253,9 @@ impl, const D: usize> Gate for RandomAccessGa self.num_copies * constraints_per_copy + self.num_extra_constants } - fn extra_constants(&self, gate_index: usize) -> Vec> { + fn extra_constant_wires(&self) -> Vec<(usize, usize)> { (0..self.num_extra_constants) - .map(|i| ConstantGenerator::new(gate_index, i, self.wire_extra_constant(i), F::ZERO)) + .map(|i| (i, self.wire_extra_constant(i))) .collect() } } diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 49f74e33..5b612d91 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -328,27 +328,19 @@ impl SimpleGenerator for NonzeroTestGenerator { /// Generator used to fill an extra constant. #[derive(Debug, Clone)] -pub struct ConstantGenerator { +pub(crate) struct ConstantGenerator { pub gate_index: usize, pub constant_index: usize, - pub target_index: usize, + pub wire_index: usize, pub constant: F, } impl ConstantGenerator { - pub fn new(gate_index: usize, constant_index: usize, target_index: usize, constant: F) -> Self { - ConstantGenerator { - gate_index, - constant_index, - target_index, - constant, - } - } - pub fn set_constant(&mut self, c: F) { self.constant = c; } } + impl SimpleGenerator for ConstantGenerator { fn dependencies(&self) -> Vec { vec![] @@ -356,7 +348,7 @@ impl SimpleGenerator for ConstantGenerator { fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { out_buffer.set_target( - Target::wire(self.gate_index, self.target_index), + Target::wire(self.gate_index, self.wire_index), self.constant, ); } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 79e2eb2f..74970446 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -219,10 +219,17 @@ impl, const D: usize> CircuitBuilder { ); constants.resize(gate_type.num_constants(), F::ZERO); - let index = self.gate_instances.len(); + let gate_index = self.gate_instances.len(); self.constant_generators - .extend(gate_type.extra_constants(index)); + .extend(gate_type.extra_constant_wires().into_iter().map( + |(constant_index, wire_index)| ConstantGenerator { + gate_index, + constant_index, + wire_index, + constant: F::ZERO, // Placeholder; will be replaced later. + }, + )); // Note that we can't immediately add this gate's generators, because the list of constants // could be modified later, i.e. in the case of `ConstantGate`. We will add them later in @@ -237,7 +244,7 @@ impl, const D: usize> CircuitBuilder { constants, }); - index + gate_index } fn check_gate_compatibility>(&self, gate: &G) { @@ -678,10 +685,7 @@ impl, const D: usize> CircuitBuilder { // Set the constant in the constant polynomial. self.gate_instances[const_gen.gate_index].constants[const_gen.constant_index] = c; // Generate a copy between the target and the routable wire. - self.connect( - Target::wire(const_gen.gate_index, const_gen.target_index), - t, - ); + self.connect(Target::wire(const_gen.gate_index, const_gen.wire_index), t); // Set the constant in the generator (it's initially set with a dummy value). const_gen.set_constant(c); self.add_simple_generator(const_gen);