From f81e32f8b4619f8822fef2c6b92a05122d5ff70a Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 31 Mar 2022 14:04:38 +0200 Subject: [PATCH] semi-working --- plonky2/src/fri/recursive_verifier.rs | 2 +- plonky2/src/gates/constant.rs | 8 ++++ plonky2/src/gates/gate.rs | 4 ++ plonky2/src/gates/random_access.rs | 61 ++++++++++++++++++++++----- plonky2/src/plonk/circuit_builder.rs | 53 ++++++++++++++++++++--- plonky2/src/plonk/circuit_data.rs | 2 +- 6 files changed, 112 insertions(+), 18 deletions(-) diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index 5b273ea3..9b619ea8 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_ram_wires() + .num_routed_wires() .max(interpolation_routed_wires); assert!( diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index d36a5f4c..3f69ceb1 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -1,3 +1,5 @@ +use std::ops::Range; + use plonky2_field::extension_field::Extendable; use plonky2_field::field_types::Field; use plonky2_field::packed_field::PackedField; @@ -111,6 +113,12 @@ impl, const D: usize> Gate for ConstantGate { fn num_constraints(&self) -> usize { self.num_consts } + + fn extra_constants(&self) -> Vec<(usize, usize)> { + (0..self.num_consts) + .map(|i| (self.const_input(i), self.wire_output(i))) + .collect() + } } impl, const D: usize> PackedEvaluableBase for ConstantGate { diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index e95ec0f8..9d1e4874 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -180,6 +180,10 @@ pub trait Gate, const D: usize>: 'static + Send + S self.generators(0, &vec![F::ZERO; self.num_constants()]) .len() } + + fn extra_constants(&self) -> Vec<(usize, usize)> { + vec![] + } } /// A wrapper around an `Rc` which implements `PartialEq`, `Eq` and `Hash` based on gate IDs. diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 2e6cf2f3..33d76a54 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -1,4 +1,5 @@ use std::marker::PhantomData; +use std::ops::Range; use itertools::Itertools; use plonky2_field::extension_field::Extendable; @@ -20,6 +21,7 @@ use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; +use crate::with_context; /// A gate for checking that a particular element of a list matches a given value. #[derive(Copy, Clone, Debug)] @@ -70,7 +72,7 @@ impl, const D: usize> RandomAccessGate { (2 + self.vec_size()) * copy + 2 + i } - pub(crate) fn num_ram_wires(&self) -> usize { + fn num_ram_wires(&self) -> usize { (2 + self.vec_size()) * self.num_copies } @@ -79,7 +81,7 @@ impl, const D: usize> RandomAccessGate { self.num_ram_wires() + i } - fn num_routed_wires(&self) -> usize { + pub fn num_routed_wires(&self) -> usize { self.num_ram_wires() + self.num_extra_constants } @@ -216,7 +218,6 @@ impl, const D: usize> Gate for RandomAccessGa gate_index: usize, 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( @@ -224,12 +225,23 @@ impl, const D: usize> Gate for RandomAccessGa gate_index, gate: *self, copy, - constants: constants.to_vec(), } .adapter(), ); g }) + .chain((0..self.num_extra_constants).map(|i| { + let g: Box> = Box::new( + RandomAccessExtraConstantsGenerator { + gate_index, + gate: *self, + i, + constant: local_constants[i], + } + .adapter(), + ); + g + })) .collect() } @@ -238,7 +250,7 @@ impl, const D: usize> Gate for RandomAccessGa } fn num_constants(&self) -> usize { - 0 + self.num_extra_constants } fn degree(&self) -> usize { @@ -247,7 +259,17 @@ impl, const D: usize> Gate for RandomAccessGa fn num_constraints(&self) -> usize { let constraints_per_copy = self.bits + 2; - self.num_copies * constraints_per_copy + self.num_copies * constraints_per_copy + self.num_extra_constants + } + + fn num_ops(&self) -> usize { + self.num_copies + } + + fn extra_constants(&self) -> Vec<(usize, usize)> { + (0..self.num_extra_constants) + .map(|i| (i, self.wire_extra_constant(i))) + .collect() } } @@ -303,7 +325,6 @@ struct RandomAccessGenerator, const D: usize> { gate_index: usize, gate: RandomAccessGate, copy: usize, - constants: Vec, } impl, const D: usize> SimpleGenerator @@ -349,10 +370,30 @@ 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); - } +#[derive(Debug)] +struct RandomAccessExtraConstantsGenerator, const D: usize> { + gate_index: usize, + gate: RandomAccessGate, + i: usize, + constant: F, +} + +impl, const D: usize> SimpleGenerator + for RandomAccessExtraConstantsGenerator +{ + fn dependencies(&self) -> Vec { + Vec::new() + } + + fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { + let wire = Wire { + gate: self.gate_index, + input: self.gate.wire_extra_constant(self.i), + }; + out_buffer.set_wire(wire, self.constant); } } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index f2d22e6b..218a836e 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -2,6 +2,7 @@ use std::cmp::max; use std::collections::{BTreeMap, HashMap, HashSet}; use std::time::Instant; +use itertools::{EitherOrBoth, Itertools}; use log::{debug, info, Level}; use plonky2_field::cosets::get_unique_coset_shifts; use plonky2_field::extension_field::{Extendable, FieldExtension}; @@ -83,6 +84,9 @@ pub struct CircuitBuilder, const D: usize> { /// Map between gate type and the current gate of this type with available slots. current_slots: HashMap, CurrentSlot>, + + /// gate_index, constant_index, target_index + constants_slots: Vec<(usize, usize, usize)>, } impl, const D: usize> CircuitBuilder { @@ -102,6 +106,7 @@ impl, const D: usize> CircuitBuilder { arithmetic_results: HashMap::new(), targets_to_constants: HashMap::new(), current_slots: HashMap::new(), + constants_slots: Vec::new(), }; builder.check_config(); builder @@ -206,16 +211,23 @@ impl, const D: usize> CircuitBuilder { } /// Adds a gate to the circuit, and returns its index. - pub fn add_gate>(&mut self, gate_type: G, constants: Vec) -> usize { + pub fn add_gate>(&mut self, gate_type: G, mut constants: Vec) -> usize { self.check_gate_compatibility(&gate_type); - assert_eq!( - gate_type.num_constants(), - constants.len(), - "Number of constants doesn't match." - ); + // assert_eq!( + // gate_type.num_constants(), + // constants.len(), + // "Number of constants doesn't match." + // ); + + assert!(constants.len() <= gate_type.num_constants()); + constants.resize(gate_type.num_constants(), F::ZERO); let index = self.gate_instances.len(); + for (ci, ti) in gate_type.extra_constants() { + self.constants_slots.push((index, ci, ti)); + } + // 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 // `build` instead. @@ -240,6 +252,13 @@ impl, const D: usize> CircuitBuilder { gate.num_wires(), self.config.num_wires ); + assert!( + gate.num_constants() <= self.config.num_constants, + "{:?} requires {} constants, but our CircuitConfig has only {}", + gate.id(), + gate.num_constants(), + self.config.num_constants + ); } pub fn connect_extension(&mut self, src: ExtensionTarget, dst: ExtensionTarget) { @@ -643,6 +662,28 @@ impl, const D: usize> CircuitBuilder { self.connect(hash_part, Target::wire(pi_gate, wire)) } + // Fill constants + while self.constants_to_targets.len() > self.constants_slots.len() { + dbg!("lfg"); + self.add_gate( + ConstantGate { + num_consts: self.config.num_constants, + }, + vec![], + ); + } + dbg!(self.constants_to_targets.len(), self.constants_slots.len()); + + for ((c, t), (gate_index, const_wire, target_wire)) in self + .constants_to_targets + .clone() + .into_iter() + .zip(self.constants_slots.clone()) + { + self.gate_instances[gate_index].constants[const_wire] = c; + self.generate_copy(Target::wire(gate_index, target_wire), t); + } + info!( "Degree before blinding & padding: {}", self.gate_instances.len() diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index eb5ef95f..8e603625 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -64,7 +64,7 @@ impl CircuitConfig { Self { num_wires: 135, num_routed_wires: 80, - num_constants: 5, + num_constants: 2, use_base_arithmetic_gate: true, security_bits: 100, num_challenges: 2,