diff --git a/halo2_proofs/src/plonk/circuit.rs b/halo2_proofs/src/plonk/circuit.rs index d7ddbf6a31..54c4d16ec5 100644 --- a/halo2_proofs/src/plonk/circuit.rs +++ b/halo2_proofs/src/plonk/circuit.rs @@ -12,7 +12,6 @@ use ff::Field; use sealed::SealedPhase; use std::collections::BTreeSet; use std::collections::HashMap; -use std::collections::HashSet; use std::fmt::Debug; use std::iter::{Product, Sum}; use std::{ @@ -1784,59 +1783,6 @@ impl QueriesMap { } } -/* -/// This is a description of the circuit environment, such as the gate, column and -/// permutation arrangements. -#[derive(Debug, Clone)] -pub struct ConstraintSystemV2BackendQueries { - pub(crate) num_fixed_columns: usize, - pub(crate) num_advice_columns: usize, - pub(crate) num_instance_columns: usize, - // pub(crate) num_selectors: usize, - pub(crate) num_challenges: usize, - - /// Contains the index of each advice column that is left unblinded. - pub(crate) unblinded_advice_columns: Vec, - - /// Contains the phase for each advice column. Should have same length as num_advice_columns. - pub(crate) advice_column_phase: Vec, - /// Contains the phase for each challenge. Should have same length as num_challenges. - pub(crate) challenge_phase: Vec, - - /// This is a cached vector that maps virtual selectors to the concrete - /// 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) advice_queries: Vec<(Column, Rotation)>, - // Contains an integer for each advice column - // identifying how many distinct queries it has - // so far; should be same length as num_advice_columns. - pub(crate) num_advice_queries: Vec, - pub(crate) instance_queries: Vec<(Column, Rotation)>, - pub(crate) fixed_queries: Vec<(Column, Rotation)>, - - // Permutation argument for performing equality constraints - pub(crate) permutation: permutation::Argument, - - // Vector of lookup arguments, where each corresponds to a sequence of - // input expressions and a sequence of table expressions involved in the lookup. - pub(crate) lookups: Vec>, - - // Vector of shuffle arguments, where each corresponds to a sequence of - // input expressions and a sequence of shuffle expressions involved in the shuffle. - pub(crate) shuffles: Vec>, - - // List of indexes of Fixed columns which are associated to a circuit-general Column tied to their annotation. - pub(crate) general_column_annotations: HashMap, - // Vector of fixed columns, which can be used to store constant values - // that are copied into advice columns. - // pub(crate) constants: Vec>, - - // pub(crate) minimum_degree: Option, -} -*/ - /// This is a description of the circuit environment, such as the gate, column and /// permutation arrangements. #[derive(Debug, Clone)] @@ -1844,7 +1790,6 @@ pub struct ConstraintSystemV2Backend { pub(crate) num_fixed_columns: usize, pub(crate) num_advice_columns: usize, pub(crate) num_instance_columns: usize, - // pub(crate) num_selectors: usize, pub(crate) num_challenges: usize, /// Contains the index of each advice column that is left unblinded. @@ -1855,14 +1800,7 @@ pub struct ConstraintSystemV2Backend { /// Contains the phase for each challenge. Should have same length as num_challenges. pub(crate) challenge_phase: Vec, - /// This is a cached vector that maps virtual selectors to the concrete - /// 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) advice_queries: Vec<(Column, Rotation)>, - // pub(crate) instance_queries: Vec<(Column, Rotation)>, - // pub(crate) fixed_queries: Vec<(Column, Rotation)>, // Permutation argument for performing equality constraints pub(crate) permutation: permutation::Argument, @@ -1877,11 +1815,6 @@ pub struct ConstraintSystemV2Backend { // List of indexes of Fixed columns which are associated to a circuit-general Column tied to their annotation. pub(crate) general_column_annotations: HashMap, - // Vector of fixed columns, which can be used to store constant values - // that are copied into advice columns. - // pub(crate) constants: Vec>, - - // pub(crate) minimum_degree: Option, } /// Witness calculator. Frontend function @@ -1942,7 +1875,6 @@ impl<'a, F: Field, ConcreteCircuit: Circuit> WitnessCalculator<'a, F, Concret k: self.k, current_phase, advice: vec![Polynomial::new_empty(self.n, F::ZERO.into()); self.cs.num_advice_columns], - unblinded_advice: HashSet::from_iter(self.cs.unblinded_advice_columns.clone()), instances: self.instances, challenges, // The prover will not be allowed to assign values to advice diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index eb47d26887..bed61f09a0 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -8,7 +8,7 @@ use group::Curve; use super::{ circuit::{ compile_circuit, Advice, Any, Assignment, Circuit, Column, CompiledCircuitV2, - ConstraintSystem, Fixed, FloorPlanner, Instance, Selector, + ConstraintSystem, Fixed, Instance, Selector, }, evaluation::Evaluator, permutation, Assigned, Challenge, Error, LagrangeCoeff, Polynomial, ProvingKey, VerifyingKey, @@ -17,7 +17,6 @@ use crate::{ arithmetic::{parallelize, CurveAffine}, circuit::Value, poly::{ - batch_invert_assigned, commitment::{Blind, Params}, EvaluationDomain, }, @@ -247,7 +246,7 @@ where /// Generate a `VerifyingKey` from an instance of `Circuit`. /// By default, selector compression is turned **off**. -pub fn keygen_vk_legacy<'params, C, P, ConcreteCircuit>( +pub fn keygen_vk<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, ) -> Result, Error> @@ -257,13 +256,13 @@ where ConcreteCircuit: Circuit, C::Scalar: FromUniformBytes<64>, { - keygen_vk_custom_legacy(params, circuit, true) + keygen_vk_custom(params, circuit, true) } /// Generate a `VerifyingKey` from an instance of `Circuit`. /// /// The selector compression optimization is turned on only if `compress_selectors` is `true`. -pub fn keygen_vk_custom_legacy<'params, C, P, ConcreteCircuit>( +pub fn keygen_vk_custom<'params, C, P, ConcreteCircuit>( params: &P, circuit: &ConcreteCircuit, compress_selectors: bool, @@ -280,97 +279,6 @@ where Ok(vk) } -// TODO: Remove -/// Generate a `VerifyingKey` from an instance of `Circuit`. -/// By default, selector compression is turned **off**. -pub fn keygen_vk<'params, C, P, ConcreteCircuit>( - params: &P, - circuit: &ConcreteCircuit, -) -> Result, Error> -where - C: CurveAffine, - P: Params<'params, C>, - ConcreteCircuit: Circuit, - C::Scalar: FromUniformBytes<64>, -{ - keygen_vk_custom(params, circuit, true) -} - -// TODO: Remove -/// Generate a `VerifyingKey` from an instance of `Circuit`. -/// -/// The selector compression optimization is turned on only if `compress_selectors` is `true`. -pub fn keygen_vk_custom<'params, C, P, ConcreteCircuit>( - params: &P, - circuit: &ConcreteCircuit, - compress_selectors: bool, -) -> Result, Error> -where - C: CurveAffine, - P: Params<'params, C>, - ConcreteCircuit: Circuit, - C::Scalar: FromUniformBytes<64>, -{ - let (domain, cs, config) = create_domain::( - params.k(), - #[cfg(feature = "circuit-params")] - circuit.params(), - ); - - if (params.n() as usize) < cs.minimum_rows() { - return Err(Error::not_enough_rows_available(params.k())); - } - - let mut assembly: Assembly = Assembly { - k: params.k(), - fixed: vec![domain.empty_lagrange_assigned(); cs.num_fixed_columns], - permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation), - selectors: vec![vec![false; params.n() as usize]; cs.num_selectors], - usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1), - _marker: std::marker::PhantomData, - }; - - // Synthesize the circuit to obtain URS - ConcreteCircuit::FloorPlanner::synthesize( - &mut assembly, - circuit, - config, - cs.constants.clone(), - )?; - - let mut fixed = batch_invert_assigned(assembly.fixed); - let (cs, selector_polys) = if compress_selectors { - cs.compress_selectors(assembly.selectors.clone()) - } else { - // After this, the ConstraintSystem should not have any selectors: `verify` does not need them, and `keygen_pk` regenerates `cs` from scratch anyways. - let selectors = std::mem::take(&mut assembly.selectors); - cs.directly_convert_selectors_to_fixed(selectors) - }; - fixed.extend( - selector_polys - .into_iter() - .map(|poly| domain.lagrange_from_vec(poly)), - ); - - let permutation_vk = assembly - .permutation - .build_vk(params, &domain, &cs.permutation); - - let fixed_commitments = fixed - .iter() - .map(|poly| params.commit_lagrange(poly, Blind::default()).to_affine()) - .collect(); - - Ok(VerifyingKey::from_parts( - domain, - fixed_commitments, - permutation_vk, - cs, - assembly.selectors, - compress_selectors, - )) -} - /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `CompiledCircuit`. pub fn keygen_pk_v2<'params, C, P>( params: &P, @@ -456,7 +364,7 @@ where } /// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. -pub fn keygen_pk_legacy<'params, C, P, ConcreteCircuit>( +pub fn keygen_pk<'params, C, P, ConcreteCircuit>( params: &P, vk: VerifyingKey, circuit: &ConcreteCircuit, @@ -469,128 +377,3 @@ where let (compiled_circuit, _, _) = compile_circuit(params.k(), circuit, vk.compress_selectors)?; keygen_pk_v2(params, vk, &compiled_circuit) } - -// TODO: Remove -/// Generate a `ProvingKey` from a `VerifyingKey` and an instance of `Circuit`. -pub fn keygen_pk<'params, C, P, ConcreteCircuit>( - params: &P, - vk: VerifyingKey, - circuit: &ConcreteCircuit, -) -> Result, Error> -where - C: CurveAffine, - P: Params<'params, C>, - ConcreteCircuit: Circuit, -{ - let mut cs = ConstraintSystem::default(); - #[cfg(feature = "circuit-params")] - let config = ConcreteCircuit::configure_with_params(&mut cs, circuit.params()); - #[cfg(not(feature = "circuit-params"))] - let config = ConcreteCircuit::configure(&mut cs); - - let cs = cs; - - if (params.n() as usize) < cs.minimum_rows() { - return Err(Error::not_enough_rows_available(params.k())); - } - - let mut assembly: Assembly = Assembly { - k: params.k(), - fixed: vec![vk.domain.empty_lagrange_assigned(); cs.num_fixed_columns], - permutation: permutation::keygen::Assembly::new(params.n() as usize, &cs.permutation), - selectors: vec![vec![false; params.n() as usize]; cs.num_selectors], - usable_rows: 0..params.n() as usize - (cs.blinding_factors() + 1), - _marker: std::marker::PhantomData, - }; - - // Synthesize the circuit to obtain URS - ConcreteCircuit::FloorPlanner::synthesize( - &mut assembly, - circuit, - config, - cs.constants.clone(), - )?; - - let mut fixed = batch_invert_assigned(assembly.fixed); - let (cs, selector_polys) = if vk.compress_selectors { - cs.compress_selectors(assembly.selectors) - } else { - cs.directly_convert_selectors_to_fixed(assembly.selectors) - }; - // println!( - // "DBG configure queries:\n{:#?}", - // ( - // &cs.advice_queries, - // &cs.instance_queries, - // &cs.fixed_queries, - // &cs.num_advice_queries - // ) - // ); - fixed.extend( - selector_polys - .into_iter() - .map(|poly| vk.domain.lagrange_from_vec(poly)), - ); - - let fixed_polys: Vec<_> = fixed - .iter() - .map(|poly| vk.domain.lagrange_to_coeff(poly.clone())) - .collect(); - - let fixed_cosets = fixed_polys - .iter() - .map(|poly| vk.domain.coeff_to_extended(poly.clone())) - .collect(); - - let permutation_pk = assembly - .permutation - .build_pk(params, &vk.domain, &cs.permutation); - - // Compute l_0(X) - // TODO: this can be done more efficiently - let mut l0 = vk.domain.empty_lagrange(); - l0[0] = C::Scalar::ONE; - let l0 = vk.domain.lagrange_to_coeff(l0); - let l0 = vk.domain.coeff_to_extended(l0); - - // Compute l_blind(X) which evaluates to 1 for each blinding factor row - // and 0 otherwise over the domain. - let mut l_blind = vk.domain.empty_lagrange(); - for evaluation in l_blind[..].iter_mut().rev().take(cs.blinding_factors()) { - *evaluation = C::Scalar::ONE; - } - let l_blind = vk.domain.lagrange_to_coeff(l_blind); - let l_blind = vk.domain.coeff_to_extended(l_blind); - - // Compute l_last(X) which evaluates to 1 on the first inactive row (just - // before the blinding factors) and 0 otherwise over the domain - let mut l_last = vk.domain.empty_lagrange(); - l_last[params.n() as usize - cs.blinding_factors() - 1] = C::Scalar::ONE; - let l_last = vk.domain.lagrange_to_coeff(l_last); - let l_last = vk.domain.coeff_to_extended(l_last); - - // Compute l_active_row(X) - let one = C::Scalar::ONE; - let mut l_active_row = vk.domain.empty_extended(); - parallelize(&mut l_active_row, |values, start| { - for (i, value) in values.iter_mut().enumerate() { - let idx = i + start; - *value = one - (l_last[idx] + l_blind[idx]); - } - }); - - // Compute the optimized evaluation data structure - let ev = Evaluator::new(&vk.cs); - - Ok(ProvingKey { - vk, - l0, - l_last, - l_active_row, - fixed_values: fixed, - fixed_polys, - fixed_cosets, - permutation: permutation_pk, - ev, - }) -} diff --git a/halo2_proofs/src/plonk/prover.rs b/halo2_proofs/src/plonk/prover.rs index 62f45e85c3..f29e09e820 100644 --- a/halo2_proofs/src/plonk/prover.rs +++ b/halo2_proofs/src/plonk/prover.rs @@ -9,8 +9,8 @@ use super::{ circuit::{ compile_circuit, sealed::{self}, - Advice, Any, Assignment, Challenge, Circuit, Column, ConstraintSystem, Fixed, FloorPlanner, - Instance, Selector, WitnessCalculator, + Advice, Any, Assignment, Challenge, Circuit, Column, Fixed, Instance, Selector, + WitnessCalculator, }, lookup, permutation, shuffle, vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY, Error, ProvingKey, @@ -329,14 +329,36 @@ impl< } } - // Check that all current_phase advice columns are Some - for (column_index, advice_column) in witness.iter().enumerate() { - if column_indices.contains(&column_index) { - // TODO: Check that column_index in witness is Some - // TODO: Check that the column length is `params.n()` - } else { - // TODO: Check that column_index in witness is None - }; + // Check that all current_phase advice columns are Some, and their length is correct + for witness in &witness { + for (column_index, advice_column) in witness.iter().enumerate() { + if column_indices.contains(&column_index) { + match advice_column { + None => { + return Err(Error::Other(format!( + "expected advice column with index {} at phase {}", + column_index, current_phase.0 + ))) + } + Some(advice_column) => { + if advice_column.len() != params.n() as usize { + return Err(Error::Other(format!( + "expected advice column with index {} to have length {}", + column_index, + params.n(), + ))); + } + } + } + } else { + if advice_column.is_some() { + return Err(Error::Other(format!( + "expected no advice column with index {} at phase {}", + column_index, current_phase.0 + ))); + } + }; + } } let mut commit_phase_fn = |advice: &mut AdviceSingle, @@ -738,7 +760,7 @@ pub(crate) struct WitnessCollection<'a, F: Field> { pub(crate) k: u32, pub(crate) current_phase: sealed::Phase, pub(crate) advice: Vec, LagrangeCoeff>>, - pub(crate) unblinded_advice: HashSet, + // pub(crate) unblinded_advice: HashSet, pub(crate) challenges: &'a HashMap, pub(crate) instances: &'a [&'a [F]], pub(crate) usable_rows: RangeTo, @@ -877,7 +899,7 @@ impl<'a, F: Field> Assignment for WitnessCollection<'a, F> { /// parameters `params` and the proving key [`ProvingKey`] that was /// generated previously for the same circuit. The provided `instances` /// are zero-padded internally. -pub fn create_proof_legacy< +pub fn create_proof< 'params, Scheme: CommitmentScheme, P: Prover<'params, Scheme>, @@ -919,557 +941,11 @@ where prover.create_proof() } -/// This creates a proof for the provided `circuit` when given the public -/// parameters `params` and the proving key [`ProvingKey`] that was -/// generated previously for the same circuit. The provided `instances` -/// are zero-padded internally. -// TODO: Remove -pub fn create_proof< - 'params, - Scheme: CommitmentScheme, - P: Prover<'params, Scheme>, - E: EncodedChallenge, - R: RngCore, - T: TranscriptWrite, - ConcreteCircuit: Circuit, ->( - params: &'params Scheme::ParamsProver, - pk: &ProvingKey, - circuits: &[ConcreteCircuit], - instances: &[&[&[Scheme::Scalar]]], - mut rng: R, - transcript: &mut T, -) -> Result<(), Error> -where - Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, -{ - if circuits.len() != instances.len() { - return Err(Error::InvalidInstances); - } - - for instance in instances.iter() { - if instance.len() != pk.vk.cs.num_instance_columns { - return Err(Error::InvalidInstances); - } - } - - // Hash verification key into transcript - pk.vk.hash_into(transcript)?; - - let domain = &pk.vk.domain; - let mut meta = ConstraintSystem::default(); - #[cfg(feature = "circuit-params")] - let config = ConcreteCircuit::configure_with_params(&mut meta, circuits[0].params()); - #[cfg(not(feature = "circuit-params"))] - let config = ConcreteCircuit::configure(&mut meta); - - // Selector optimizations cannot be applied here; use the ConstraintSystem - // from the verification key. - let meta = &pk.vk.cs; - - struct InstanceSingle { - pub instance_values: Vec>, - pub instance_polys: Vec>, - } - - let instance: Vec> = instances - .iter() - .map(|instance| -> Result, Error> { - let instance_values = instance - .iter() - .map(|values| { - let mut poly = domain.empty_lagrange(); - assert_eq!(poly.len(), params.n() as usize); - if values.len() > (poly.len() - (meta.blinding_factors() + 1)) { - return Err(Error::InstanceTooLarge); - } - for (poly, value) in poly.iter_mut().zip(values.iter()) { - if !P::QUERY_INSTANCE { - transcript.common_scalar(*value)?; - } - *poly = *value; - } - Ok(poly) - }) - .collect::, _>>()?; - - if P::QUERY_INSTANCE { - let instance_commitments_projective: Vec<_> = instance_values - .iter() - .map(|poly| params.commit_lagrange(poly, Blind::default())) - .collect(); - let mut instance_commitments = - vec![Scheme::Curve::identity(); instance_commitments_projective.len()]; - ::CurveExt::batch_normalize( - &instance_commitments_projective, - &mut instance_commitments, - ); - let instance_commitments = instance_commitments; - drop(instance_commitments_projective); - - for commitment in &instance_commitments { - transcript.common_point(*commitment)?; - } - } - - let instance_polys: Vec<_> = instance_values - .iter() - .map(|poly| { - let lagrange_vec = domain.lagrange_from_vec(poly.to_vec()); - domain.lagrange_to_coeff(lagrange_vec) - }) - .collect(); - - Ok(InstanceSingle { - instance_values, - instance_polys, - }) - }) - .collect::, _>>()?; - - #[derive(Clone)] - struct AdviceSingle { - pub advice_polys: Vec>, - pub advice_blinds: Vec>, - } - - let (advice, challenges) = { - let mut advice = vec![ - AdviceSingle:: { - advice_polys: vec![domain.empty_lagrange(); meta.num_advice_columns], - advice_blinds: vec![Blind::default(); meta.num_advice_columns], - }; - instances.len() - ]; - let mut challenges = HashMap::::with_capacity(meta.num_challenges); - - let unusable_rows_start = params.n() as usize - (meta.blinding_factors() + 1); - for current_phase in pk.vk.cs.phases() { - println!("DBG phase {:?}", current_phase); - let column_indices = meta - .advice_column_phase - .iter() - .enumerate() - .filter_map(|(column_index, phase)| { - if current_phase == *phase { - Some(column_index) - } else { - None - } - }) - .collect::>(); - - for ((circuit, advice), instances) in - circuits.iter().zip(advice.iter_mut()).zip(instances) - { - let mut witness = WitnessCollection { - k: params.k(), - current_phase, - advice: vec![domain.empty_lagrange_assigned(); meta.num_advice_columns], - unblinded_advice: HashSet::from_iter(meta.unblinded_advice_columns.clone()), - instances, - challenges: &challenges, - // The prover will not be allowed to assign values to advice - // cells that exist within inactive rows, which include some - // number of blinding factors and an extra row for use in the - // permutation argument. - usable_rows: ..unusable_rows_start, - _marker: std::marker::PhantomData, - }; - - // Synthesize the circuit to obtain the witness and other information. - ConcreteCircuit::FloorPlanner::synthesize( - &mut witness, - circuit, - config.clone(), - meta.constants.clone(), - )?; - - let mut advice_values = batch_invert_assigned::( - witness - .advice - .into_iter() - .enumerate() - .filter_map(|(column_index, advice)| { - if column_indices.contains(&column_index) { - Some(advice) - } else { - None - } - }) - .collect(), - ); - - // Add blinding factors to advice columns - for (column_index, advice_values) in column_indices.iter().zip(&mut advice_values) { - if !witness.unblinded_advice.contains(column_index) { - for cell in &mut advice_values[unusable_rows_start..] { - *cell = Scheme::Scalar::random(&mut rng); - } - } else { - #[cfg(feature = "sanity-checks")] - for cell in &advice_values[unusable_rows_start..] { - assert_eq!(*cell, Scheme::Scalar::ZERO); - } - } - } - - // Compute commitments to advice column polynomials - let blinds: Vec<_> = column_indices - .iter() - .map(|i| { - if witness.unblinded_advice.contains(i) { - Blind::default() - } else { - Blind(Scheme::Scalar::random(&mut rng)) - } - }) - .collect(); - // println!("DBG blinds: {:?}", blinds); - let advice_commitments_projective: Vec<_> = advice_values - .iter() - .zip(blinds.iter()) - .map(|(poly, blind)| params.commit_lagrange(poly, *blind)) - .collect(); - // println!( - // "DBG advice_commitments_projective: {:?}", - // advice_commitments_projective - // ); - let mut advice_commitments = - vec![Scheme::Curve::identity(); advice_commitments_projective.len()]; - ::CurveExt::batch_normalize( - &advice_commitments_projective, - &mut advice_commitments, - ); - // println!("DBG advice_commitments: {:?}", advice_commitments); - let advice_commitments = advice_commitments; - drop(advice_commitments_projective); - - for commitment in &advice_commitments { - transcript.write_point(*commitment)?; - } - for ((column_index, advice_values), blind) in - column_indices.iter().zip(advice_values).zip(blinds) - { - advice.advice_polys[*column_index] = advice_values; - advice.advice_blinds[*column_index] = blind; - } - } - - for (index, phase) in meta.challenge_phase.iter().enumerate() { - if current_phase == *phase { - let existing = - challenges.insert(index, *transcript.squeeze_challenge_scalar::<()>()); - assert!(existing.is_none()); - } - } - } - - assert_eq!(challenges.len(), meta.num_challenges); - let challenges = (0..meta.num_challenges) - .map(|index| challenges.remove(&index).unwrap()) - .collect::>(); - - (advice, challenges) - }; - - // Sample theta challenge for keeping lookup columns linearly independent - let theta: ChallengeTheta<_> = transcript.squeeze_challenge_scalar(); - - let lookups: Vec>> = instance - .iter() - .zip(advice.iter()) - .map(|(instance, advice)| -> Result, Error> { - // Construct and commit to permuted values for each lookup - pk.vk - .cs - .lookups - .iter() - .map(|lookup| { - lookup.commit_permuted( - pk, - params, - domain, - theta, - &advice.advice_polys, - &pk.fixed_values, - &instance.instance_values, - &challenges, - &mut rng, - transcript, - ) - }) - .collect() - }) - .collect::, _>>()?; - - // Sample beta challenge - let beta: ChallengeBeta<_> = transcript.squeeze_challenge_scalar(); - - // Sample gamma challenge - let gamma: ChallengeGamma<_> = transcript.squeeze_challenge_scalar(); - - // Commit to permutations. - let permutations: Vec> = instance - .iter() - .zip(advice.iter()) - .map(|(instance, advice)| { - pk.vk.cs.permutation.commit( - params, - pk, - &pk.permutation, - &advice.advice_polys, - &pk.fixed_values, - &instance.instance_values, - beta, - gamma, - &mut rng, - transcript, - ) - }) - .collect::, _>>()?; - - let lookups: Vec>> = lookups - .into_iter() - .map(|lookups| -> Result, _> { - // Construct and commit to products for each lookup - lookups - .into_iter() - .map(|lookup| lookup.commit_product(pk, params, beta, gamma, &mut rng, transcript)) - .collect::, _>>() - }) - .collect::, _>>()?; - - let shuffles: Vec>> = instance - .iter() - .zip(advice.iter()) - .map(|(instance, advice)| -> Result, _> { - // Compress expressions for each shuffle - pk.vk - .cs - .shuffles - .iter() - .map(|shuffle| { - shuffle.commit_product( - pk, - params, - domain, - theta, - gamma, - &advice.advice_polys, - &pk.fixed_values, - &instance.instance_values, - &challenges, - &mut rng, - transcript, - ) - }) - .collect::, _>>() - }) - .collect::, _>>()?; - - // Commit to the vanishing argument's random polynomial for blinding h(x_3) - let vanishing = vanishing::Argument::commit(params, domain, &mut rng, transcript)?; - - // Obtain challenge for keeping all separate gates linearly independent - let y: ChallengeY<_> = transcript.squeeze_challenge_scalar(); - - // Calculate the advice polys - let advice: Vec> = advice - .into_iter() - .map( - |AdviceSingle { - advice_polys, - advice_blinds, - }| { - AdviceSingle { - advice_polys: advice_polys - .into_iter() - .map(|poly| domain.lagrange_to_coeff(poly)) - .collect::>(), - advice_blinds, - } - }, - ) - .collect(); - - // Evaluate the h(X) polynomial - let h_poly = pk.ev.evaluate_h( - pk, - &advice - .iter() - .map(|a| a.advice_polys.as_slice()) - .collect::>(), - &instance - .iter() - .map(|i| i.instance_polys.as_slice()) - .collect::>(), - &challenges, - *y, - *beta, - *gamma, - *theta, - &lookups, - &shuffles, - &permutations, - ); - - // Construct the vanishing argument's h(X) commitments - let vanishing = vanishing.construct(params, domain, h_poly, &mut rng, transcript)?; - - let x: ChallengeX<_> = transcript.squeeze_challenge_scalar(); - let xn = x.pow([params.n()]); - - if P::QUERY_INSTANCE { - // Compute and hash instance evals for each circuit instance - for instance in instance.iter() { - // Evaluate polynomials at omega^i x - let instance_evals: Vec<_> = meta - .instance_queries - .iter() - .map(|&(column, at)| { - eval_polynomial( - &instance.instance_polys[column.index()], - domain.rotate_omega(*x, at), - ) - }) - .collect(); - - // Hash each instance column evaluation - for eval in instance_evals.iter() { - transcript.write_scalar(*eval)?; - } - } - } - - // Compute and hash advice evals for each circuit instance - for advice in advice.iter() { - // Evaluate polynomials at omega^i x - let advice_evals: Vec<_> = meta - .advice_queries - .iter() - .map(|&(column, at)| { - eval_polynomial( - &advice.advice_polys[column.index()], - domain.rotate_omega(*x, at), - ) - }) - .collect(); - - // Hash each advice column evaluation - for eval in advice_evals.iter() { - transcript.write_scalar(*eval)?; - } - } - - // Compute and hash fixed evals (shared across all circuit instances) - let fixed_evals: Vec<_> = meta - .fixed_queries - .iter() - .map(|&(column, at)| { - eval_polynomial(&pk.fixed_polys[column.index()], domain.rotate_omega(*x, at)) - }) - .collect(); - - // Hash each fixed column evaluation - for eval in fixed_evals.iter() { - transcript.write_scalar(*eval)?; - } - - let vanishing = vanishing.evaluate(x, xn, domain, transcript)?; - - // Evaluate common permutation data - pk.permutation.evaluate(x, transcript)?; - - // Evaluate the permutations, if any, at omega^i x. - let permutations: Vec> = permutations - .into_iter() - .map(|permutation| -> Result<_, _> { permutation.construct().evaluate(pk, x, transcript) }) - .collect::, _>>()?; - - // Evaluate the lookups, if any, at omega^i x. - let lookups: Vec>> = lookups - .into_iter() - .map(|lookups| -> Result, _> { - lookups - .into_iter() - .map(|p| p.evaluate(pk, x, transcript)) - .collect::, _>>() - }) - .collect::, _>>()?; - - // Evaluate the shuffles, if any, at omega^i x. - let shuffles: Vec>> = shuffles - .into_iter() - .map(|shuffles| -> Result, _> { - shuffles - .into_iter() - .map(|p| p.evaluate(pk, x, transcript)) - .collect::, _>>() - }) - .collect::, _>>()?; - - let instances = instance - .iter() - .zip(advice.iter()) - .zip(permutations.iter()) - .zip(lookups.iter()) - .zip(shuffles.iter()) - .flat_map(|((((instance, advice), permutation), lookups), shuffles)| { - iter::empty() - .chain( - P::QUERY_INSTANCE - .then_some(pk.vk.cs.instance_queries.iter().map(move |&(column, at)| { - ProverQuery { - point: domain.rotate_omega(*x, at), - poly: &instance.instance_polys[column.index()], - blind: Blind::default(), - } - })) - .into_iter() - .flatten(), - ) - .chain( - pk.vk - .cs - .advice_queries - .iter() - .map(move |&(column, at)| ProverQuery { - point: domain.rotate_omega(*x, at), - poly: &advice.advice_polys[column.index()], - blind: advice.advice_blinds[column.index()], - }), - ) - .chain(permutation.open(pk, x)) - .chain(lookups.iter().flat_map(move |p| p.open(pk, x))) - .chain(shuffles.iter().flat_map(move |p| p.open(pk, x))) - }) - .chain( - pk.vk - .cs - .fixed_queries - .iter() - .map(|&(column, at)| ProverQuery { - point: domain.rotate_omega(*x, at), - poly: &pk.fixed_polys[column.index()], - blind: Blind::default(), - }), - ) - .chain(pk.permutation.open(x)) - // We query the h(X) polynomial at x - .chain(vanishing.open(x)); - - let prover = P::new(params); - prover - .create_proof(rng, transcript, instances) - .map_err(|_| Error::ConstraintSystemFailure) -} - #[test] fn test_create_proof() { use crate::{ circuit::SimpleFloorPlanner, - plonk::{keygen_pk, keygen_vk}, + plonk::{keygen_pk, keygen_vk, ConstraintSystem}, poly::kzg::{ commitment::{KZGCommitmentScheme, ParamsKZG}, multiopen::ProverSHPLONK, diff --git a/halo2_proofs/src/poly/kzg/strategy.rs b/halo2_proofs/src/poly/kzg/strategy.rs index 5e1a9cfa8e..14b6565b80 100644 --- a/halo2_proofs/src/poly/kzg/strategy.rs +++ b/halo2_proofs/src/poly/kzg/strategy.rs @@ -102,7 +102,7 @@ where self.msm_accumulator.scale(E::Scalar::random(OsRng)); // Guard is updated with new msm contributions - let guard = f(self.msm_accumulator).expect("todo"); + let guard = f(self.msm_accumulator)?; Ok(Self { msm_accumulator: guard.msm_accumulator, }) @@ -144,7 +144,6 @@ where if msm.check() { Ok(()) } else { - println!("OH NO"); Err(Error::ConstraintSystemFailure) } } diff --git a/halo2_proofs/tests/frontend_backend_split.rs b/halo2_proofs/tests/frontend_backend_split.rs index 34a71ff59b..8144ae8c18 100644 --- a/halo2_proofs/tests/frontend_backend_split.rs +++ b/halo2_proofs/tests/frontend_backend_split.rs @@ -5,27 +5,20 @@ #[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc; -use assert_matches::assert_matches; -use ff::{FromUniformBytes, WithSmallOrderMulGroup}; use halo2_proofs::arithmetic::Field; -use halo2_proofs::circuit::{AssignedCell, Cell, Layouter, Region, SimpleFloorPlanner, Value}; +use halo2_proofs::circuit::{AssignedCell, Layouter, Region, SimpleFloorPlanner, Value}; use halo2_proofs::dev::MockProver; use halo2_proofs::plonk::{ compile_circuit, keygen_pk_v2, keygen_vk_v2, verify_proof, verify_proof_single, Advice, - Assigned, Challenge, Circuit, Column, CompiledCircuitV2, ConstraintSystem, - ConstraintSystemV2Backend, Error, Expression, FirstPhase, Fixed, Instance, ProverV2Single, - ProvingKey, SecondPhase, Selector, TableColumn, VerifyingKey, WitnessCalculator, + Challenge, Circuit, Column, ConstraintSystem, Error, Expression, FirstPhase, Fixed, Instance, + ProverV2Single, SecondPhase, Selector, WitnessCalculator, }; -use halo2_proofs::poly::commitment::{CommitmentScheme, ParamsProver, Prover, Verifier}; +use halo2_proofs::poly::commitment::ParamsProver; use halo2_proofs::poly::Rotation; -use halo2_proofs::poly::VerificationStrategy; use halo2_proofs::transcript::{ - Blake2bRead, Blake2bWrite, Challenge255, EncodedChallenge, TranscriptReadBuffer, - TranscriptWriterBuffer, + Blake2bRead, Blake2bWrite, Challenge255, TranscriptReadBuffer, TranscriptWriterBuffer, }; -use rand_core::{OsRng, RngCore}; use std::collections::HashMap; -use std::marker::PhantomData; #[derive(Clone)] struct MyCircuitConfig { @@ -428,7 +421,7 @@ impl, const WIDTH_FACTOR: usize> Circuit for MyCircuit, const WIDTH_FACTOR: usize> Circuit for MyCircuit = MyCircuit::new(k, 42); diff --git a/scratch b/scratch deleted file mode 100644 index ab22c18135..0000000000 --- a/scratch +++ /dev/null @@ -1,137 +0,0 @@ -DBG collected queries -Queries { - advice: [ - ( - Column { - index: 0, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ( - Column { - index: 0, - column_type: Advice, - }, - Rotation( - 1, - ), - ), - ( - Column { - index: 1, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ( - Column { - index: 2, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ], - instance: [], - fixed: [ - ( - Column { - index: 0, - column_type: Fixed, - }, - Rotation( - 0, - ), - ), - ( - Column { - index: 5, - column_type: Fixed, - }, - Rotation( - 0, - ), - ), - ], - num_advice_queries: [ - 2, - 1, - 1, - 0, - ], -} -DBG collected queries -Queries { - advice: [ - ( - Column { - index: 0, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ( - Column { - index: 0, - column_type: Advice, - }, - Rotation( - 1, - ), - ), - ( - Column { - index: 1, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ( - Column { - index: 2, - column_type: Advice, - }, - Rotation( - 0, - ), - ), - ], - instance: [], - fixed: [ - ( - Column { - index: 0, - column_type: Fixed, - }, - Rotation( - 0, - ), - ), - ( # EXTRA - Column { - index: 5, - column_type: Fixed, - }, - Rotation( - 0, - ), - ), - ], - num_advice_queries: [ - 2, - 1, - 1, - 0, - ], -} -