mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-05 20:10:32 +00:00
Use lookup mod in plonk::prover and plonk::verifier
This commit is contained in:
parent
19c1b20063
commit
0c81e9adab
7 changed files with 181 additions and 46 deletions
|
|
@ -53,6 +53,7 @@ pub struct Proof<C: CurveAffine> {
|
||||||
advice_commitments: Vec<C>,
|
advice_commitments: Vec<C>,
|
||||||
h_commitments: Vec<C>,
|
h_commitments: Vec<C>,
|
||||||
permutations: Option<permutation::Proof<C>>,
|
permutations: Option<permutation::Proof<C>>,
|
||||||
|
lookups: Vec<lookup::Proof<C>>,
|
||||||
advice_evals: Vec<C::Scalar>,
|
advice_evals: Vec<C::Scalar>,
|
||||||
aux_evals: Vec<C::Scalar>,
|
aux_evals: Vec<C::Scalar>,
|
||||||
fixed_evals: Vec<C::Scalar>,
|
fixed_evals: Vec<C::Scalar>,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use ff::Field;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use super::{permutation, Error};
|
use super::{lookup, permutation, Error};
|
||||||
use crate::poly::Rotation;
|
use crate::poly::Rotation;
|
||||||
|
|
||||||
/// A column type
|
/// A column type
|
||||||
|
|
@ -313,6 +313,10 @@ pub struct ConstraintSystem<F> {
|
||||||
// Vector of permutation arguments, where each corresponds to a sequence of columns
|
// Vector of permutation arguments, where each corresponds to a sequence of columns
|
||||||
// that are involved in a permutation argument.
|
// that are involved in a permutation argument.
|
||||||
pub(crate) permutations: Vec<permutation::Argument>,
|
pub(crate) permutations: Vec<permutation::Argument>,
|
||||||
|
|
||||||
|
// Vector of lookup arguments, where each corresponds to a sequence of
|
||||||
|
// input columns and a sequence of table columns involved in the lookup.
|
||||||
|
pub(crate) lookups: Vec<lookup::Argument>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> Default for ConstraintSystem<F> {
|
impl<F: Field> Default for ConstraintSystem<F> {
|
||||||
|
|
@ -330,6 +334,7 @@ impl<F: Field> Default for ConstraintSystem<F> {
|
||||||
aux_queries: Vec::new(),
|
aux_queries: Vec::new(),
|
||||||
rotations,
|
rotations,
|
||||||
permutations: Vec::new(),
|
permutations: Vec::new(),
|
||||||
|
lookups: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use super::circuit::{Any, Column};
|
use super::circuit::{Any, Column};
|
||||||
use crate::arithmetic::CurveAffine;
|
use crate::arithmetic::CurveAffine;
|
||||||
|
|
||||||
mod prover;
|
pub(crate) mod prover;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::super::{
|
use super::super::{
|
||||||
circuit::{Advice, Any, Aux, Column, Fixed},
|
circuit::{Advice, Any, Aux, Column, Fixed},
|
||||||
ChallengeX, Error, ProvingKey,
|
ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, Error, ProvingKey,
|
||||||
};
|
};
|
||||||
use super::{Argument, Proof};
|
use super::{Argument, Proof};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -41,8 +41,8 @@ pub(crate) struct Product<C: CurveAffine> {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct Committed<C: CurveAffine> {
|
pub(crate) struct Committed<C: CurveAffine> {
|
||||||
permuted: Permuted<C>,
|
pub permuted: Permuted<C>,
|
||||||
product: Product<C>,
|
pub product: Product<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Constructed<C: CurveAffine> {
|
pub(crate) struct Constructed<C: CurveAffine> {
|
||||||
|
|
@ -85,7 +85,7 @@ impl Argument {
|
||||||
pk: &ProvingKey<C>,
|
pk: &ProvingKey<C>,
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
domain: &EvaluationDomain<C::Scalar>,
|
domain: &EvaluationDomain<C::Scalar>,
|
||||||
theta: C::Scalar,
|
theta: ChallengeTheta<C::Scalar>,
|
||||||
advice_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
advice_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
fixed_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
fixed_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
aux_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
aux_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
|
|
@ -105,7 +105,7 @@ impl Argument {
|
||||||
// Compressed version of input columns
|
// Compressed version of input columns
|
||||||
let compressed_input_value = unpermuted_input_values
|
let compressed_input_value = unpermuted_input_values
|
||||||
.iter()
|
.iter()
|
||||||
.fold(domain.empty_lagrange(), |acc, input| acc * theta + input);
|
.fold(domain.empty_lagrange(), |acc, input| acc * *theta + input);
|
||||||
|
|
||||||
// Values of table columns involved in the lookup
|
// Values of table columns involved in the lookup
|
||||||
let unpermuted_table_values: Vec<Polynomial<C::Scalar, LagrangeCoeff>> = self
|
let unpermuted_table_values: Vec<Polynomial<C::Scalar, LagrangeCoeff>> = self
|
||||||
|
|
@ -121,7 +121,7 @@ impl Argument {
|
||||||
// Compressed version of table columns
|
// Compressed version of table columns
|
||||||
let compressed_table_value = unpermuted_table_values
|
let compressed_table_value = unpermuted_table_values
|
||||||
.iter()
|
.iter()
|
||||||
.fold(domain.empty_lagrange(), |acc, table| acc * theta + table);
|
.fold(domain.empty_lagrange(), |acc, table| acc * *theta + table);
|
||||||
|
|
||||||
// Permute compressed (InputColumn, TableColumn) pair
|
// Permute compressed (InputColumn, TableColumn) pair
|
||||||
let (permuted_input_value, permuted_table_value) =
|
let (permuted_input_value, permuted_table_value) =
|
||||||
|
|
@ -192,9 +192,9 @@ impl Argument {
|
||||||
permuted: &Permuted<C>,
|
permuted: &Permuted<C>,
|
||||||
pk: &ProvingKey<C>,
|
pk: &ProvingKey<C>,
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
theta: C::Scalar,
|
theta: ChallengeTheta<C::Scalar>,
|
||||||
beta: C::Scalar,
|
beta: ChallengeBeta<C::Scalar>,
|
||||||
gamma: C::Scalar,
|
gamma: ChallengeGamma<C::Scalar>,
|
||||||
advice_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
advice_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
fixed_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
fixed_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
aux_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
aux_values: &[Polynomial<C::Scalar, LagrangeCoeff>],
|
||||||
|
|
@ -240,8 +240,8 @@ impl Argument {
|
||||||
.zip(permuted.permuted_input_value[start..].iter())
|
.zip(permuted.permuted_input_value[start..].iter())
|
||||||
.zip(permuted.permuted_table_value[start..].iter())
|
.zip(permuted.permuted_table_value[start..].iter())
|
||||||
{
|
{
|
||||||
*lookup_product *= &(beta + permuted_input_value);
|
*lookup_product *= &(*beta + permuted_input_value);
|
||||||
*lookup_product *= &(gamma + permuted_table_value);
|
*lookup_product *= &(*gamma + permuted_table_value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -382,10 +382,10 @@ impl<C: CurveAffine> Committed<C> {
|
||||||
pub(in crate::plonk) fn construct<'a>(
|
pub(in crate::plonk) fn construct<'a>(
|
||||||
self,
|
self,
|
||||||
pk: &'a ProvingKey<C>,
|
pk: &'a ProvingKey<C>,
|
||||||
theta: C::Scalar,
|
theta: ChallengeTheta<C::Scalar>,
|
||||||
beta: C::Scalar,
|
beta: ChallengeBeta<C::Scalar>,
|
||||||
gamma: C::Scalar,
|
gamma: ChallengeGamma<C::Scalar>,
|
||||||
argument: Argument,
|
argument: &'a Argument,
|
||||||
advice_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
advice_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
||||||
fixed_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
fixed_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
||||||
aux_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
aux_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
|
||||||
|
|
@ -458,8 +458,8 @@ impl<C: CurveAffine> Committed<C> {
|
||||||
.zip(permuted.permuted_input_coset[start..].iter())
|
.zip(permuted.permuted_input_coset[start..].iter())
|
||||||
.zip(permuted.permuted_table_coset[start..].iter())
|
.zip(permuted.permuted_table_coset[start..].iter())
|
||||||
{
|
{
|
||||||
*left *= &(*permuted_input + &beta);
|
*left *= &(*permuted_input + &(*beta));
|
||||||
*left *= &(*permuted_table + &gamma);
|
*left *= &(*permuted_table + &(*gamma));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -473,7 +473,7 @@ impl<C: CurveAffine> Committed<C> {
|
||||||
parallelize(&mut input_terms, |input_term, start| {
|
parallelize(&mut input_terms, |input_term, start| {
|
||||||
for (input_term, input) in input_term.iter_mut().zip(input[start..].iter())
|
for (input_term, input) in input_term.iter_mut().zip(input[start..].iter())
|
||||||
{
|
{
|
||||||
*input_term *= θ
|
*input_term *= &(*theta);
|
||||||
*input_term += input;
|
*input_term += input;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -486,7 +486,7 @@ impl<C: CurveAffine> Committed<C> {
|
||||||
parallelize(&mut table_terms, |table_term, start| {
|
parallelize(&mut table_terms, |table_term, start| {
|
||||||
for (table_term, table) in table_term.iter_mut().zip(table[start..].iter())
|
for (table_term, table) in table_term.iter_mut().zip(table[start..].iter())
|
||||||
{
|
{
|
||||||
*table_term *= θ
|
*table_term *= &(*theta);
|
||||||
*table_term += table;
|
*table_term += table;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -499,8 +499,8 @@ impl<C: CurveAffine> Committed<C> {
|
||||||
.zip(input_terms[start..].iter())
|
.zip(input_terms[start..].iter())
|
||||||
.zip(table_terms[start..].iter())
|
.zip(table_terms[start..].iter())
|
||||||
{
|
{
|
||||||
*right *= &(*input_term + &beta);
|
*right *= &(*input_term + &(*beta));
|
||||||
*right *= &(*table_term + &gamma);
|
*right *= &(*table_term + &(*gamma));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
&'a self,
|
&'a self,
|
||||||
vk: &'a VerifyingKey<C>,
|
vk: &'a VerifyingKey<C>,
|
||||||
l_0: C::Scalar,
|
l_0: C::Scalar,
|
||||||
argument: Argument,
|
argument: &'a Argument,
|
||||||
theta: ChallengeTheta<C::Scalar>,
|
theta: ChallengeTheta<C::Scalar>,
|
||||||
beta: ChallengeBeta<C::Scalar>,
|
beta: ChallengeBeta<C::Scalar>,
|
||||||
gamma: ChallengeGamma<C::Scalar>,
|
gamma: ChallengeGamma<C::Scalar>,
|
||||||
|
|
@ -106,13 +106,13 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn evals(&self) -> impl Iterator<Item = C::Scalar> {
|
pub(crate) fn evals(&self) -> impl Iterator<Item = &C::Scalar> {
|
||||||
iter::empty()
|
iter::empty()
|
||||||
.chain(Some(self.product_eval))
|
.chain(Some(&self.product_eval))
|
||||||
.chain(Some(self.product_inv_eval))
|
.chain(Some(&self.product_inv_eval))
|
||||||
.chain(Some(self.permuted_input_eval))
|
.chain(Some(&self.permuted_input_eval))
|
||||||
.chain(Some(self.permuted_input_inv_eval))
|
.chain(Some(&self.permuted_input_inv_eval))
|
||||||
.chain(Some(self.permuted_table_eval))
|
.chain(Some(&self.permuted_table_eval))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::plonk) fn queries<'a>(
|
pub(in crate::plonk) fn queries<'a>(
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ use std::iter;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed},
|
circuit::{Advice, Assignment, Circuit, Column, ConstraintSystem, Fixed},
|
||||||
permutation, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY, Error,
|
lookup, permutation, ChallengeBeta, ChallengeGamma, ChallengeTheta, ChallengeX, ChallengeY,
|
||||||
Proof, ProvingKey,
|
Error, Proof, ProvingKey,
|
||||||
};
|
};
|
||||||
use crate::arithmetic::{eval_polynomial, Curve, CurveAffine, FieldExt};
|
use crate::arithmetic::{eval_polynomial, Curve, CurveAffine, FieldExt};
|
||||||
use crate::poly::{
|
use crate::poly::{
|
||||||
|
|
@ -172,6 +172,28 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
// Sample theta challenge for keeping lookup columns linearly independent
|
// Sample theta challenge for keeping lookup columns linearly independent
|
||||||
let theta = ChallengeTheta::<C::Scalar>::get(&mut transcript);
|
let theta = ChallengeTheta::<C::Scalar>::get(&mut transcript);
|
||||||
|
|
||||||
|
// Construct permuted values for each lookup
|
||||||
|
let lookups_permuted = pk
|
||||||
|
.vk
|
||||||
|
.cs
|
||||||
|
.lookups
|
||||||
|
.iter()
|
||||||
|
.map(|lookup| {
|
||||||
|
lookup
|
||||||
|
.commit_permuted(
|
||||||
|
&pk,
|
||||||
|
¶ms,
|
||||||
|
&domain,
|
||||||
|
theta,
|
||||||
|
&witness.advice,
|
||||||
|
&pk.fixed_values,
|
||||||
|
&aux,
|
||||||
|
&mut transcript,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Sample beta challenge
|
// Sample beta challenge
|
||||||
let beta = ChallengeBeta::get(&mut transcript);
|
let beta = ChallengeBeta::get(&mut transcript);
|
||||||
|
|
||||||
|
|
@ -192,6 +214,40 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Construct products for each lookup
|
||||||
|
let lookups_products = pk
|
||||||
|
.vk
|
||||||
|
.cs
|
||||||
|
.lookups
|
||||||
|
.iter()
|
||||||
|
.zip(lookups_permuted.iter())
|
||||||
|
.map(|(lookup, permuted)| {
|
||||||
|
lookup
|
||||||
|
.commit_product(
|
||||||
|
permuted,
|
||||||
|
&pk,
|
||||||
|
¶ms,
|
||||||
|
theta,
|
||||||
|
beta,
|
||||||
|
gamma,
|
||||||
|
&witness.advice,
|
||||||
|
&pk.fixed_values,
|
||||||
|
&aux,
|
||||||
|
&mut transcript,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let lookups = lookups_permuted
|
||||||
|
.iter()
|
||||||
|
.zip(lookups_products.iter())
|
||||||
|
.map(|(permuted, product)| lookup::prover::Committed {
|
||||||
|
permuted: permuted.clone(),
|
||||||
|
product: product.clone(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Obtain challenge for keeping all separate gates linearly independent
|
// Obtain challenge for keeping all separate gates linearly independent
|
||||||
let y = ChallengeY::<C::Scalar>::get(&mut transcript);
|
let y = ChallengeY::<C::Scalar>::get(&mut transcript);
|
||||||
|
|
||||||
|
|
@ -202,6 +258,25 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.map(|(p, expressions)| (Some(p), Some(expressions)))
|
.map(|(p, expressions)| (Some(p), Some(expressions)))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// Evaluate the h(X) polynomial's constraint system expressions for the lookup constraints, if any.
|
||||||
|
let (lookups, lookup_expressions): (Vec<_>, Vec<_>) = lookups
|
||||||
|
.into_iter()
|
||||||
|
.zip(pk.vk.cs.lookups.iter())
|
||||||
|
.map(|(p, argument)| {
|
||||||
|
p.construct(
|
||||||
|
pk,
|
||||||
|
theta,
|
||||||
|
beta,
|
||||||
|
gamma,
|
||||||
|
argument,
|
||||||
|
&advice_cosets,
|
||||||
|
&pk.fixed_cosets,
|
||||||
|
&aux_cosets,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.unzip();
|
||||||
|
|
||||||
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
|
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
|
||||||
let h_poly = iter::empty()
|
let h_poly = iter::empty()
|
||||||
// Custom constraints
|
// Custom constraints
|
||||||
|
|
@ -217,6 +292,8 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
}))
|
}))
|
||||||
// Permutation constraints, if any.
|
// Permutation constraints, if any.
|
||||||
.chain(permutation_expressions.into_iter().flatten())
|
.chain(permutation_expressions.into_iter().flatten())
|
||||||
|
// Lookup constraints, if any.
|
||||||
|
.chain(lookup_expressions.into_iter().flatten())
|
||||||
.fold(domain.empty_extended(), |h_poly, v| h_poly * *y + &v);
|
.fold(domain.empty_extended(), |h_poly, v| h_poly * *y + &v);
|
||||||
|
|
||||||
// Divide by t(X) = X^{params.n} - 1.
|
// Divide by t(X) = X^{params.n} - 1.
|
||||||
|
|
@ -296,6 +373,12 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
// Evaluate the permutations, if any, at omega^i x.
|
// Evaluate the permutations, if any, at omega^i x.
|
||||||
let permutations = permutations.map(|p| p.evaluate(pk, x, &mut transcript));
|
let permutations = permutations.map(|p| p.evaluate(pk, x, &mut transcript));
|
||||||
|
|
||||||
|
// Evaluate the lookups, if any, at omega^i x.
|
||||||
|
let lookups = lookups
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| p.evaluate(pk, x, &mut transcript))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let instances =
|
let instances =
|
||||||
iter::empty()
|
iter::empty()
|
||||||
.chain(pk.vk.cs.advice_queries.iter().enumerate().map(
|
.chain(pk.vk.cs.advice_queries.iter().enumerate().map(
|
||||||
|
|
@ -339,13 +422,15 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
let multiopening = multiopen::Proof::create(
|
let multiopening = multiopen::Proof::create(
|
||||||
params,
|
params,
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
instances.chain(
|
instances
|
||||||
permutations
|
.chain(
|
||||||
.as_ref()
|
permutations
|
||||||
.map(|p| p.open(pk, x))
|
.as_ref()
|
||||||
.into_iter()
|
.map(|p| p.open(pk, x))
|
||||||
.flatten(),
|
.into_iter()
|
||||||
),
|
.flatten(),
|
||||||
|
)
|
||||||
|
.chain(lookups.iter().map(|p| p.open(pk, x)).into_iter().flatten()),
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::OpeningError)?;
|
.map_err(|_| Error::OpeningError)?;
|
||||||
|
|
||||||
|
|
@ -353,6 +438,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
advice_commitments,
|
advice_commitments,
|
||||||
h_commitments,
|
h_commitments,
|
||||||
permutations: permutations.map(|p| p.build()),
|
permutations: permutations.map(|p| p.build()),
|
||||||
|
lookups: lookups.into_iter().map(|p| p.build()).collect::<Vec<_>>(),
|
||||||
advice_evals,
|
advice_evals,
|
||||||
fixed_evals,
|
fixed_evals,
|
||||||
aux_evals,
|
aux_evals,
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,11 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
// Sample theta challenge for keeping lookup columns linearly independent
|
// Sample theta challenge for keeping lookup columns linearly independent
|
||||||
let theta = ChallengeTheta::get(&mut transcript);
|
let theta = ChallengeTheta::get(&mut transcript);
|
||||||
|
|
||||||
|
// Hash each lookup permuted commitment
|
||||||
|
for lookup in &self.lookups {
|
||||||
|
lookup.absorb_permuted_commitments(&mut transcript)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Sample beta challenge
|
// Sample beta challenge
|
||||||
let beta = ChallengeBeta::get(&mut transcript);
|
let beta = ChallengeBeta::get(&mut transcript);
|
||||||
|
|
||||||
|
|
@ -62,6 +67,11 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
p.absorb_commitments(&mut transcript)?;
|
p.absorb_commitments(&mut transcript)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hash each lookup product commitment
|
||||||
|
for lookup in &self.lookups {
|
||||||
|
lookup.absorb_product_commitment(&mut transcript)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Sample y challenge, which keeps the gates linearly independent.
|
// Sample y challenge, which keeps the gates linearly independent.
|
||||||
let y = ChallengeY::get(&mut transcript);
|
let y = ChallengeY::get(&mut transcript);
|
||||||
|
|
||||||
|
|
@ -93,6 +103,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten(),
|
.flatten(),
|
||||||
)
|
)
|
||||||
|
.chain(self.lookups.iter().map(|p| p.evals()).into_iter().flatten())
|
||||||
{
|
{
|
||||||
transcript.absorb_scalar(*eval);
|
transcript.absorb_scalar(*eval);
|
||||||
}
|
}
|
||||||
|
|
@ -142,13 +153,21 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
.verify(
|
.verify(
|
||||||
params,
|
params,
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
queries.chain(
|
queries
|
||||||
self.permutations
|
.chain(
|
||||||
.as_ref()
|
self.permutations
|
||||||
.map(|p| p.queries(vk, x))
|
.as_ref()
|
||||||
.into_iter()
|
.map(|p| p.queries(vk, x))
|
||||||
.flatten(),
|
.into_iter()
|
||||||
),
|
.flatten(),
|
||||||
|
)
|
||||||
|
.chain(
|
||||||
|
self.lookups
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.queries(vk, x))
|
||||||
|
.into_iter()
|
||||||
|
.flatten(),
|
||||||
|
),
|
||||||
msm,
|
msm,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::OpeningError)
|
.map_err(|_| Error::OpeningError)
|
||||||
|
|
@ -180,6 +199,10 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
.map(|p| p.check_lengths(vk))
|
.map(|p| p.check_lengths(vk))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
|
if self.lookups.len() != vk.cs.lookups.len() {
|
||||||
|
return Err(Error::IncompatibleParams);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: check h_commitments
|
// TODO: check h_commitments
|
||||||
|
|
||||||
if self.advice_commitments.len() != vk.cs.num_advice_columns {
|
if self.advice_commitments.len() != vk.cs.num_advice_columns {
|
||||||
|
|
@ -230,6 +253,26 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten(),
|
.flatten(),
|
||||||
)
|
)
|
||||||
|
.chain(
|
||||||
|
self.lookups
|
||||||
|
.iter()
|
||||||
|
.zip(vk.cs.lookups.iter())
|
||||||
|
.map(|(p, argument)| {
|
||||||
|
p.expressions(
|
||||||
|
vk,
|
||||||
|
l_0,
|
||||||
|
argument,
|
||||||
|
theta,
|
||||||
|
beta,
|
||||||
|
gamma,
|
||||||
|
&self.advice_evals,
|
||||||
|
&self.fixed_evals,
|
||||||
|
&self.aux_evals,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.flatten(),
|
||||||
|
)
|
||||||
.fold(C::Scalar::zero(), |h_eval, v| h_eval * &y + &v);
|
.fold(C::Scalar::zero(), |h_eval, v| h_eval * &y + &v);
|
||||||
|
|
||||||
// Compute h(x) from the prover
|
// Compute h(x) from the prover
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue