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