From 19c1b20063d1a5eaef78d263844acdfd58f12200 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Tue, 1 Dec 2020 17:11:47 +0800 Subject: [PATCH] Add lookup::verifier methods --- src/plonk/lookup/verifier.rs | 159 ++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 3 deletions(-) diff --git a/src/plonk/lookup/verifier.rs b/src/plonk/lookup/verifier.rs index 594644e..c22ede1 100644 --- a/src/plonk/lookup/verifier.rs +++ b/src/plonk/lookup/verifier.rs @@ -1,4 +1,157 @@ -use super::Proof; -use crate::arithmetic::CurveAffine; +use std::iter; -impl Proof {} +use super::super::circuit::Any; +use super::{Argument, Proof}; +use crate::{ + arithmetic::CurveAffine, + plonk::{ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, VerifyingKey}, + poly::{multiopen::VerifierQuery, Rotation}, + transcript::{Hasher, Transcript}, +}; +use ff::Field; + +impl Proof { + pub(crate) fn absorb_permuted_commitments< + HBase: Hasher, + HScalar: Hasher, + >( + &self, + transcript: &mut Transcript, + ) -> Result<(), Error> { + transcript + .absorb_point(&self.permuted_input_commitment) + .map_err(|_| Error::TranscriptError)?; + transcript + .absorb_point(&self.permuted_table_commitment) + .map_err(|_| Error::TranscriptError)?; + Ok(()) + } + + pub(crate) fn absorb_product_commitment, HScalar: Hasher>( + &self, + transcript: &mut Transcript, + ) -> Result<(), Error> { + transcript + .absorb_point(&self.product_commitment) + .map_err(|_| Error::TranscriptError)?; + Ok(()) + } + + pub(in crate::plonk) fn expressions<'a>( + &'a self, + vk: &'a VerifyingKey, + l_0: C::Scalar, + argument: Argument, + theta: ChallengeTheta, + beta: ChallengeBeta, + gamma: ChallengeGamma, + advice_evals: &[C::Scalar], + fixed_evals: &[C::Scalar], + aux_evals: &[C::Scalar], + ) -> impl Iterator + 'a { + let product_expression = || { + // z'(X) (a'(X) + \beta) (s'(X) + \gamma) + // - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma) + let left = self.product_eval + * &(self.permuted_input_eval + &beta) + * &(self.permuted_table_eval + &gamma); + + let mut right = self.product_inv_eval; + let mut input_term = C::Scalar::zero(); + for &input in argument.input_columns.iter() { + let index = vk.cs.get_any_query_index(input, 0); + let eval = match input.column_type() { + Any::Advice => advice_evals[index], + Any::Fixed => fixed_evals[index], + Any::Aux => aux_evals[index], + }; + input_term *= θ + input_term += &eval; + } + input_term += β + + let mut table_term = C::Scalar::zero(); + for &table in argument.table_columns.iter() { + let index = vk.cs.get_any_query_index(table, 0); + let eval = match table.column_type() { + Any::Advice => advice_evals[index], + Any::Fixed => fixed_evals[index], + Any::Aux => aux_evals[index], + }; + table_term *= θ + table_term += &eval; + } + table_term += γ + + right *= &(input_term * &table_term); + left - &right + }; + + std::iter::empty() + .chain( + // l_0(X) * (1 - z'(X)) = 0 + Some(l_0 * &(C::Scalar::one() - &self.product_eval)), + ) + .chain( + // z'(X) (a'(X) + \beta) (s'(X) + \gamma) + // - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma) + Some(product_expression()), + ) + .chain(Some( + l_0 * &(self.permuted_input_eval - &self.permuted_table_eval), + )) + .chain(Some( + (self.permuted_input_eval - &self.permuted_table_eval) + * &(self.permuted_input_eval - &self.permuted_input_inv_eval), + )) + } + + pub(crate) fn evals(&self) -> impl Iterator { + iter::empty() + .chain(Some(self.product_eval)) + .chain(Some(self.product_inv_eval)) + .chain(Some(self.permuted_input_eval)) + .chain(Some(self.permuted_input_inv_eval)) + .chain(Some(self.permuted_table_eval)) + } + + pub(in crate::plonk) fn queries<'a>( + &'a self, + vk: &'a VerifyingKey, + x: ChallengeX, + ) -> impl Iterator> + Clone { + let x_inv = vk.domain.rotate_omega(*x, Rotation(-1)); + + iter::empty() + // Open lookup product commitments at x + .chain(Some(VerifierQuery { + point: *x, + commitment: &self.product_commitment, + eval: self.product_eval, + })) + // Open lookup input commitments at x + .chain(Some(VerifierQuery { + point: *x, + commitment: &self.permuted_input_commitment, + eval: self.permuted_input_eval, + })) + // Open lookup table commitments at x + .chain(Some(VerifierQuery { + point: *x, + commitment: &self.permuted_table_commitment, + eval: self.permuted_table_eval, + })) + // Open lookup input commitments at \omega^{-1} x + .chain(Some(VerifierQuery { + point: x_inv, + commitment: &self.permuted_input_commitment, + eval: self.permuted_input_inv_eval, + })) + // Open lookup product commitments at \omega^{-1} x + .chain(Some(VerifierQuery { + point: x_inv, + commitment: &self.product_commitment, + eval: self.product_inv_eval, + })) + } +}