snarkvm_synthesizer_snark/
lib.rs1#![forbid(unsafe_code)]
17#![allow(clippy::too_many_arguments)]
18#![warn(clippy::cast_possible_truncation)]
19#![cfg_attr(not(feature = "aleo-cli"), allow(unused_variables))]
20
21use console::network::{FiatShamir, prelude::*};
22use snarkvm_algorithms::{snark::varuna, traits::SNARK};
23
24use once_cell::sync::OnceCell;
25use std::sync::Arc;
26
27#[cfg(feature = "aleo-cli")]
28use colored::Colorize;
29
30type Varuna<N> = varuna::VarunaSNARK<<N as Environment>::PairingCurve, FiatShamir<N>, varuna::VarunaHidingMode>;
31
32mod certificate;
33pub use certificate::Certificate;
34
35mod proof;
36pub use proof::Proof;
37
38mod proving_key;
39pub use proving_key::ProvingKey;
40
41mod universal_srs;
42pub use universal_srs::UniversalSRS;
43
44mod verifying_key;
45pub use verifying_key::VerifyingKey;
46
47#[cfg(test)]
48pub(crate) mod test_helpers {
49 use super::*;
50 use circuit::{
51 environment::{Assignment, Circuit, Eject, Environment, Inject, Mode, One},
52 types::Field,
53 };
54 use console::{network::MainnetV0, prelude::One as _};
55 use snarkvm_algorithms::snark::varuna::VarunaVersion;
56
57 use once_cell::sync::OnceCell;
58
59 type CurrentNetwork = MainnetV0;
60
61 fn create_example_circuit<E: Environment>() -> Field<E> {
63 let one = console::types::Field::<E::Network>::one();
64 let two = one + one;
65
66 const EXPONENT: u64 = 64;
67
68 let mut candidate = Field::<E>::new(Mode::Public, one);
70 let mut accumulator = Field::new(Mode::Private, two);
71 for _ in 0..EXPONENT {
72 candidate += &accumulator;
73 accumulator *= Field::new(Mode::Private, two);
74 }
75
76 assert_eq!((accumulator - Field::one()).eject_value(), candidate.eject_value());
77 assert_eq!(2, E::num_public());
78 assert_eq!(2 * EXPONENT + 1, E::num_private());
79 assert_eq!(EXPONENT, E::num_constraints());
80 assert!(E::is_satisfied());
81
82 candidate
83 }
84
85 pub(crate) fn sample_assignment() -> Assignment<<Circuit as Environment>::BaseField> {
87 static INSTANCE: OnceCell<Assignment<<Circuit as Environment>::BaseField>> = OnceCell::new();
88 INSTANCE
89 .get_or_init(|| {
90 let _candidate_output = create_example_circuit::<Circuit>();
91 let assignment = Circuit::eject_assignment_and_reset();
92 assert_eq!(0, Circuit::num_constants());
93 assert_eq!(1, Circuit::num_public());
94 assert_eq!(0, Circuit::num_private());
95 assert_eq!(0, Circuit::num_constraints());
96 assignment
97 })
98 .clone()
99 }
100
101 pub(crate) fn sample_keys() -> (ProvingKey<CurrentNetwork>, VerifyingKey<CurrentNetwork>) {
103 static INSTANCE: OnceCell<(ProvingKey<CurrentNetwork>, VerifyingKey<CurrentNetwork>)> = OnceCell::new();
104 INSTANCE
105 .get_or_init(|| {
106 let assignment = sample_assignment();
107 let srs = UniversalSRS::load().unwrap();
108 let (proving_key, verifying_key) = srs.to_circuit_key("test", &assignment).unwrap();
109 (proving_key, verifying_key)
110 })
111 .clone()
112 }
113
114 pub(crate) fn sample_proof() -> Proof<CurrentNetwork> {
116 static INSTANCE: OnceCell<Proof<CurrentNetwork>> = OnceCell::new();
117 INSTANCE
118 .get_or_init(|| {
119 let assignment = sample_assignment();
120 let (proving_key, _) = sample_keys();
121 proving_key.prove("test", VarunaVersion::V2, &assignment, &mut TestRng::default()).unwrap()
122 })
123 .clone()
124 }
125
126 pub(super) fn sample_certificate() -> Certificate<CurrentNetwork> {
128 static INSTANCE: OnceCell<Certificate<CurrentNetwork>> = OnceCell::new();
129 INSTANCE
130 .get_or_init(|| {
131 let (proving_key, verifying_key) = sample_keys();
132 Certificate::certify("test", &proving_key, &verifying_key).unwrap()
134 })
135 .clone()
136 }
137}
138
139#[cfg(test)]
140mod test {
141 use super::*;
142 use circuit::environment::{Circuit, Environment};
143 use console::network::MainnetV0;
144 use snarkvm_algorithms::snark::varuna::VarunaVersion;
145
146 type CurrentNetwork = MainnetV0;
147
148 #[test]
149 fn test_varuna() {
150 let assignment = crate::test_helpers::sample_assignment();
151
152 let srs = UniversalSRS::<CurrentNetwork>::load().unwrap();
154 let (proving_key, verifying_key) = srs.to_circuit_key("test", &assignment).unwrap();
155 let varuna_version = VarunaVersion::V2;
156 println!("Called circuit setup");
157
158 let proof = proving_key.prove("test", varuna_version, &assignment, &mut TestRng::default()).unwrap();
159 println!("Called prover");
160
161 let one = <Circuit as Environment>::BaseField::one();
162 assert!(verifying_key.verify("test", varuna_version, &[one, one], &proof));
163 println!("Called verifier");
164 println!("\nShould not verify (i.e. verifier messages should print below):");
165 assert!(!verifying_key.verify("test", varuna_version, &[one, one + one], &proof));
166 assert!(!verifying_key.verify("test", VarunaVersion::V1, &[one, one], &proof));
167 }
168
169 #[test]
170 fn test_varuna_verify_public_input_size() {
171 fn create_assignment() -> circuit::Assignment<<CurrentNetwork as console::prelude::Environment>::Field> {
173 use circuit::{Inject, environment::Mode, types::Field};
174
175 Circuit::reset();
177
178 let console_field = console::types::Field::<CurrentNetwork>::one();
180 let circuit_field_0 = Field::<Circuit>::new(Mode::Private, console_field);
181
182 let console_field = console_field.double();
184 let circuit_field_1 = Field::<Circuit>::new(Mode::Private, console_field);
185
186 let _circuit_field_2 = circuit_field_0 * circuit_field_1;
188
189 Circuit::eject_assignment_and_reset()
191 }
192
193 let assignment = create_assignment();
194 assert_eq!(assignment.num_public(), 1);
195 assert_eq!(assignment.num_private(), 3);
196
197 let srs = UniversalSRS::<CurrentNetwork>::load().unwrap();
198 let (proving_key, verifying_key) = srs.to_circuit_key("test", &assignment).unwrap();
199 let varuna_version = VarunaVersion::V2;
200 println!("Called circuit setup");
201
202 let proof = proving_key.prove("test", varuna_version, &assignment, &mut TestRng::default()).unwrap();
203 println!("Called prover");
204
205 let one = <Circuit as Environment>::BaseField::one();
207 assert!(verifying_key.verify("test", varuna_version, &[one], &proof));
208
209 assert!(!verifying_key.verify("test", VarunaVersion::V1, &[one], &proof));
211 assert!(!verifying_key.verify("test", varuna_version, &[one, one], &proof));
212 assert!(!verifying_key.verify("test", varuna_version, &[one, one + one], &proof));
213 assert!(!verifying_key.verify("test", varuna_version, &[one, one, one], &proof));
214 assert!(!verifying_key.verify("test", varuna_version, &[one, one, one + one], &proof));
215 assert!(!verifying_key.verify("test", varuna_version, &[one, one, one, one], &proof));
216
217 println!("Called verifier");
218 }
219}