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        // Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1
65        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}