halo2/src/plonk/lookup/verifier.rs

211 lines
7.1 KiB
Rust
Raw Normal View History

2020-12-01 01:11:47 -08:00
use std::iter;
2020-11-30 22:53:20 -08:00
2021-04-12 23:47:25 -07:00
use super::super::{
circuit::Expression, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX,
};
use super::Argument;
2020-12-01 01:11:47 -08:00
use crate::{
2021-02-10 03:36:25 -08:00
arithmetic::{CurveAffine, FieldExt},
2021-04-12 23:47:25 -07:00
plonk::{Error, VerifyingKey},
2020-12-01 01:11:47 -08:00
poly::{multiopen::VerifierQuery, Rotation},
transcript::{EncodedChallenge, TranscriptRead},
2020-12-01 01:11:47 -08:00
};
use ff::Field;
pub struct PermutationCommitments<C: CurveAffine> {
permuted_input_commitment: C,
permuted_table_commitment: C,
}
pub struct Committed<C: CurveAffine> {
2021-01-13 14:44:37 -08:00
permuted: PermutationCommitments<C>,
product_commitment: C,
}
pub struct Evaluated<C: CurveAffine> {
committed: Committed<C>,
product_eval: C::Scalar,
product_inv_eval: C::Scalar,
permuted_input_eval: C::Scalar,
permuted_input_inv_eval: C::Scalar,
permuted_table_eval: C::Scalar,
}
2021-02-10 03:36:25 -08:00
impl<F: FieldExt> Argument<F> {
2021-04-12 23:47:25 -07:00
pub(in crate::plonk) fn read_permuted_commitments<
C: CurveAffine,
E: EncodedChallenge<C>,
T: TranscriptRead<C, E>,
2021-04-12 23:47:25 -07:00
>(
2020-12-01 01:11:47 -08:00
&self,
transcript: &mut T,
) -> Result<PermutationCommitments<C>, Error> {
let permuted_input_commitment = transcript
.read_point()
.map_err(|_| Error::TranscriptError)?;
let permuted_table_commitment = transcript
.read_point()
2020-12-01 01:11:47 -08:00
.map_err(|_| Error::TranscriptError)?;
Ok(PermutationCommitments {
permuted_input_commitment,
permuted_table_commitment,
})
2020-12-01 01:11:47 -08:00
}
}
2020-12-01 01:11:47 -08:00
impl<C: CurveAffine> PermutationCommitments<C> {
2021-04-12 23:47:25 -07:00
pub(in crate::plonk) fn read_product_commitment<
E: EncodedChallenge<C>,
T: TranscriptRead<C, E>,
2021-04-12 23:47:25 -07:00
>(
self,
transcript: &mut T,
) -> Result<Committed<C>, Error> {
let product_commitment = transcript
.read_point()
.map_err(|_| Error::TranscriptError)?;
Ok(Committed {
2021-01-13 14:44:37 -08:00
permuted: self,
product_commitment,
})
2020-12-01 01:11:47 -08:00
}
}
impl<C: CurveAffine> Committed<C> {
pub(crate) fn evaluate<E: EncodedChallenge<C>, T: TranscriptRead<C, E>>(
self,
transcript: &mut T,
) -> Result<Evaluated<C>, Error> {
let product_eval = transcript
.read_scalar()
.map_err(|_| Error::TranscriptError)?;
let product_inv_eval = transcript
.read_scalar()
.map_err(|_| Error::TranscriptError)?;
let permuted_input_eval = transcript
.read_scalar()
.map_err(|_| Error::TranscriptError)?;
let permuted_input_inv_eval = transcript
.read_scalar()
.map_err(|_| Error::TranscriptError)?;
let permuted_table_eval = transcript
.read_scalar()
.map_err(|_| Error::TranscriptError)?;
2020-12-01 01:11:47 -08:00
Ok(Evaluated {
committed: self,
product_eval,
product_inv_eval,
permuted_input_eval,
permuted_input_inv_eval,
permuted_table_eval,
})
}
}
impl<C: CurveAffine> Evaluated<C> {
2020-12-01 01:11:47 -08:00
pub(in crate::plonk) fn expressions<'a>(
&'a self,
l_0: C::Scalar,
2021-02-10 03:36:25 -08:00
argument: &'a Argument<C::Scalar>,
theta: ChallengeTheta<C>,
beta: ChallengeBeta<C>,
gamma: ChallengeGamma<C>,
2020-12-01 01:11:47 -08:00
advice_evals: &[C::Scalar],
fixed_evals: &[C::Scalar],
instance_evals: &[C::Scalar],
2020-12-01 01:11:47 -08:00
) -> impl Iterator<Item = C::Scalar> + 'a {
let product_expression = || {
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
// - z'(\omega^{-1} X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma)
2020-12-01 01:11:47 -08:00
let left = self.product_eval
* &(self.permuted_input_eval + &*beta)
* &(self.permuted_table_eval + &*gamma);
2020-12-01 01:11:47 -08:00
let compress_expressions = |expressions: &[Expression<C::Scalar>]| {
expressions
.iter()
.map(|expression| {
expression.evaluate(
2021-02-13 02:36:29 -08:00
&|scalar| scalar,
&|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)
};
let right = self.product_inv_eval
* &(compress_expressions(&argument.input_expressions) + &*beta)
* &(compress_expressions(&argument.table_expressions) + &*gamma);
2020-12-01 01:11:47 -08:00
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) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma)
2020-12-01 01:11:47 -08:00
Some(product_expression()),
)
.chain(Some(
// l_0(X) * (a'(X) - s'(X)) = 0
2020-12-01 01:11:47 -08:00
l_0 * &(self.permuted_input_eval - &self.permuted_table_eval),
))
.chain(Some(
// (a(X)s(X))⋅(a(X)a(\omega{-1} X)) = 0
2020-12-01 01:11:47 -08:00
(self.permuted_input_eval - &self.permuted_table_eval)
* &(self.permuted_input_eval - &self.permuted_input_inv_eval),
))
}
pub(in crate::plonk) fn queries<'r, 'params: 'r>(
&'r self,
vk: &'r VerifyingKey<C>,
x: ChallengeX<C>,
) -> impl Iterator<Item = VerifierQuery<'r, 'params, C>> + Clone {
2020-12-01 01:11:47 -08:00
let x_inv = vk.domain.rotate_omega(*x, Rotation(-1));
iter::empty()
// Open lookup product commitments at x
.chain(Some(VerifierQuery::new_commitment(
&self.committed.product_commitment,
*x,
self.product_eval,
)))
2020-12-01 01:11:47 -08:00
// Open lookup input commitments at x
.chain(Some(VerifierQuery::new_commitment(
&self.committed.permuted.permuted_input_commitment,
*x,
self.permuted_input_eval,
)))
2020-12-01 01:11:47 -08:00
// Open lookup table commitments at x
.chain(Some(VerifierQuery::new_commitment(
&self.committed.permuted.permuted_table_commitment,
*x,
self.permuted_table_eval,
)))
2020-12-01 01:11:47 -08:00
// Open lookup input commitments at \omega^{-1} x
.chain(Some(VerifierQuery::new_commitment(
&self.committed.permuted.permuted_input_commitment,
x_inv,
self.permuted_input_inv_eval,
)))
2020-12-01 01:11:47 -08:00
// Open lookup product commitments at \omega^{-1} x
.chain(Some(VerifierQuery::new_commitment(
&self.committed.product_commitment,
x_inv,
self.product_inv_eval,
)))
2020-12-01 01:11:47 -08:00
}
}