grapevine-sonobe/src/circom.rs
src/circom.rsRaw
1#[cfg(test)]
2mod test {
3 use super::*;
4 use crate::params::test_nova_setup;
5 use crate::utils::inputs::{
6 get_z0, prepare_external_inputs, random_f_bigint, CircomPrivateInput,
7 };
8 use ark_bn254::{constraints::GVar, Fr, G1Projective as Projective};
9 // use ark_circom::circom::CircomCircuit;
10 use ark_ff::PrimeField;
11 use ark_grumpkin::{constraints::GVar as GVar2, Projective as Projective2};
12 use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar};
13 use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
14 use lazy_static::lazy_static;
15 use num_bigint::BigInt;
16 use sonobe::{
17 commitment::pedersen::Pedersen, folding::nova::Nova, frontend::circom::CircomFCircuit,
18 transcript::poseidon::poseidon_test_config, Error, FoldingScheme,
19 };
20 use sonobe::{frontend::FCircuit, Error as SonobeError};
21 use std::env::current_dir;
22 use std::path::PathBuf;
23 use std::time::Instant;
24
25 use crate::errors::GrapevineError;
26
27 lazy_static! {
28 pub static ref R1CS_PATH: PathBuf = PathBuf::from("./circom/artifacts/grapevine.r1cs");
29 pub static ref WASM_PATH: PathBuf = PathBuf::from("./circom/artifacts/grapevine.wasm");
30 pub static ref PHRASE: String = String::from("This is a secret");
31 pub static ref USERNAMES: [String; 5] = [
32 String::from("alice"),
33 String::from("bob"),
34 String::from("charlie"),
35 String::from("david"),
36 String::from("eve")
37 ];
38 pub static ref AUTH_SECRETS: [BigInt; 5] = (0..5)
39 .map(|_| random_f_bigint::<Fr>())
40 .collect::<Vec<BigInt>>()
41 .try_into()
42 .unwrap();
43 }
44
45 #[test]
46 fn test_step_native() {
47 // define inputs
48 let step_0_inputs = CircomPrivateInput {
49 phrase: Some(String::from(&*PHRASE)),
50 usernames: [None, Some(String::from(&*USERNAMES[0]))],
51 auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
52 chaff: false,
53 };
54 let external_inputs = prepare_external_inputs::<Fr>(&step_0_inputs);
55
56 // initialize new Grapevine function circuit
57 let f_circuit = CircomFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone(), 4, 6 + 4)); // 4=ivc_input.lenght, 6+4=external_inputs
58
59 let z_0 = get_z0();
60 let z_1 = f_circuit
61 .step_native(0, z_0.to_vec(), external_inputs)
62 .unwrap();
63 println!("z_1: {:?}", z_1);
64 }
65
66 #[test]
67 fn test_step_constraints() {
68 // define inputs
69 let step_0_inputs = CircomPrivateInput {
70 phrase: Some(String::from(&*PHRASE)),
71 usernames: [None, Some(String::from(&*USERNAMES[0]))],
72 auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
73 chaff: false,
74 };
75 let external_inputs = prepare_external_inputs::<Fr>(&step_0_inputs);
76
77 // initialize new Grapevine function circuit
78 let f_circuit = CircomFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone(), 4, 6 + 4)); // 4=ivc_input.lenght, 6+4=external_inputs
79
80 let z_0 = get_z0();
81 let z_1 = f_circuit
82 .step_native(0, z_0.to_vec(), external_inputs.clone())
83 .unwrap();
84
85 // assign z0
86 let cs = ConstraintSystem::<Fr>::new_ref();
87 let z_0_var = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(z_0)).unwrap();
88 let external_inputs_var =
89 Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(external_inputs)).unwrap();
90
91 // compute constraints for step 0
92 let cs = ConstraintSystem::<Fr>::new_ref();
93 let z_1_var = f_circuit
94 .generate_step_constraints(cs.clone(), 1, z_0_var, external_inputs_var)
95 .unwrap();
96 println!("z_1: {:?}", z_1_var);
97
98 assert_eq!(z_1_var.value().unwrap(), z_1);
99 }
100
101 // WIP
102 /*
103 #[test]
104 fn test_multiple_steps_native() {
105 // initialize new Grapevine function circuit
106 let mut f_circuit = GrapevineFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone()));
107
108 /* DEGREE 1 */
109 // define degree 1 logic inputs
110 let inputs = CircomPrivateInput {
111 phrase: Some(String::from(&*PHRASE)),
112 usernames: [None, Some(String::from(&*USERNAMES[0]))],
113 auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
114 chaff: false,
115 };
116 f_circuit.set_private_input(inputs);
117
118 // compute step 0 (degree 1 logic step)
119 let z_i = f_circuit.step_native(0, get_z0().to_vec()).unwrap();
120
121 // define degree 1 chaff inputs
122 let inputs = CircomPrivateInput::empty(true);
123 f_circuit.set_private_input(inputs);
124
125 // compute step 1 (degree 1 chaff step)
126 let z_i = f_circuit.step_native(1, z_i.to_vec()).unwrap();
127 println!("z_i: {:?}", z_i);
128
129 /* DEGREE 2 */
130 // define degree 2 logic inputs
131 let inputs = CircomPrivateInput {
132 phrase: None,
133 usernames: [
134 Some(String::from(&*USERNAMES[0])),
135 Some(String::from(&*USERNAMES[1])),
136 ],
137 auth_secrets: [Some(AUTH_SECRETS[0].clone()), Some(AUTH_SECRETS[1].clone())],
138 chaff: false,
139 };
140 f_circuit.set_private_input(inputs);
141
142 // compute step 2 (degree 2 logic step)
143 let z_i = f_circuit.step_native(2, z_i.to_vec()).unwrap();
144
145 // define degree 2 chaff inputs
146 let inputs = CircomPrivateInput::empty(true);
147 f_circuit.set_private_input(inputs);
148
149 // compute step 3 (degree 2 chaff step)
150 let z_i = f_circuit.step_native(3, z_i.to_vec()).unwrap();
151
152 /* DEGREE 3 */
153 // define degree 3 logic inputs
154 let inputs = CircomPrivateInput {
155 phrase: None,
156 usernames: [
157 Some(String::from(&*USERNAMES[1])),
158 Some(String::from(&*USERNAMES[2])),
159 ],
160 auth_secrets: [Some(AUTH_SECRETS[1].clone()), Some(AUTH_SECRETS[2].clone())],
161 chaff: false,
162 };
163 f_circuit.set_private_input(inputs);
164
165 // compute step 4 (degree 3 logic step)
166 let z_i = f_circuit.step_native(4, z_i.to_vec()).unwrap();
167
168 // define degree 3 chaff inputs
169 let inputs = CircomPrivateInput::empty(true);
170 f_circuit.set_private_input(inputs);
171
172 // compute step 5 (degree 3 chaff step)
173 let z_i = f_circuit.step_native(5, z_i.to_vec()).unwrap();
174
175 /* RESULT */
176 // @todo: compute hashes natively
177 assert_eq!(z_i[0], Fr::from(3));
178 assert_eq!(z_i[3], Fr::from(0));
179 }
180 */
181
182 // #[test]
183 // fn test_multiple_steps_constraints() {
184 // // initialize new Grapevine function circuit
185 // let mut f_circuit = GrapevineFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone()));
186 //
187 // /* DEGREE 1 */
188 // // define degree 1 logic inputs
189 // let inputs = CircomPrivateInput {
190 // phrase: Some(String::from(&*PHRASE)),
191 // usernames: [None, Some(String::from(&*USERNAMES[0]))],
192 // auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
193 // chaff: false
194 // };
195 // f_circuit.set_private_input(inputs);
196 //
197 // // assign z0
198 // let cs = ConstraintSystem::<Fr>::new_ref();
199 // let z_0_var = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(get_z0())).unwrap();
200 //
201 // // compute constraints for step 0 (degree 1 logic step)
202 // let cs = ConstraintSystem::<Fr>::new_ref();
203 // let z_1_var = f_circuit
204 // .generate_step_constraints(cs.clone(), 0, z_0_var)
205 // .unwrap();
206 // println!("z_1: {:?}", z_1_var);
207 //
208 // // define degree 1 chaff inputs
209 // let inputs = CircomPrivateInput::empty(true);
210 // f_circuit.set_private_input(inputs);
211 //
212 // // compute step 1 (degree 1 chaff step)
213 // let z_i = f_circuit.step_native(1, z_i.to_vec()).unwrap();
214 // println!("z_i: {:?}", z_i);
215 //
216 // // define inputs
217 // let step_0_inputs = CircomPrivateInput {
218 // phrase: Some(String::from(&*PHRASE)),
219 // usernames: [None, Some(String::from(&*USERNAMES[0]))],
220 // auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
221 // chaff: false
222 // };
223 //
224 // // initialize new Grapevine function circuit
225 // let mut f_circuit = GrapevineFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone()));
226 // f_circuit.set_private_input(step_0_inputs);
227 //
228 // }
229
230 /*
231 #[test]
232 fn test_full_one_step() {
233 // initialize new Grapevine function circuit
234 let mut f_circuit = GrapevineFCircuit::<Fr>::new((R1CS_PATH.clone(), WASM_PATH.clone()));
235
236 // Get test params
237 let (prover_params, verifier_params) =
238 test_nova_setup::<GrapevineFCircuit<Fr>>(f_circuit.clone());
239
240 // define inputs
241 // define inputs
242 let step_0_inputs = CircomPrivateInput {
243 phrase: Some(String::from(&*PHRASE)),
244 usernames: [None, Some(String::from(&*USERNAMES[0]))],
245 auth_secrets: [None, Some(AUTH_SECRETS[0].clone())],
246 chaff: false,
247 };
248 // let z_0 = get_z0();
249 }
250
251 #[test]
252 fn test_full() {
253 let num_steps = 10;
254 let initial_state = vec![Fr::from(19), Fr::from(0)];
255
256 let r1cs_path = PathBuf::from("./circom/artifacts/grapevine.r1cs");
257 let wasm_path = PathBuf::from("./circom/artifacts/grapevine.wasm");
258
259 let f_circuit = GrapevineFCircuit::<Fr>::new((r1cs_path, wasm_path));
260
261 let start = Instant::now();
262 println!("Generating params...");
263 let (prover_params, verifier_params) =
264 test_nova_setup::<GrapevineFCircuit<Fr>>(f_circuit.clone());
265 println!("Generated params: {:?}", start.elapsed());
266 type NOVA = Nova<
267 Projective,
268 GVar,
269 Projective2,
270 GVar2,
271 GrapevineFCircuit<Fr>,
272 Pedersen<Projective>,
273 Pedersen<Projective2>,
274 >;
275
276 let start = Instant::now();
277 println!("Initializing folding scheme...");
278 let mut folding_scheme =
279 NOVA::init(&prover_params, f_circuit, initial_state.clone()).unwrap();
280 println!("Initialized folding scheme: {:?}", start.elapsed());
281
282 for i in 0..num_steps {
283 let start = Instant::now();
284 folding_scheme.prove_step().unwrap();
285 println!("Proved step {}: {:?}", i, start.elapsed());
286 }
287
288 let (running_instance, incoming_instance, cyclefold_instance) = folding_scheme.instances();
289
290 println!("Running IVC Verifier...");
291 let start = Instant::now();
292 NOVA::verify(
293 verifier_params,
294 initial_state.clone(),
295 folding_scheme.state(),
296 Fr::from(num_steps as u32),
297 running_instance,
298 incoming_instance,
299 cyclefold_instance,
300 )
301 .unwrap();
302 println!("Verified: {:?}", start.elapsed());
303 }
304 */
305}