Skip to main content

ark_snark/
lib.rs

1//! This crate contains traits that define the basic behaviour of SNARKs.
2
3#![no_std]
4#![warn(
5    unused,
6    future_incompatible,
7    nonstandard_style,
8    rust_2018_idioms,
9    missing_docs
10)]
11#![forbid(unsafe_code)]
12
13use ark_ff::PrimeField;
14use ark_relations::gr1cs::ConstraintSynthesizer;
15use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
16use ark_std::{
17    fmt::Debug,
18    rand::{CryptoRng, RngCore},
19};
20
21/// The basic functionality for a SNARK.
22pub trait SNARK<F: PrimeField> {
23    /// The information required by the prover to produce a proof for a specific
24    /// circuit *C*.
25    type ProvingKey: Clone + CanonicalSerialize + CanonicalDeserialize;
26
27    /// The information required by the verifier to check a proof for a specific
28    /// circuit *C*.
29    type VerifyingKey: Clone + CanonicalSerialize + CanonicalDeserialize;
30
31    /// The proof output by the prover.
32    type Proof: Clone + CanonicalSerialize + CanonicalDeserialize;
33
34    /// This contains the verification key, but preprocessed to enable faster
35    /// verification.
36    type ProcessedVerifyingKey: Clone + CanonicalSerialize + CanonicalDeserialize;
37
38    /// Errors encountered during setup, proving, or verification.
39    type Error: 'static + ark_std::error::Error;
40
41    /// Takes in a description of a computation (specified in R1CS constraints),
42    /// and samples proving and verification keys for that circuit.
43    fn circuit_specific_setup<C: ConstraintSynthesizer<F>, R: RngCore + CryptoRng>(
44        circuit: C,
45        rng: &mut R,
46    ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error>;
47
48    /// Generates a proof of satisfaction of the arithmetic circuit C (specified
49    /// as R1CS constraints).
50    fn prove<C: ConstraintSynthesizer<F>, R: RngCore + CryptoRng>(
51        circuit_pk: &Self::ProvingKey,
52        circuit: C,
53        rng: &mut R,
54    ) -> Result<Self::Proof, Self::Error>;
55
56    /// Checks that `proof` is a valid proof of the satisfaction of circuit
57    /// encoded in `circuit_vk`, with respect to the public input
58    /// `public_input`, specified as R1CS constraints.
59    fn verify(
60        circuit_vk: &Self::VerifyingKey,
61        public_input: &[F],
62        proof: &Self::Proof,
63    ) -> Result<bool, Self::Error> {
64        let pvk = Self::process_vk(circuit_vk)?;
65        Self::verify_with_processed_vk(&pvk, public_input, proof)
66    }
67
68    /// Preprocesses `circuit_vk` to enable faster verification.
69    fn process_vk(
70        circuit_vk: &Self::VerifyingKey,
71    ) -> Result<Self::ProcessedVerifyingKey, Self::Error>;
72
73    /// Checks that `proof` is a valid proof of the satisfaction of circuit
74    /// encoded in `circuit_pvk`, with respect to the public input
75    /// `public_input`, specified as R1CS constraints.
76    fn verify_with_processed_vk(
77        circuit_pvk: &Self::ProcessedVerifyingKey,
78        public_input: &[F],
79        proof: &Self::Proof,
80    ) -> Result<bool, Self::Error>;
81}
82
83/// A SNARK with (only) circuit-specific setup.
84pub trait CircuitSpecificSetupSNARK<F: PrimeField>: SNARK<F> {
85    /// The setup algorithm for circuit-specific SNARKs. By default, this
86    /// just invokes `<Self as SNARK<F>>::circuit_specific_setup(...)`.
87    fn setup<C: ConstraintSynthesizer<F>, R: RngCore + CryptoRng>(
88        circuit: C,
89        rng: &mut R,
90    ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error> {
91        <Self as SNARK<F>>::circuit_specific_setup(circuit, rng)
92    }
93}
94
95/// A helper type for universal-setup SNARKs, which must infer their computation
96/// size bounds.
97pub enum UniversalSetupIndexError<Bound, E> {
98    /// The provided universal public parameters were insufficient to encode
99    /// the given circuit.
100    NeedLargerBound(Bound),
101    /// Other errors occurred during indexing.
102    Other(E),
103}
104
105/// A SNARK with universal setup. That is, a SNARK where the trusted setup is
106/// circuit-independent.
107pub trait UniversalSetupSNARK<F: PrimeField>: SNARK<F> {
108    /// Specifies how to bound the size of public parameters required to
109    /// generate the index proving and verification keys for a given
110    /// circuit.
111    type ComputationBound: Clone + Default + Debug;
112    /// Specifies the type of universal public parameters.
113    type PublicParameters: Clone + Debug;
114
115    /// Specifies how to bound the size of public parameters required to
116    /// generate the index proving and verification keys for a given
117    /// circuit.
118    fn universal_setup<R: RngCore + CryptoRng>(
119        compute_bound: &Self::ComputationBound,
120        rng: &mut R,
121    ) -> Result<Self::PublicParameters, Self::Error>;
122
123    /// Indexes the public parameters according to the circuit `circuit`, and
124    /// outputs circuit-specific proving and verification keys.
125    fn index<C: ConstraintSynthesizer<F>, R: RngCore + CryptoRng>(
126        pp: &Self::PublicParameters,
127        circuit: C,
128        rng: &mut R,
129    ) -> Result<
130        (Self::ProvingKey, Self::VerifyingKey),
131        UniversalSetupIndexError<Self::ComputationBound, Self::Error>,
132    >;
133}