use std::iter; use ff::Field; use crate::{ arithmetic::CurveAffine, plonk::{Error, VerifyingKey}, poly::{ commitment::{Params, MSM}, multiopen::VerifierQuery, }, transcript::{read_n_points, EncodedChallenge, TranscriptRead}, }; use super::super::{ChallengeX, ChallengeY}; use super::Argument; pub struct Committed { random_poly_commitment: C, } pub struct Constructed { h_commitments: Vec, random_poly_commitment: C, } pub struct PartiallyEvaluated { h_commitments: Vec, random_poly_commitment: C, random_eval: C::Scalar, } pub struct Evaluated<'params, C: CurveAffine> { h_commitment: MSM<'params, C>, random_poly_commitment: C, expected_h_eval: C::Scalar, random_eval: C::Scalar, } impl Argument { pub(in crate::plonk) fn read_commitments_before_y< E: EncodedChallenge, T: TranscriptRead, >( transcript: &mut T, ) -> Result, Error> { let random_poly_commitment = transcript.read_point()?; Ok(Committed { random_poly_commitment, }) } } impl Committed { pub(in crate::plonk) fn read_commitments_after_y< E: EncodedChallenge, T: TranscriptRead, >( self, vk: &VerifyingKey, transcript: &mut T, ) -> Result, Error> { // Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1 let h_commitments = read_n_points(transcript, vk.domain.get_quotient_poly_degree())?; Ok(Constructed { h_commitments, random_poly_commitment: self.random_poly_commitment, }) } } impl Constructed { pub(in crate::plonk) fn evaluate_after_x, T: TranscriptRead>( self, transcript: &mut T, ) -> Result, Error> { let random_eval = transcript.read_scalar()?; Ok(PartiallyEvaluated { h_commitments: self.h_commitments, random_poly_commitment: self.random_poly_commitment, random_eval, }) } } impl PartiallyEvaluated { pub(in crate::plonk) fn verify( self, params: &Params, expressions: impl Iterator, y: ChallengeY, xn: C::Scalar, ) -> Evaluated { let expected_h_eval = expressions.fold(C::Scalar::ZERO, |h_eval, v| h_eval * &*y + &v); let expected_h_eval = expected_h_eval * ((xn - C::Scalar::ONE).invert().unwrap()); let h_commitment = self.h_commitments .iter() .rev() .fold(params.empty_msm(), |mut acc, commitment| { acc.scale(xn); acc.append_term(C::Scalar::ONE, *commitment); acc }); Evaluated { expected_h_eval, h_commitment, random_poly_commitment: self.random_poly_commitment, random_eval: self.random_eval, } } } impl<'params, C: CurveAffine> Evaluated<'params, C> { pub(in crate::plonk) fn queries<'r>( &'r self, x: ChallengeX, ) -> impl Iterator> + Clone where 'params: 'r, { iter::empty() .chain(Some(VerifierQuery::new_msm( &self.h_commitment, *x, self.expected_h_eval, ))) .chain(Some(VerifierQuery::new_commitment( &self.random_poly_commitment, *x, self.random_eval, ))) } }