halo2_axiom/poly/ipa/commitment/
verifier.rs1use group::ff::{BatchInvert, Field};
2
3use super::ParamsIPA;
4use crate::{arithmetic::CurveAffine, poly::ipa::strategy::GuardIPA};
5use crate::{
6 poly::{commitment::MSM, ipa::msm::MSMIPA, Error},
7 transcript::{EncodedChallenge, TranscriptRead},
8};
9
10pub fn verify_proof<'params, C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptRead<C, E>>(
14 params: &'params ParamsIPA<C>,
15 mut msm: MSMIPA<'params, C>,
16 transcript: &mut T,
17 x: C::Scalar,
18 v: C::Scalar,
19) -> Result<GuardIPA<'params, C>, Error> {
20 let k = params.k as usize;
21
22 msm.add_constant_term(-v); let s_poly_commitment = transcript.read_point().map_err(|_| Error::OpeningError)?;
25 let xi = *transcript.squeeze_challenge_scalar::<()>();
26 msm.append_term(xi, s_poly_commitment.into());
27
28 let z = *transcript.squeeze_challenge_scalar::<()>();
29
30 let mut rounds = vec![];
31 for _ in 0..k {
32 let l = transcript.read_point().map_err(|_| Error::OpeningError)?;
34 let r = transcript.read_point().map_err(|_| Error::OpeningError)?;
35
36 let u_j_packed = transcript.squeeze_challenge();
37 let u_j = *u_j_packed.as_challenge_scalar::<()>();
38
39 rounds.push((l, r, u_j, u_j, u_j_packed));
40 }
41
42 rounds
43 .iter_mut()
44 .map(|&mut (_, _, _, ref mut u_j, _)| u_j)
45 .batch_invert();
46
47 let mut u = Vec::with_capacity(k);
50 let mut u_packed: Vec<C::Scalar> = Vec::with_capacity(k);
51 for (l, r, u_j, u_j_inv, u_j_packed) in rounds {
52 msm.append_term(u_j_inv, l.into());
53 msm.append_term(u_j, r.into());
54
55 u.push(u_j);
56 u_packed.push(u_j_packed.get_scalar());
57 }
58
59 let c = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
74 let neg_c = -c;
75 let f = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
76 let b = compute_b(x, &u);
77
78 msm.add_to_u_scalar(neg_c * &b * &z);
79 msm.add_to_w_scalar(-f);
80
81 let guard = GuardIPA {
82 msm,
83 neg_c,
84 u,
85 u_packed,
86 };
87
88 Ok(guard)
89}
90
91fn compute_b<F: Field>(x: F, u: &[F]) -> F {
93 let mut tmp = F::ONE;
94 let mut cur = x;
95 for u_j in u.iter().rev() {
96 tmp *= F::ONE + &(*u_j * &cur);
97 cur *= cur;
98 }
99 tmp
100}