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}