From 9852913a32877937af11ea3ee4e5992c14272aa1 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Thu, 27 Aug 2020 10:46:54 -0600 Subject: [PATCH] Add some comments and documentation. --- src/plonk/verifier.rs | 48 +++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 33c0f2cc..cc28d7df 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -13,19 +13,26 @@ impl Proof { // Create a transcript for obtaining Fiat-Shamir challenges. let mut transcript = HBase::init(C::Base::one()); + // Hash the prover's advice commitments into the transcript for commitment in &self.advice_commitments { hash_point(&mut transcript, commitment) .expect("proof cannot contain points at infinity"); } + // Sample x_2 challenge, which keeps the gates linearly independent. let x_2: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1 for c in &self.h_commitments { hash_point(&mut transcript, c).expect("proof cannot contain points at infinity"); } + // Sample x_3 challenge, which is used to ensure the circuit is + // satisfied with high probability. let x_3: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Hash together all the openings provided by the prover into a new + // transcript on the scalar field. let mut transcript_scalar = HScalar::init(C::Scalar::one()); for eval in self.advice_evals.iter() { @@ -40,6 +47,10 @@ impl Proof { transcript_scalar.absorb(*eval); } + let transcript_scalar_point = + C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); + transcript.absorb(transcript_scalar_point); + // Evaluate the circuit using the custom gates provided let mut h_eval = C::Scalar::zero(); for poly in srs.meta.gates.iter() { @@ -70,15 +81,16 @@ impl Proof { return false; } - let transcript_scalar_point = - C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); - transcript.absorb(transcript_scalar_point); + // We are now convinced the circuit is satisfied so long as the + // polynomial commitments open to the correct values. + // Sample x_4 for compressing openings at the same points together let x_4: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Compress the commitments and expected evaluations at x_3 together + // using the challenge x_4 let mut q_commitments: Vec<_> = vec![None; srs.meta.query_rows.len()]; let mut q_evals: Vec<_> = vec![C::Scalar::zero(); srs.meta.query_rows.len()]; - { for (i, &(wire, ref at)) in srs.meta.advice_queries.iter().enumerate() { let query_row = *srs.meta.query_rows.get(at).unwrap(); @@ -131,14 +143,28 @@ impl Proof { } } + // Sample a challenge x_5 for keeping the multi-point quotient + // polynomial terms linearly independent. let x_5: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Obtain the commitment to the multi-point quotient polynomial f(X). hash_point(&mut transcript, &self.f_commitment) .expect("proof cannot contain points at infinity"); + // Sample a challenge x_6 for checking that f(X) was committed to + // correctly. let x_6: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); - // We can compute the expected f_eval from x_5 + for eval in self.q_evals.iter() { + transcript_scalar.absorb(*eval); + } + + let transcript_scalar_point = + C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); + transcript.absorb(transcript_scalar_point); + + // We can compute the expected f_eval at x_6 using the q_evals provided + // by the prover and from x_5 let mut f_eval = C::Scalar::zero(); for (&row, &col) in srs.meta.query_rows.iter() { let mut eval: C::Scalar = self.q_evals[col].clone(); @@ -158,16 +184,11 @@ impl Proof { f_eval += &eval; } - for eval in self.q_evals.iter() { - transcript_scalar.absorb(*eval); - } - - let transcript_scalar_point = - C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); - transcript.absorb(transcript_scalar_point); - + // Sample a challenge x_7 that we will use to collapse the openings of + // the various remaining polynomials at x_6 together. let x_7: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + // Compute the final commitment that has to be opened let mut f_commitment: C::Projective = self.f_commitment.to_projective(); for (_, &col) in srs.meta.query_rows.iter() { f_commitment *= x_7; @@ -176,6 +197,7 @@ impl Proof { f_eval += &self.q_evals[col]; } + // Verify the opening proof params.verify_proof( &self.opening, &mut transcript,