1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::errors::SNARKError;
use snarkvm_utilities::{FromBytes, ToBytes, ToMinimalBits};
use rand::{CryptoRng, Rng};
use snarkvm_fields::{PrimeField, ToConstraintField};
use snarkvm_r1cs::ConstraintSynthesizer;
use std::{fmt::Debug, sync::atomic::AtomicBool};
pub trait Prepare<T> {
fn prepare(&self) -> T;
}
pub enum SRS<'a, R: Rng + CryptoRng, T> {
CircuitSpecific(&'a mut R),
Universal(&'a T),
}
pub trait SNARK: Clone + Debug {
type ScalarField: Clone + PrimeField;
type BaseField: Clone + PrimeField;
type PreparedVerifyingKey: Clone;
type Proof: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Send + Sync;
type ProvingKey: Clone + ToBytes + FromBytes + Send + Sync;
type UniversalSetupConfig: Clone;
type UniversalSetupParameters: FromBytes + ToBytes + Clone;
type VerifierInput: ?Sized;
type VerifyingKey: Clone
+ Send
+ Sync
+ ToBytes
+ FromBytes
+ Prepare<Self::PreparedVerifyingKey>
+ From<Self::PreparedVerifyingKey>
+ From<Self::ProvingKey>
+ ToConstraintField<Self::BaseField>
+ ToMinimalBits;
fn universal_setup<R: Rng + CryptoRng>(
_config: &Self::UniversalSetupConfig,
_rng: &mut R,
) -> Result<Self::UniversalSetupParameters, SNARKError> {
unimplemented!()
}
fn setup<C: ConstraintSynthesizer<Self::ScalarField>, R: Rng + CryptoRng>(
circuit: &C,
srs: &mut SRS<R, Self::UniversalSetupParameters>,
) -> Result<(Self::ProvingKey, Self::VerifyingKey), SNARKError>;
fn prove<C: ConstraintSynthesizer<Self::ScalarField>, R: Rng + CryptoRng>(
proving_key: &Self::ProvingKey,
input_and_witness: &C,
rng: &mut R,
) -> Result<Self::Proof, SNARKError> {
Self::prove_with_terminator(proving_key, input_and_witness, &AtomicBool::new(false), rng)
}
fn prove_with_terminator<C: ConstraintSynthesizer<Self::ScalarField>, R: Rng + CryptoRng>(
proving_key: &Self::ProvingKey,
input_and_witness: &C,
terminator: &AtomicBool,
rng: &mut R,
) -> Result<Self::Proof, SNARKError>;
fn verify_prepared(
prepared_verifying_key: &Self::PreparedVerifyingKey,
input: &Self::VerifierInput,
proof: &Self::Proof,
) -> Result<bool, SNARKError>;
fn verify(
verifying_key: &Self::VerifyingKey,
input: &Self::VerifierInput,
proof: &Self::Proof,
) -> Result<bool, SNARKError> {
let processed_verifying_key = verifying_key.prepare();
Self::verify_prepared(&processed_verifying_key, input, proof)
}
}