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}