halo2_axiom/plonk/vanishing/
verifier.rs
1use std::iter;
2
3use ff::Field;
4
5use crate::{
6 arithmetic::CurveAffine,
7 plonk::{Error, VerifyingKey},
8 poly::{
9 commitment::{Params, MSM},
10 VerifierQuery,
11 },
12 transcript::{read_n_points, EncodedChallenge, TranscriptRead},
13};
14
15use super::super::{ChallengeX, ChallengeY};
16use super::Argument;
17
18pub struct Committed<C: CurveAffine> {
19 random_poly_commitment: C,
20}
21
22pub struct Constructed<C: CurveAffine> {
23 h_commitments: Vec<C>,
24 random_poly_commitment: C,
25}
26
27pub struct PartiallyEvaluated<C: CurveAffine> {
28 h_commitments: Vec<C>,
29 random_poly_commitment: C,
30 random_eval: C::Scalar,
31}
32
33pub struct Evaluated<C: CurveAffine, M: MSM<C>> {
34 h_commitment: M,
35 random_poly_commitment: C,
36 expected_h_eval: C::Scalar,
37 random_eval: C::Scalar,
38}
39
40impl<C: CurveAffine> Argument<C> {
41 pub(in crate::plonk) fn read_commitments_before_y<
42 E: EncodedChallenge<C>,
43 T: TranscriptRead<C, E>,
44 >(
45 transcript: &mut T,
46 ) -> Result<Committed<C>, Error> {
47 let random_poly_commitment = transcript.read_point()?;
48
49 Ok(Committed {
50 random_poly_commitment,
51 })
52 }
53}
54
55impl<C: CurveAffine> Committed<C> {
56 pub(in crate::plonk) fn read_commitments_after_y<
57 E: EncodedChallenge<C>,
58 T: TranscriptRead<C, E>,
59 >(
60 self,
61 vk: &VerifyingKey<C>,
62 transcript: &mut T,
63 ) -> Result<Constructed<C>, Error> {
64 let h_commitments = read_n_points(transcript, vk.domain.get_quotient_poly_degree())?;
66
67 Ok(Constructed {
68 h_commitments,
69 random_poly_commitment: self.random_poly_commitment,
70 })
71 }
72}
73
74impl<C: CurveAffine> Constructed<C> {
75 pub(in crate::plonk) fn evaluate_after_x<E: EncodedChallenge<C>, T: TranscriptRead<C, E>>(
76 self,
77 transcript: &mut T,
78 ) -> Result<PartiallyEvaluated<C>, Error> {
79 let random_eval = transcript.read_scalar()?;
80
81 Ok(PartiallyEvaluated {
82 h_commitments: self.h_commitments,
83 random_poly_commitment: self.random_poly_commitment,
84 random_eval,
85 })
86 }
87}
88
89impl<C: CurveAffine> PartiallyEvaluated<C> {
90 pub(in crate::plonk) fn verify<'params, P: Params<'params, C>>(
91 self,
92 params: &'params P,
93 expressions: impl Iterator<Item = C::Scalar>,
94 y: ChallengeY<C>,
95 xn: C::Scalar,
96 ) -> Evaluated<C, P::MSM> {
97 let expected_h_eval = expressions.fold(C::Scalar::ZERO, |h_eval, v| h_eval * &*y + &v);
98 let expected_h_eval = expected_h_eval * ((xn - C::Scalar::ONE).invert().unwrap());
99
100 let h_commitment =
101 self.h_commitments
102 .iter()
103 .rev()
104 .fold(params.empty_msm(), |mut acc, commitment| {
105 acc.scale(xn);
106 let commitment: C::CurveExt = (*commitment).into();
107 acc.append_term(C::Scalar::ONE, commitment);
108
109 acc
110 });
111
112 Evaluated {
113 expected_h_eval,
114 h_commitment,
115 random_poly_commitment: self.random_poly_commitment,
116 random_eval: self.random_eval,
117 }
118 }
119}
120
121impl<C: CurveAffine, M: MSM<C>> Evaluated<C, M> {
122 pub(in crate::plonk) fn queries(
123 &self,
124 x: ChallengeX<C>,
125 ) -> impl Iterator<Item = VerifierQuery<C, M>> + Clone {
126 iter::empty()
127 .chain(Some(VerifierQuery::new_msm(
128 &self.h_commitment,
129 *x,
130 self.expected_h_eval,
131 )))
132 .chain(Some(VerifierQuery::new_commitment(
133 &self.random_poly_commitment,
134 *x,
135 self.random_eval,
136 )))
137 }
138}