ark_snark/
lib.rs

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