mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Extract plonk::vanishing::{Argument, Proof} from prover and verifier
Co-authored-by: Jack Grigg <jack@electriccoin.co>
This commit is contained in:
parent
cf734f7875
commit
8360b94f89
6 changed files with 237 additions and 98 deletions
|
|
@ -15,6 +15,8 @@ mod circuit;
|
||||||
mod keygen;
|
mod keygen;
|
||||||
mod lookup;
|
mod lookup;
|
||||||
mod permutation;
|
mod permutation;
|
||||||
|
mod vanishing;
|
||||||
|
|
||||||
mod prover;
|
mod prover;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
|
|
||||||
|
|
@ -51,13 +53,12 @@ pub struct ProvingKey<C: CurveAffine> {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Proof<C: CurveAffine> {
|
pub struct Proof<C: CurveAffine> {
|
||||||
advice_commitments: Vec<C>,
|
advice_commitments: Vec<C>,
|
||||||
h_commitments: Vec<C>,
|
|
||||||
permutations: Option<permutation::Proof<C>>,
|
permutations: Option<permutation::Proof<C>>,
|
||||||
lookups: Vec<lookup::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>,
|
||||||
h_evals: Vec<C::Scalar>,
|
vanishing: vanishing::Proof<C>,
|
||||||
multiopening: multiopen::Proof<C>,
|
multiopening: multiopen::Proof<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
permutation, vanishing, 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::{
|
||||||
|
|
@ -222,7 +222,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<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::get(&mut transcript);
|
||||||
|
|
||||||
// Evaluate the h(X) polynomial's constraint system expressions for the permutation constraints, if any.
|
// Evaluate the h(X) polynomial's constraint system expressions for the permutation constraints, if any.
|
||||||
let (permutations, permutation_expressions) = permutations
|
let (permutations, permutation_expressions) = permutations
|
||||||
|
|
@ -242,7 +242,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 expressions = iter::empty()
|
||||||
// Custom constraints
|
// Custom constraints
|
||||||
.chain(meta.gates.iter().map(|poly| {
|
.chain(meta.gates.iter().map(|poly| {
|
||||||
poly.evaluate(
|
poly.evaluate(
|
||||||
|
|
@ -257,40 +257,11 @@ 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.
|
// Lookup constraints, if any.
|
||||||
.chain(lookup_expressions.into_iter().flatten())
|
.chain(lookup_expressions.into_iter().flatten());
|
||||||
.fold(domain.empty_extended(), |h_poly, v| h_poly * *y + &v);
|
|
||||||
|
|
||||||
// Divide by t(X) = X^{params.n} - 1.
|
// Construct the vanishing argument
|
||||||
let h_poly = domain.divide_by_vanishing_poly(h_poly);
|
let vanishing =
|
||||||
|
vanishing::Argument::construct(params, domain, expressions, y, &mut transcript)?;
|
||||||
// Obtain final h(X) polynomial
|
|
||||||
let h_poly = domain.extended_to_coeff(h_poly);
|
|
||||||
|
|
||||||
// Split h(X) up into pieces
|
|
||||||
let h_pieces = h_poly
|
|
||||||
.chunks_exact(params.n as usize)
|
|
||||||
.map(|v| domain.coeff_from_vec(v.to_vec()))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
drop(h_poly);
|
|
||||||
let h_blinds: Vec<_> = h_pieces.iter().map(|_| Blind(C::Scalar::rand())).collect();
|
|
||||||
|
|
||||||
// Compute commitments to each h(X) piece
|
|
||||||
let h_commitments_projective: Vec<_> = h_pieces
|
|
||||||
.iter()
|
|
||||||
.zip(h_blinds.iter())
|
|
||||||
.map(|(h_piece, blind)| params.commit(&h_piece, *blind))
|
|
||||||
.collect();
|
|
||||||
let mut h_commitments = vec![C::zero(); h_commitments_projective.len()];
|
|
||||||
C::Projective::batch_to_affine(&h_commitments_projective, &mut h_commitments);
|
|
||||||
let h_commitments = h_commitments;
|
|
||||||
drop(h_commitments_projective);
|
|
||||||
|
|
||||||
// Hash each h(X) piece
|
|
||||||
for c in h_commitments.iter() {
|
|
||||||
transcript
|
|
||||||
.absorb_point(c)
|
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = ChallengeX::get(&mut transcript);
|
let x = ChallengeX::get(&mut transcript);
|
||||||
|
|
||||||
|
|
@ -319,21 +290,17 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let h_evals: Vec<_> = h_pieces
|
// Hash each column evaluation
|
||||||
.iter()
|
|
||||||
.map(|poly| eval_polynomial(poly, *x))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Hash each advice evaluation
|
|
||||||
for eval in advice_evals
|
for eval in advice_evals
|
||||||
.iter()
|
.iter()
|
||||||
.chain(aux_evals.iter())
|
.chain(aux_evals.iter())
|
||||||
.chain(fixed_evals.iter())
|
.chain(fixed_evals.iter())
|
||||||
.chain(h_evals.iter())
|
|
||||||
{
|
{
|
||||||
transcript.absorb_scalar(*eval);
|
transcript.absorb_scalar(*eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vanishing = vanishing.evaluate(x, &mut transcript);
|
||||||
|
|
||||||
// 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));
|
||||||
|
|
||||||
|
|
@ -370,18 +337,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
// We query the h(X) polynomial at x
|
// We query the h(X) polynomial at x
|
||||||
.chain(
|
.chain(vanishing.open(x));
|
||||||
h_pieces
|
|
||||||
.iter()
|
|
||||||
.zip(h_blinds.iter())
|
|
||||||
.zip(h_evals.iter())
|
|
||||||
.map(|((h_poly, h_blind), h_eval)| ProverQuery {
|
|
||||||
point: *x,
|
|
||||||
poly: h_poly,
|
|
||||||
blind: *h_blind,
|
|
||||||
eval: *h_eval,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
let multiopening = multiopen::Proof::create(
|
let multiopening = multiopen::Proof::create(
|
||||||
params,
|
params,
|
||||||
|
|
@ -400,13 +356,12 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
Ok(Proof {
|
Ok(Proof {
|
||||||
advice_commitments,
|
advice_commitments,
|
||||||
h_commitments,
|
|
||||||
permutations: permutations.map(|p| p.build()),
|
permutations: permutations.map(|p| p.build()),
|
||||||
lookups: lookups.into_iter().map(|p| p.build()).collect(),
|
lookups: lookups.into_iter().map(|p| p.build()).collect(),
|
||||||
advice_evals,
|
advice_evals,
|
||||||
fixed_evals,
|
fixed_evals,
|
||||||
aux_evals,
|
aux_evals,
|
||||||
h_evals,
|
vanishing: vanishing.build(),
|
||||||
multiopening,
|
multiopening,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/plonk/vanishing.rs
Normal file
17
src/plonk/vanishing.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use crate::arithmetic::CurveAffine;
|
||||||
|
|
||||||
|
mod prover;
|
||||||
|
mod verifier;
|
||||||
|
|
||||||
|
/// A vanishing argument.
|
||||||
|
pub(crate) struct Argument<C: CurveAffine> {
|
||||||
|
_marker: PhantomData<C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct Proof<C: CurveAffine> {
|
||||||
|
h_commitments: Vec<C>,
|
||||||
|
h_evals: Vec<C::Scalar>,
|
||||||
|
}
|
||||||
122
src/plonk/vanishing/prover.rs
Normal file
122
src/plonk/vanishing/prover.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
use super::{Argument, Proof};
|
||||||
|
use crate::{
|
||||||
|
arithmetic::{eval_polynomial, Curve, CurveAffine, FieldExt},
|
||||||
|
plonk::{ChallengeX, ChallengeY, Error},
|
||||||
|
poly::{
|
||||||
|
commitment::{Blind, Params},
|
||||||
|
multiopen::ProverQuery,
|
||||||
|
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, Polynomial,
|
||||||
|
},
|
||||||
|
transcript::{Hasher, Transcript},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(in crate::plonk) struct Constructed<C: CurveAffine> {
|
||||||
|
h_pieces: Vec<Polynomial<C::Scalar, Coeff>>,
|
||||||
|
h_blinds: Vec<Blind<C::Scalar>>,
|
||||||
|
h_commitments: Vec<C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
|
||||||
|
constructed: Constructed<C>,
|
||||||
|
h_evals: Vec<C::Scalar>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: CurveAffine> Argument<C> {
|
||||||
|
pub(in crate::plonk) fn construct<HBase: Hasher<C::Base>, HScalar: Hasher<C::Scalar>>(
|
||||||
|
params: &Params<C>,
|
||||||
|
domain: &EvaluationDomain<C::Scalar>,
|
||||||
|
expressions: impl Iterator<Item = Polynomial<C::Scalar, ExtendedLagrangeCoeff>>,
|
||||||
|
y: ChallengeY<C::Scalar>,
|
||||||
|
transcript: &mut Transcript<C, HBase, HScalar>,
|
||||||
|
) -> Result<Constructed<C>, Error> {
|
||||||
|
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
|
||||||
|
let h_poly = expressions.fold(domain.empty_extended(), |h_poly, v| h_poly * *y + &v);
|
||||||
|
|
||||||
|
// Divide by t(X) = X^{params.n} - 1.
|
||||||
|
let h_poly = domain.divide_by_vanishing_poly(h_poly);
|
||||||
|
|
||||||
|
// Obtain final h(X) polynomial
|
||||||
|
let h_poly = domain.extended_to_coeff(h_poly);
|
||||||
|
|
||||||
|
// Split h(X) up into pieces
|
||||||
|
let h_pieces = h_poly
|
||||||
|
.chunks_exact(params.n as usize)
|
||||||
|
.map(|v| domain.coeff_from_vec(v.to_vec()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
drop(h_poly);
|
||||||
|
let h_blinds: Vec<_> = h_pieces.iter().map(|_| Blind(C::Scalar::rand())).collect();
|
||||||
|
|
||||||
|
// Compute commitments to each h(X) piece
|
||||||
|
let h_commitments_projective: Vec<_> = h_pieces
|
||||||
|
.iter()
|
||||||
|
.zip(h_blinds.iter())
|
||||||
|
.map(|(h_piece, blind)| params.commit(&h_piece, *blind))
|
||||||
|
.collect();
|
||||||
|
let mut h_commitments = vec![C::zero(); h_commitments_projective.len()];
|
||||||
|
C::Projective::batch_to_affine(&h_commitments_projective, &mut h_commitments);
|
||||||
|
let h_commitments = h_commitments;
|
||||||
|
|
||||||
|
// Hash each h(X) piece
|
||||||
|
for c in h_commitments.iter() {
|
||||||
|
transcript
|
||||||
|
.absorb_point(c)
|
||||||
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Constructed {
|
||||||
|
h_pieces,
|
||||||
|
h_blinds,
|
||||||
|
h_commitments,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: CurveAffine> Constructed<C> {
|
||||||
|
pub(in crate::plonk) fn evaluate<HBase: Hasher<C::Base>, HScalar: Hasher<C::Scalar>>(
|
||||||
|
self,
|
||||||
|
x: ChallengeX<C::Scalar>,
|
||||||
|
transcript: &mut Transcript<C, HBase, HScalar>,
|
||||||
|
) -> Evaluated<C> {
|
||||||
|
let h_evals: Vec<_> = self
|
||||||
|
.h_pieces
|
||||||
|
.iter()
|
||||||
|
.map(|poly| eval_polynomial(poly, *x))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Hash each advice evaluation
|
||||||
|
for eval in &h_evals {
|
||||||
|
transcript.absorb_scalar(*eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
Evaluated {
|
||||||
|
constructed: self,
|
||||||
|
h_evals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: CurveAffine> Evaluated<C> {
|
||||||
|
pub(in crate::plonk) fn open<'a>(
|
||||||
|
&'a self,
|
||||||
|
x: ChallengeX<C::Scalar>,
|
||||||
|
) -> impl Iterator<Item = ProverQuery<'a, C>> + Clone {
|
||||||
|
self.constructed
|
||||||
|
.h_pieces
|
||||||
|
.iter()
|
||||||
|
.zip(self.constructed.h_blinds.iter())
|
||||||
|
.zip(self.h_evals.iter())
|
||||||
|
.map(move |((h_poly, h_blind), h_eval)| ProverQuery {
|
||||||
|
point: *x,
|
||||||
|
poly: h_poly,
|
||||||
|
blind: *h_blind,
|
||||||
|
eval: *h_eval,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) fn build(self) -> Proof<C> {
|
||||||
|
Proof {
|
||||||
|
h_commitments: self.constructed.h_commitments,
|
||||||
|
h_evals: self.h_evals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/plonk/vanishing/verifier.rs
Normal file
76
src/plonk/vanishing/verifier.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
use ff::Field;
|
||||||
|
|
||||||
|
use super::Proof;
|
||||||
|
use crate::{
|
||||||
|
arithmetic::CurveAffine,
|
||||||
|
plonk::{ChallengeX, ChallengeY, Error, VerifyingKey},
|
||||||
|
poly::multiopen::VerifierQuery,
|
||||||
|
transcript::{Hasher, Transcript},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<C: CurveAffine> Proof<C> {
|
||||||
|
pub(in crate::plonk) fn check_lengths(&self, _vk: &VerifyingKey<C>) -> Result<(), Error> {
|
||||||
|
// TODO: check h_evals
|
||||||
|
|
||||||
|
// TODO: check h_commitments
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) fn absorb_commitments<
|
||||||
|
HBase: Hasher<C::Base>,
|
||||||
|
HScalar: Hasher<C::Scalar>,
|
||||||
|
>(
|
||||||
|
&self,
|
||||||
|
transcript: &mut Transcript<C, HBase, HScalar>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1
|
||||||
|
for c in &self.h_commitments {
|
||||||
|
transcript
|
||||||
|
.absorb_point(c)
|
||||||
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) fn verify(
|
||||||
|
&self,
|
||||||
|
expressions: impl Iterator<Item = C::Scalar>,
|
||||||
|
y: ChallengeY<C::Scalar>,
|
||||||
|
xn: C::Scalar,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let expected_h_eval = expressions.fold(C::Scalar::zero(), |h_eval, v| h_eval * &y + &v);
|
||||||
|
|
||||||
|
// Compute h(x) from the prover
|
||||||
|
let h_eval = self
|
||||||
|
.h_evals
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.fold(C::Scalar::zero(), |acc, eval| acc * &xn + eval);
|
||||||
|
|
||||||
|
// Did the prover commit to the correct polynomial?
|
||||||
|
if expected_h_eval != (h_eval * &(xn - &C::Scalar::one())) {
|
||||||
|
return Err(Error::ConstraintSystemFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) fn evals(&self) -> impl Iterator<Item = &C::Scalar> {
|
||||||
|
self.h_evals.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::plonk) fn queries<'a>(
|
||||||
|
&'a self,
|
||||||
|
x: ChallengeX<C::Scalar>,
|
||||||
|
) -> impl Iterator<Item = VerifierQuery<'a, C>> + Clone {
|
||||||
|
self.h_commitments
|
||||||
|
.iter()
|
||||||
|
.zip(self.h_evals.iter())
|
||||||
|
.map(move |(commitment, &eval)| VerifierQuery {
|
||||||
|
point: *x,
|
||||||
|
commitment,
|
||||||
|
eval,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -75,12 +75,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
// 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);
|
||||||
|
|
||||||
// Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1
|
self.vanishing.absorb_commitments(&mut transcript)?;
|
||||||
for c in &self.h_commitments {
|
|
||||||
transcript
|
|
||||||
.absorb_point(c)
|
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sample x challenge, which is used to ensure the circuit is
|
// Sample x challenge, which is used to ensure the circuit is
|
||||||
// satisfied with high probability.
|
// satisfied with high probability.
|
||||||
|
|
@ -95,7 +90,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.aux_evals.iter())
|
.chain(self.aux_evals.iter())
|
||||||
.chain(self.fixed_evals.iter())
|
.chain(self.fixed_evals.iter())
|
||||||
.chain(self.h_evals.iter())
|
.chain(self.vanishing.evals())
|
||||||
.chain(
|
.chain(
|
||||||
self.permutations
|
self.permutations
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -135,17 +130,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
eval: self.fixed_evals[query_index],
|
eval: self.fixed_evals[query_index],
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.chain(
|
.chain(self.vanishing.queries(x));
|
||||||
self.h_commitments
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.zip(self.h_evals.iter())
|
|
||||||
.map(|((idx, _), &eval)| VerifierQuery {
|
|
||||||
point: *x,
|
|
||||||
commitment: &self.h_commitments[idx],
|
|
||||||
eval,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// We are now convinced the circuit is satisfied so long as the
|
// We are now convinced the circuit is satisfied so long as the
|
||||||
// polynomial commitments open to the correct values.
|
// polynomial commitments open to the correct values.
|
||||||
|
|
@ -184,8 +169,6 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
return Err(Error::IncompatibleParams);
|
return Err(Error::IncompatibleParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check h_evals
|
|
||||||
|
|
||||||
if self.fixed_evals.len() != vk.cs.fixed_queries.len() {
|
if self.fixed_evals.len() != vk.cs.fixed_queries.len() {
|
||||||
return Err(Error::IncompatibleParams);
|
return Err(Error::IncompatibleParams);
|
||||||
}
|
}
|
||||||
|
|
@ -203,8 +186,6 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
return Err(Error::IncompatibleParams);
|
return Err(Error::IncompatibleParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check h_commitments
|
|
||||||
|
|
||||||
if self.advice_commitments.len() != vk.cs.num_advice_columns {
|
if self.advice_commitments.len() != vk.cs.num_advice_columns {
|
||||||
return Err(Error::IncompatibleParams);
|
return Err(Error::IncompatibleParams);
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +215,7 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
* &vk.domain.get_barycentric_weight(); // l_0(x)
|
* &vk.domain.get_barycentric_weight(); // l_0(x)
|
||||||
|
|
||||||
// Compute the expected value of h(x)
|
// Compute the expected value of h(x)
|
||||||
let expected_h_eval = std::iter::empty()
|
let expressions = std::iter::empty()
|
||||||
// Evaluate the circuit using the custom gates provided
|
// Evaluate the circuit using the custom gates provided
|
||||||
.chain(vk.cs.gates.iter().map(|poly| {
|
.chain(vk.cs.gates.iter().map(|poly| {
|
||||||
poly.evaluate(
|
poly.evaluate(
|
||||||
|
|
@ -272,21 +253,8 @@ impl<'a, C: CurveAffine> Proof<C> {
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten(),
|
.flatten(),
|
||||||
)
|
);
|
||||||
.fold(C::Scalar::zero(), |h_eval, v| h_eval * &y + &v);
|
|
||||||
|
|
||||||
// Compute h(x) from the prover
|
self.vanishing.verify(expressions, y, xn)
|
||||||
let h_eval = self
|
|
||||||
.h_evals
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.fold(C::Scalar::zero(), |acc, eval| acc * &xn + eval);
|
|
||||||
|
|
||||||
// Did the prover commit to the correct polynomial?
|
|
||||||
if expected_h_eval != (h_eval * &(xn - &C::Scalar::one())) {
|
|
||||||
return Err(Error::ConstraintSystemFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue