halo2_axiom/poly/kzg/multiopen/gwc/
verifier.rs

1use std::fmt::Debug;
2
3use super::{construct_intermediate_sets, ChallengeU, ChallengeV};
4use crate::arithmetic::powers;
5use crate::helpers::SerdeCurveAffine;
6use crate::poly::commitment::Verifier;
7use crate::poly::commitment::MSM;
8use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG};
9use crate::poly::kzg::msm::{DualMSM, MSMKZG};
10use crate::poly::kzg::strategy::GuardKZG;
11use crate::poly::query::Query;
12use crate::poly::query::{CommitmentReference, VerifierQuery};
13use crate::poly::Error;
14use crate::transcript::{EncodedChallenge, TranscriptRead};
15
16use ff::Field;
17use pairing::{Engine, MultiMillerLoop};
18
19#[derive(Debug)]
20/// Concrete KZG verifier with GWC variant
21pub struct VerifierGWC<'params, E: Engine> {
22    params: &'params ParamsKZG<E>,
23}
24
25impl<'params, E> Verifier<'params, KZGCommitmentScheme<E>> for VerifierGWC<'params, E>
26where
27    E: MultiMillerLoop + Debug,
28    E::G1Affine: SerdeCurveAffine<ScalarExt = E::Fr, CurveExt = E::G1>,
29    E::G2Affine: SerdeCurveAffine,
30{
31    type Guard = GuardKZG<'params, E>;
32    type MSMAccumulator = DualMSM<'params, E>;
33
34    const QUERY_INSTANCE: bool = false;
35
36    fn new(params: &'params ParamsKZG<E>) -> Self {
37        Self { params }
38    }
39
40    fn verify_proof<
41        'com,
42        Ch: EncodedChallenge<E::G1Affine>,
43        T: TranscriptRead<E::G1Affine, Ch>,
44        I,
45    >(
46        &self,
47        transcript: &mut T,
48        queries: I,
49        mut msm_accumulator: DualMSM<'params, E>,
50    ) -> Result<Self::Guard, Error>
51    where
52        I: IntoIterator<Item = VerifierQuery<'com, E::G1Affine, MSMKZG<E>>> + Clone,
53    {
54        let v: ChallengeV<_> = transcript.squeeze_challenge_scalar();
55
56        let commitment_data = construct_intermediate_sets(queries);
57
58        let w: Vec<E::G1Affine> = (0..commitment_data.len())
59            .map(|_| transcript.read_point().map_err(|_| Error::SamplingError))
60            .collect::<Result<Vec<E::G1Affine>, Error>>()?;
61
62        let u: ChallengeU<_> = transcript.squeeze_challenge_scalar();
63
64        let mut commitment_multi = MSMKZG::<E>::new();
65        let mut eval_multi = E::Fr::ZERO;
66
67        let mut witness = MSMKZG::<E>::new();
68        let mut witness_with_aux = MSMKZG::<E>::new();
69
70        for ((commitment_at_a_point, wi), power_of_u) in
71            commitment_data.iter().zip(w).zip(powers(*u))
72        {
73            assert!(!commitment_at_a_point.queries.is_empty());
74            let z = commitment_at_a_point.point;
75
76            let (mut commitment_batch, eval_batch) = commitment_at_a_point
77                .queries
78                .iter()
79                .zip(powers(*v))
80                .map(|(query, power_of_v)| {
81                    assert_eq!(query.get_point(), z);
82
83                    let commitment = match query.get_commitment() {
84                        CommitmentReference::Commitment(c) => {
85                            let mut msm = MSMKZG::<E>::new();
86                            msm.append_term(power_of_v, (*c).into());
87                            msm
88                        }
89                        CommitmentReference::MSM(msm) => {
90                            let mut msm = msm.clone();
91                            msm.scale(power_of_v);
92                            msm
93                        }
94                    };
95                    let eval = power_of_v * query.get_eval();
96
97                    (commitment, eval)
98                })
99                .reduce(|(mut commitment_acc, eval_acc), (commitment, eval)| {
100                    commitment_acc.add_msm(&commitment);
101                    (commitment_acc, eval_acc + eval)
102                })
103                .unwrap();
104
105            commitment_batch.scale(power_of_u);
106            commitment_multi.add_msm(&commitment_batch);
107            eval_multi += power_of_u * eval_batch;
108
109            witness_with_aux.append_term(power_of_u * z, wi.into());
110            witness.append_term(power_of_u, wi.into());
111        }
112
113        msm_accumulator.left.add_msm(&witness);
114
115        msm_accumulator.right.add_msm(&witness_with_aux);
116        msm_accumulator.right.add_msm(&commitment_multi);
117        let g0: E::G1 = self.params.g[0].into();
118        msm_accumulator.right.append_term(eval_multi, -g0);
119
120        Ok(Self::Guard::new(msm_accumulator))
121    }
122}