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
use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup};
use ark_ff::PrimeField;
use crate::{r1cs_to_qap::R1CSToQAP, Groth16};
use super::{PreparedVerifyingKey, Proof, VerifyingKey};
use ark_relations::r1cs::{Result as R1CSResult, SynthesisError};
use core::ops::{AddAssign, Neg};
pub fn prepare_verifying_key<E: Pairing>(vk: &VerifyingKey<E>) -> PreparedVerifyingKey<E> {
PreparedVerifyingKey {
vk: vk.clone(),
alpha_g1_beta_g2: E::pairing(vk.alpha_g1, vk.beta_g2).0,
gamma_g2_neg_pc: vk.gamma_g2.into_group().neg().into_affine().into(),
delta_g2_neg_pc: vk.delta_g2.into_group().neg().into_affine().into(),
}
}
impl<E: Pairing, QAP: R1CSToQAP> Groth16<E, QAP> {
pub fn prepare_inputs(
pvk: &PreparedVerifyingKey<E>,
public_inputs: &[E::ScalarField],
) -> R1CSResult<E::G1> {
if (public_inputs.len() + 1) != pvk.vk.gamma_abc_g1.len() {
return Err(SynthesisError::MalformedVerifyingKey);
}
let mut g_ic = pvk.vk.gamma_abc_g1[0].into_group();
for (i, b) in public_inputs.iter().zip(pvk.vk.gamma_abc_g1.iter().skip(1)) {
g_ic.add_assign(&b.mul_bigint(i.into_bigint()));
}
Ok(g_ic)
}
pub fn verify_proof_with_prepared_inputs(
pvk: &PreparedVerifyingKey<E>,
proof: &Proof<E>,
prepared_inputs: &E::G1,
) -> R1CSResult<bool> {
let qap = E::multi_miller_loop(
[
<E::G1Affine as Into<E::G1Prepared>>::into(proof.a),
prepared_inputs.into_affine().into(),
proof.c.into(),
],
[
proof.b.into(),
pvk.gamma_g2_neg_pc.clone(),
pvk.delta_g2_neg_pc.clone(),
],
);
let test = E::final_exponentiation(qap).ok_or(SynthesisError::UnexpectedIdentity)?;
Ok(test.0 == pvk.alpha_g1_beta_g2)
}
pub fn verify_proof(
pvk: &PreparedVerifyingKey<E>,
proof: &Proof<E>,
public_inputs: &[E::ScalarField],
) -> R1CSResult<bool> {
let prepared_inputs = Self::prepare_inputs(pvk, public_inputs)?;
Self::verify_proof_with_prepared_inputs(pvk, proof, &prepared_inputs)
}
}