Skip to main content

ark_groth16/
lib.rs

1//! An implementation of the [`Groth16`] zkSNARK.
2//!
3//! [`Groth16`]: https://eprint.iacr.org/2016/260.pdf
4#![cfg_attr(not(feature = "std"), no_std)]
5#![warn(
6    unused,
7    future_incompatible,
8    nonstandard_style,
9    rust_2018_idioms,
10    missing_docs
11)]
12#![allow(clippy::many_single_char_names, clippy::op_ref)]
13#![forbid(unsafe_code)]
14
15#[macro_use]
16extern crate ark_std;
17
18/// Reduce an R1CS instance to a *Quadratic Arithmetic Program* instance.
19pub mod r1cs_to_qap;
20
21/// Data structures used by the prover, verifier, and generator.
22pub mod data_structures;
23
24/// Generate public parameters for the Groth16 zkSNARK construction.
25pub mod generator;
26
27/// Create proofs for the Groth16 zkSNARK construction.
28pub mod prover;
29
30/// Verify proofs for the Groth16 zkSNARK construction.
31pub mod verifier;
32
33/// Constraints for the Groth16 verifier.
34#[cfg(feature = "r1cs")]
35pub mod constraints;
36
37#[cfg(test)]
38mod test;
39
40pub use self::{data_structures::*, verifier::*};
41
42use ark_ec::pairing::Pairing;
43use ark_relations::gr1cs::{ConstraintSynthesizer, SynthesisError};
44use ark_snark::*;
45use ark_std::{marker::PhantomData, rand::RngCore, vec::Vec};
46use r1cs_to_qap::{LibsnarkReduction, R1CSToQAP};
47
48/// The SNARK of [[Groth16]](https://eprint.iacr.org/2016/260.pdf).
49pub struct Groth16<E: Pairing, QAP: R1CSToQAP = LibsnarkReduction> {
50    _p: PhantomData<(E, QAP)>,
51}
52
53impl<E: Pairing, QAP: R1CSToQAP> SNARK<E::ScalarField> for Groth16<E, QAP> {
54    type ProvingKey = ProvingKey<E>;
55    type VerifyingKey = VerifyingKey<E>;
56    type Proof = Proof<E>;
57    type ProcessedVerifyingKey = PreparedVerifyingKey<E>;
58    type Error = SynthesisError;
59
60    fn circuit_specific_setup<C: ConstraintSynthesizer<E::ScalarField>, R: RngCore>(
61        circuit: C,
62        rng: &mut R,
63    ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error>
64    where
65        C: ConstraintSynthesizer<E::ScalarField>,
66        R: RngCore,
67    {
68        let pk = Self::generate_random_parameters_with_reduction(circuit, rng)?;
69        let vk = pk.vk.clone();
70
71        Ok((pk, vk))
72    }
73
74    fn prove<C: ConstraintSynthesizer<E::ScalarField>, R: RngCore>(
75        pk: &Self::ProvingKey,
76        circuit: C,
77        rng: &mut R,
78    ) -> Result<Self::Proof, Self::Error> {
79        Self::create_random_proof_with_reduction(circuit, pk, rng)
80    }
81
82    fn process_vk(
83        circuit_vk: &Self::VerifyingKey,
84    ) -> Result<Self::ProcessedVerifyingKey, Self::Error> {
85        Ok(prepare_verifying_key(circuit_vk))
86    }
87
88    fn verify_with_processed_vk(
89        circuit_pvk: &Self::ProcessedVerifyingKey,
90        x: &[E::ScalarField],
91        proof: &Self::Proof,
92    ) -> Result<bool, Self::Error> {
93        Ok(Self::verify_proof(&circuit_pvk, proof, &x)?)
94    }
95}
96
97impl<E: Pairing, QAP: R1CSToQAP> CircuitSpecificSetupSNARK<E::ScalarField> for Groth16<E, QAP> {}