diff --git a/halo2_proofs/src/plonk/circuit.rs b/halo2_proofs/src/plonk/circuit.rs index ae6ec15703..b78acd8294 100644 --- a/halo2_proofs/src/plonk/circuit.rs +++ b/halo2_proofs/src/plonk/circuit.rs @@ -35,7 +35,6 @@ pub struct Column { } impl Column { - #[cfg(test)] pub(crate) fn new(index: usize, column_type: C) -> Self { Column { index, column_type } } @@ -1508,6 +1507,31 @@ impl>, Iter: IntoIterator> IntoIterato } } +/// GateV2Backend +#[derive(Clone, Debug)] +pub struct GateV2Backend { + name: String, + constraint_names: Vec, + polys: Vec>, +} + +impl GateV2Backend { + /// Returns the gate name. + pub fn name(&self) -> &str { + self.name.as_str() + } + + /// Returns the name of the constraint at index `constraint_index`. + pub fn constraint_name(&self, constraint_index: usize) -> &str { + self.constraint_names[constraint_index].as_str() + } + + /// Returns constraints of this gate + pub fn polynomials(&self) -> &[Expression] { + &self.polys + } +} + /// Gate #[derive(Clone, Debug)] pub struct Gate { @@ -1585,7 +1609,7 @@ pub struct ConstraintSystemV2Backend { /// fixed column that they were compressed into. This is just used by dev /// tooling right now. // pub(crate) selector_map: Vec>, - pub(crate) gates: Vec>, + pub(crate) gates: Vec>, // pub(crate) advice_queries: Vec<(Column, Rotation)>, // Contains an integer for each advice column // identifying how many distinct queries it has diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index fbd62070b6..187b9f4972 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -8,8 +8,8 @@ use std::{collections::HashMap, iter}; use super::{ circuit::{ sealed::{self}, - Advice, Any, Assignment, Challenge, Circuit, Column, CompiledCircuitV2, ConstraintSystem, - ConstraintSystemV2Backend, Fixed, FloorPlanner, Instance, Selector, + Advice, Any, Assignment, Challenge, Circuit, Column, ConstraintSystem, + ConstraintSystemV2Backend, Expression, Fixed, FloorPlanner, Instance, Selector, }, lookup, permutation, shuffle, vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY, Error, ProvingKey, ProvingKeyV2, @@ -55,20 +55,107 @@ pub struct ProverV2< R: RngCore, T: TranscriptWrite, > { + // Circuit and setup fields params: &'params Scheme::ParamsProver, pk: &'a ProvingKeyV2, - cs: &'a ConstraintSystemV2Backend, advice_queries: Vec<(Column, Rotation)>, instance_queries: Vec<(Column, Rotation)>, fixed_queries: Vec<(Column, Rotation)>, phases: Vec, + // State instance: Vec>, - rng: R, - transcript: T, advice: Vec>, challenges: HashMap, next_phase_index: usize, - _marker: std::marker::PhantomData<(Scheme, P, E, R, T)>, + rng: R, + transcript: T, + _marker: std::marker::PhantomData<(P, E)>, +} + +struct Queries { + advice: Vec<(Column, Rotation)>, + instance: Vec<(Column, Rotation)>, + fixed: Vec<(Column, Rotation)>, +} + +struct QueriesSet { + advice: BTreeSet<(Column, Rotation)>, + instance: BTreeSet<(Column, Rotation)>, + fixed: BTreeSet<(Column, Rotation)>, +} + +fn collect_queries(expr: &Expression, queries: &mut QueriesSet) { + match expr { + Expression::Constant(_) => (), + Expression::Selector(_selector) => { + panic!("no Selector should arrive to the Backend"); + } + Expression::Fixed(query) => { + queries + .fixed + .insert((Column::new(query.column_index, Fixed), query.rotation)); + } + Expression::Advice(query) => { + queries.advice.insert(( + Column::new(query.column_index, Advice { phase: query.phase }), + query.rotation, + )); + } + Expression::Instance(query) => { + queries + .instance + .insert((Column::new(query.column_index, Instance), query.rotation)); + } + Expression::Challenge(_) => (), + Expression::Negated(a) => collect_queries(a, queries), + Expression::Sum(a, b) => { + collect_queries(a, queries); + collect_queries(b, queries); + } + Expression::Product(a, b) => { + collect_queries(a, queries); + collect_queries(b, queries); + } + Expression::Scaled(a, _) => collect_queries(a, queries), + }; +} + +fn get_all_queries(cs: &ConstraintSystemV2Backend) -> Queries { + let mut queries = QueriesSet { + advice: BTreeSet::new(), + instance: BTreeSet::new(), + fixed: BTreeSet::new(), + }; + + for gate in &cs.gates { + for expr in gate.polynomials() { + collect_queries(expr, &mut queries); + } + } + for lookup in &cs.lookups { + for expr in lookup + .input_expressions + .iter() + .chain(lookup.table_expressions.iter()) + { + collect_queries(expr, &mut queries); + } + } + for shuffle in &cs.shuffles { + for expr in shuffle + .input_expressions + .iter() + .chain(shuffle.shuffle_expressions.iter()) + { + collect_queries(expr, &mut queries); + } + } + + Queries { + advice: queries.advice.into_iter().collect(), + instance: queries.instance.into_iter().collect(), + fixed: queries.fixed.into_iter().collect(), + } } impl< @@ -85,7 +172,6 @@ impl< pub fn new( params: &'params Scheme::ParamsProver, pk: &'a ProvingKeyV2, - circuit: &'a CompiledCircuitV2, instances: &[&[&[Scheme::Scalar]]], rng: R, mut transcript: T, @@ -94,22 +180,19 @@ impl< where Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, { - // TODO: We have cs duplicated in circuit.cs and pk.vk.cs. Can we dedup them? - for instance in instances.iter() { if instance.len() != pk.vk.cs.num_instance_columns { return Err(Error::InvalidInstances); } } - // TODO(Edu): Calculate advice_queries, fixed_queries, instance_queries from the gates and - // lookup expressions. + let queries = get_all_queries(&pk.vk.cs); // Hash verification key into transcript pk.vk.hash_into(&mut transcript)?; - let meta = &circuit.cs; - let phases = circuit.cs.phases(); + let meta = &pk.vk.cs; + let phases = meta.phases(); let domain = &pk.vk.domain; @@ -182,11 +265,10 @@ impl< Ok(ProverV2 { params, - cs: &circuit.cs, pk, - advice_queries: todo!(), - instance_queries: todo!(), - fixed_queries: todo!(), + advice_queries: queries.advice, + instance_queries: queries.instance, + fixed_queries: queries.fixed, phases, instance, rng, @@ -220,7 +302,7 @@ impl< } let params = self.params; - let meta = self.cs; + let meta = &self.pk.vk.cs; let transcript = &mut self.transcript; let mut rng = &mut self.rng; @@ -262,7 +344,6 @@ impl< } let mut commit_phase_fn = |advice: &mut AdviceSingle, - challenges: &mut HashMap, witness: Vec< Option, LagrangeCoeff>>, >| @@ -325,7 +406,7 @@ impl< }; for (witness, advice) in witness.into_iter().zip(advice.iter_mut()) { - commit_phase_fn(advice, challenges, witness)?; + commit_phase_fn(advice, witness)?; } for (index, phase) in meta.challenge_phase.iter().enumerate() { @@ -346,7 +427,7 @@ impl< Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, { let params = self.params; - let meta = self.cs; + let meta = &self.pk.vk.cs; let pk = self.pk; let domain = &self.pk.vk.domain; @@ -369,9 +450,7 @@ impl< |instance: &InstanceSingle, advice: &AdviceSingle| -> Result>, Error> { - pk.vk - .cs - .lookups + meta.lookups .iter() .map(|lookup| { lookup.commit_permuted_v2( @@ -409,7 +488,7 @@ impl< .iter() .zip(advice.iter()) .map(|(instance, advice)| { - pk.vk.cs.permutation.commit_v2( + meta.permutation.commit_v2( params, pk, &pk.permutation, @@ -442,9 +521,7 @@ impl< .zip(advice.iter()) .map(|(instance, advice)| -> Result, _> { // Compress expressions for each shuffle - pk.vk - .cs - .shuffles + meta.shuffles .iter() .map(|shuffle| { shuffle.commit_product_v2( diff --git a/halo2_proofs/src/poly.rs b/halo2_proofs/src/poly.rs index 9cb6b149bc..c52e982f19 100644 --- a/halo2_proofs/src/poly.rs +++ b/halo2_proofs/src/poly.rs @@ -303,7 +303,7 @@ impl<'a, F: Field, B: Basis> Sub for &'a Polynomial { /// Describes the relative rotation of a vector. Negative numbers represent /// reverse (leftmost) rotations and positive numbers represent forward (rightmost) /// rotations. Zero represents no rotation. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Rotation(pub i32); impl Rotation {