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
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
use snarkvm_errors::gadgets::SynthesisError;
use snarkvm_models::curves::{AffineCurve, PairingCurve, PairingEngine, PrimeField, ProjectiveCurve};
use core::ops::{AddAssign, Neg};
pub fn prepare_verifying_key<E: PairingEngine>(vk: VerifyingKey<E>) -> PreparedVerifyingKey<E> {
let alpha_g1_beta_g2 = E::pairing(vk.alpha_g1, vk.beta_g2);
let gamma_g2_neg_pc = vk.gamma_g2.neg().prepare();
let delta_g2_neg_pc = vk.delta_g2.neg().prepare();
PreparedVerifyingKey {
vk,
alpha_g1_beta_g2,
gamma_g2_neg_pc,
delta_g2_neg_pc,
}
}
pub fn verify_proof<E: PairingEngine>(
pvk: &PreparedVerifyingKey<E>,
proof: &Proof<E>,
public_inputs: &[E::Fr],
) -> Result<bool, SynthesisError> {
if (public_inputs.len() + 1) != pvk.gamma_abc_g1().len() {
return Err(SynthesisError::MalformedVerifyingKey);
}
let mut g_ic = pvk.gamma_abc_g1()[0].into_projective();
for (i, b) in public_inputs.iter().zip(pvk.gamma_abc_g1().iter().skip(1)) {
g_ic.add_assign(&b.mul(i.into_repr()));
}
let qap = E::miller_loop(
[
(&proof.a.prepare(), &proof.b.prepare()),
(&g_ic.into_affine().prepare(), &pvk.gamma_g2_neg_pc),
(&proof.c.prepare(), &pvk.delta_g2_neg_pc),
]
.iter()
.copied(),
);
let test = E::final_exponentiation(&qap).ok_or(SynthesisError::UnexpectedIdentity)?;
Ok(test == pvk.alpha_g1_beta_g2)
}