diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index 9b619ea8..5b273ea3 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -86,7 +86,7 @@ impl, const D: usize> CircuitBuilder { let min_wires = random_access.num_wires().max(interpolation_wires); let min_routed_wires = random_access - .num_routed_wires() + .num_ram_wires() .max(interpolation_routed_wires); assert!( diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index 990a4df8..d36a5f4c 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -159,7 +159,7 @@ mod tests { #[test] fn low_degree() { - let num_consts = CircuitConfig::standard_recursion_config().constant_gate_size; + let num_consts = CircuitConfig::standard_recursion_config().num_constants; let gate = ConstantGate { num_consts }; test_low_degree::(gate) } @@ -169,7 +169,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let num_consts = CircuitConfig::standard_recursion_config().constant_gate_size; + let num_consts = CircuitConfig::standard_recursion_config().num_constants; let gate = ConstantGate { num_consts }; test_eval_fns::(gate) } diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 6379f99f..2e6cf2f3 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -26,14 +26,16 @@ use crate::plonk::vars::{ pub(crate) struct RandomAccessGate, const D: usize> { pub bits: usize, pub num_copies: usize, + pub num_extra_constants: usize, _phantom: PhantomData, } impl, const D: usize> RandomAccessGate { - fn new(num_copies: usize, bits: usize) -> Self { + fn new(num_copies: usize, bits: usize, num_extra_constants: usize) -> Self { Self { bits, num_copies, + num_extra_constants, _phantom: PhantomData, } } @@ -45,7 +47,7 @@ impl, const D: usize> RandomAccessGate { // Need `(2 + vec_size + bits) * num_copies` wires config.num_wires / (2 + vec_size + bits), ); - Self::new(max_copies, bits) + Self::new(max_copies, bits, config.num_constants) } fn vec_size(&self) -> usize { @@ -68,12 +70,17 @@ impl, const D: usize> RandomAccessGate { (2 + self.vec_size()) * copy + 2 + i } - fn start_of_intermediate_wires(&self) -> usize { + pub(crate) fn num_ram_wires(&self) -> usize { (2 + self.vec_size()) * self.num_copies } - pub(crate) fn num_routed_wires(&self) -> usize { - self.start_of_intermediate_wires() + fn wire_extra_constant(&self, i: usize) -> usize { + debug_assert!(i < self.num_extra_constants); + self.num_ram_wires() + i + } + + fn num_routed_wires(&self) -> usize { + self.num_ram_wires() + self.num_extra_constants } /// An intermediate wire where the prover gives the (purported) binary decomposition of the @@ -81,7 +88,7 @@ impl, const D: usize> RandomAccessGate { pub fn wire_bit(&self, i: usize, copy: usize) -> usize { debug_assert!(i < self.bits); debug_assert!(copy < self.num_copies); - self.start_of_intermediate_wires() + copy * self.bits + i + self.num_routed_wires() + copy * self.bits + i } } @@ -129,6 +136,11 @@ impl, const D: usize> Gate for RandomAccessGa constraints.push(list_items[0] - claimed_element); } + constraints.extend( + (0..self.num_extra_constants) + .map(|i| vars.local_constants[i] - vars.local_wires[self.wire_extra_constant(i)]), + ); + constraints } @@ -189,14 +201,22 @@ impl, const D: usize> Gate for RandomAccessGa constraints.push(builder.sub_extension(list_items[0], claimed_element)); } + constraints.extend((0..self.num_extra_constants).map(|i| { + builder.sub_extension( + vars.local_constants[i], + vars.local_wires[self.wire_extra_constant(i)], + ) + })); + constraints } fn generators( &self, gate_index: usize, - _local_constants: &[F], + local_constants: &[F], ) -> Vec>> { + let constants = local_constants[..self.num_extra_constants].to_vec(); (0..self.num_copies) .map(|copy| { let g: Box> = Box::new( @@ -204,6 +224,7 @@ impl, const D: usize> Gate for RandomAccessGa gate_index, gate: *self, copy, + constants: constants.to_vec(), } .adapter(), ); @@ -270,6 +291,10 @@ impl, const D: usize> PackedEvaluableBase debug_assert_eq!(list_items.len(), 1); yield_constr.one(list_items[0] - claimed_element); } + yield_constr.many( + (0..self.num_extra_constants) + .map(|i| vars.local_constants[i] - vars.local_wires[self.wire_extra_constant(i)]), + ); } } @@ -278,6 +303,7 @@ struct RandomAccessGenerator, const D: usize> { gate_index: usize, gate: RandomAccessGate, copy: usize, + constants: Vec, } impl, const D: usize> SimpleGenerator @@ -323,6 +349,10 @@ impl, const D: usize> SimpleGenerator let bit = F::from_bool(((access_index >> i) & 1) != 0); set_local_wire(self.gate.wire_bit(i, copy), bit); } + + for (i, &c) in self.constants.iter().enumerate() { + set_local_wire(self.gate.wire_extra_constant(i), c); + } } } @@ -344,7 +374,7 @@ mod tests { #[test] fn low_degree() { - test_low_degree::(RandomAccessGate::new(4, 4)); + test_low_degree::(RandomAccessGate::new(4, 4, 1)); } #[test] @@ -352,7 +382,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - test_eval_fns::(RandomAccessGate::new(4, 4)) + test_eval_fns::(RandomAccessGate::new(4, 4, 1)) } #[test] @@ -404,6 +434,7 @@ mod tests { let gate = RandomAccessGate:: { bits, num_copies, + num_extra_constants: 1, _phantom: PhantomData, }; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 022e2b12..f2d22e6b 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -321,14 +321,7 @@ impl, const D: usize> CircuitBuilder { return target; } - 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 = ConstantGate { num_consts }; - let (gate, instance) = self.find_slot(gate, &[], &vec![F::ZERO; num_consts]); - let target = Target::wire(gate, instance); - self.gate_instances[gate].constants[instance] = c; - + let target = self.add_virtual_target(); self.constants_to_targets.insert(c, target); self.targets_to_constants.insert(target, c); diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 8c33ae98..eb5ef95f 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -33,7 +33,7 @@ use crate::util::timing::TimingTree; pub struct CircuitConfig { pub num_wires: usize, pub num_routed_wires: usize, - pub constant_gate_size: usize, + pub num_constants: usize, /// Whether to use a dedicated gate for base field arithmetic, rather than using a single gate /// for both base field and extension field arithmetic. pub use_base_arithmetic_gate: bool, @@ -64,7 +64,7 @@ impl CircuitConfig { Self { num_wires: 135, num_routed_wires: 80, - constant_gate_size: 5, + num_constants: 5, use_base_arithmetic_gate: true, security_bits: 100, num_challenges: 2,