diff --git a/src/plonk.rs b/src/plonk.rs index 38f9ab4..205613b 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -472,7 +472,7 @@ fn test_proving() { let sl_ = meta.query_any(sl.into(), Rotation::cur()); let sl2_ = meta.query_any(sl2.into(), Rotation::cur()); meta.lookup(&[a_.clone()], &[sl_.clone()]); - meta.lookup(&[a_, b_], &[sl_, sl2_]); + meta.lookup(&[a_ + b_], &[sl_ + sl2_]); meta.create_gate("Combined add-mult", |meta| { let d = meta.query_advice(d, Rotation::next()); diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 61b4ed7..d4d8631 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -15,10 +15,8 @@ pub trait ColumnType: 'static + Sized + std::fmt::Debug {} /// A column with an index and type #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub struct Column { - /// Index of column - pub index: usize, - /// Type of column - pub column_type: C, + index: usize, + column_type: C, } impl Column { diff --git a/src/plonk/lookup/prover.rs b/src/plonk/lookup/prover.rs index 3b6ad94..5530433 100644 --- a/src/plonk/lookup/prover.rs +++ b/src/plonk/lookup/prover.rs @@ -1,6 +1,6 @@ use super::super::{ - circuit::{Advice, Aux, Column, Expression, Fixed}, - ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, ProvingKey, + circuit::Expression, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, + ProvingKey, }; use super::Argument; use crate::{ @@ -13,20 +13,24 @@ use crate::{ transcript::TranscriptWrite, }; use ff::Field; -use std::{collections::BTreeMap, iter}; +use std::{ + collections::BTreeMap, + iter, + ops::{Mul, MulAssign}, +}; #[derive(Debug)] -pub(in crate::plonk) struct Permuted<'a, C: CurveAffine> { - unpermuted_input_columns: Vec<&'a Polynomial>, - unpermuted_input_cosets: Vec<&'a Polynomial>, +pub(in crate::plonk) struct Permuted { + unpermuted_input_columns: Vec>, + unpermuted_input_cosets: Vec>, permuted_input_column: Polynomial, permuted_input_poly: Polynomial, permuted_input_coset: Polynomial, permuted_input_inv_coset: Polynomial, permuted_input_blind: Blind, permuted_input_commitment: C, - unpermuted_table_columns: Vec<&'a Polynomial>, - unpermuted_table_cosets: Vec<&'a Polynomial>, + unpermuted_table_columns: Vec>, + unpermuted_table_cosets: Vec>, permuted_table_column: Polynomial, permuted_table_poly: Polynomial, permuted_table_coset: Polynomial, @@ -35,8 +39,8 @@ pub(in crate::plonk) struct Permuted<'a, C: CurveAffine> { } #[derive(Debug)] -pub(in crate::plonk) struct Committed<'a, C: CurveAffine> { - permuted: Permuted<'a, C>, +pub(in crate::plonk) struct Committed { + permuted: Permuted, product_poly: Polynomial, product_coset: Polynomial, product_inv_coset: Polynomial, @@ -67,7 +71,7 @@ impl Argument { /// - constructs Permuted struct using permuted_input_value = A', and /// permuted_table_column = S'. /// The Permuted struct is used to update the Lookup, and is then returned. - pub(in crate::plonk) fn commit_permuted<'a, C: CurveAffine, T: TranscriptWrite>( + pub(in crate::plonk) fn commit_permuted<'a, C, T: TranscriptWrite>( &self, pk: &ProvingKey, params: &Params, @@ -80,31 +84,56 @@ impl Argument { fixed_cosets: &'a [Polynomial], instance_cosets: &'a [Polynomial], transcript: &mut T, - ) -> Result, Error> { + ) -> Result, Error> + where + C: CurveAffine, + C::Projective: Mul + MulAssign, + { // Closure to get values of columns and compress them - let compress_columns = |columns: &[Expression]| { + let compress_columns = |columns: &[Expression]| { // Values of input columns involved in the lookup - let (unpermuted_columns, unpermuted_cosets): (Vec<_>, Vec<_>) = columns + let unpermuted_columns: Vec<_> = columns .iter() .map(|column| { - match column { - Expression::Advice(index) => { - let column_index = pk.vk.cs.advice_queries[*index].0.index(); - (&advice_values[column_index], &advice_cosets[*index]) - } - Expression::Fixed(index) => { - let column_index = pk.vk.cs.fixed_queries[*index].0.index(); - (&fixed_values[column_index], &fixed_cosets[*index]) - } - Expression::Instance(index) => { - let column_index = pk.vk.cs.instance_queries[*index].0.index(); - (&instance_values[column_index], &instance_cosets[*index]) - } - // TODO: other Expression variants - _ => unreachable!(), - } + column.evaluate( + &|index| { + let column_index = pk.vk.cs.fixed_queries[index].0.index(); + fixed_values[column_index].clone() + }, + &|index| { + let column_index = pk.vk.cs.advice_queries[index].0.index(); + advice_values[column_index].clone() + }, + &|index| { + let column_index = pk.vk.cs.instance_queries[index].0.index(); + instance_values[column_index].clone() + }, + &|a, b| a + &b, + &|a, b| { + let a = &mut a.clone(); + for (a_, b_) in a.iter_mut().zip(b.iter()) { + *a_ *= b_; + } + a.clone() + }, + &|a, scalar| a * scalar, + ) }) - .unzip(); + .collect(); + + let unpermuted_cosets: Vec<_> = columns + .iter() + .map(|column| { + column.evaluate( + &|index| fixed_cosets[index].clone(), + &|index| advice_cosets[index].clone(), + &|index| instance_cosets[index].clone(), + &|a, b| a + &b, + &|a, b| a * &b, + &|a, scalar| a * scalar, + ) + }) + .collect(); // Compressed version of columns let compressed_column = unpermuted_columns @@ -185,7 +214,7 @@ impl Argument { } } -impl<'a, C: CurveAffine> Permuted<'a, C> { +impl Permuted { /// Given a Lookup with input columns, table columns, and the permuted /// input column and permuted table column, this method constructs the /// grand product polynomial over the lookup. The grand product polynomial @@ -199,7 +228,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> { beta: ChallengeBeta, gamma: ChallengeGamma, transcript: &mut T, - ) -> Result, Error> { + ) -> Result, Error> { // Goal is to compute the products of fractions // // Numerator: (\theta^{m-1} a_0(\omega^i) + \theta^{m-2} a_1(\omega^i) + ... + \theta a_{m-2}(\omega^i) + a_{m-1}(\omega^i) + \beta) @@ -327,7 +356,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> { .write_point(product_commitment) .map_err(|_| Error::TranscriptError)?; - Ok(Committed::<'a, C> { + Ok(Committed:: { permuted: self, product_poly: z, product_coset, @@ -338,7 +367,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> { } } -impl<'a, C: CurveAffine> Committed<'a, C> { +impl<'a, C: CurveAffine> Committed { /// Given a Lookup with input columns, table columns, permuted input /// column, permuted table column, and grand product polynomial, this /// method constructs constraints that must hold between these values. diff --git a/src/plonk/lookup/verifier.rs b/src/plonk/lookup/verifier.rs index 9be04cf..14dee34 100644 --- a/src/plonk/lookup/verifier.rs +++ b/src/plonk/lookup/verifier.rs @@ -1,6 +1,6 @@ use std::iter; -use super::super::circuit::{Advice, Aux, Column, Expression, Fixed}; +use super::super::circuit::Expression; use super::Argument; use crate::{ arithmetic::{CurveAffine, FieldExt}, @@ -99,7 +99,6 @@ impl Committed { impl Evaluated { pub(in crate::plonk) fn expressions<'a>( &'a self, - vk: &'a VerifyingKey, l_0: C::Scalar, argument: &'a Argument, theta: ChallengeTheta, @@ -120,13 +119,14 @@ impl Evaluated { columns .iter() .map(|column| { - match column { - Expression::Advice(index) => advice_evals[*index], - Expression::Fixed(index) => fixed_evals[*index], - Expression::Instance(index) => instance_evals[*index], - // TODO: other Expression variants - _ => unreachable!(), - } + column.evaluate( + &|index| fixed_evals[index], + &|index| advice_evals[index], + &|index| instance_evals[index], + &|a, b| a + &b, + &|a, b| a * &b, + &|a, scalar| a * scalar, + ) }) .fold(C::Scalar::zero(), |acc, eval| acc * &*theta + &eval) }; diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 15ec08b..ed43f5b 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -246,7 +246,7 @@ pub fn create_proof, ConcreteCircuit: Circ // Sample theta challenge for keeping lookup columns linearly independent let theta = ChallengeTheta::get(transcript); - let lookups: Vec>> = instance + let lookups: Vec>> = instance .iter() .zip(advice.iter()) .map(|(instance, advice)| -> Result, Error> { @@ -307,7 +307,7 @@ pub fn create_proof, ConcreteCircuit: Circ }) .collect::, _>>()?; - let lookups: Vec>> = lookups + let lookups: Vec>> = lookups .into_iter() .map(|lookups| -> Result, _> { // Construct and commit to products for each lookup diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index f1f09d2..c854901 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -201,7 +201,6 @@ pub fn verify_proof<'a, C: CurveAffine, T: TranscriptRead>( .zip(vk.cs.lookups.iter()) .flat_map(move |(p, argument)| { p.expressions( - vk, l_0, argument, theta,