arnaucube
arnaucube/grapevine-sonobePublic Self-hosted repository
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}