diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6a9edfd..389f9e95 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,7 +180,7 @@ jobs: feature_set: [basic, wasm] include: - feature_set: basic - features: --features default,light-test + features: --features default # We only want to test `frontends` package with `wasm` feature. - feature_set: wasm features: -p frontends --features wasm,parallel --target wasm32-unknown-unknown diff --git a/Cargo.toml b/Cargo.toml index 46e1281f..67aafb5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,6 @@ members = [ "folding-schemes", "solidity-verifiers", "cli", - "frontends" + "experimental-frontends" ] resolver = "2" diff --git a/README.md b/README.md index 3da10531..1898025a 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ Folding schemes implemented: - [Nova: Recursive Zero-Knowledge Arguments from Folding Schemes](https://eprint.iacr.org/2021/370.pdf), Abhiram Kothapalli, Srinath Setty, Ioanna Tzialla. 2021 - [CycleFold: Folding-scheme-based recursive arguments over a cycle of elliptic curves](https://eprint.iacr.org/2023/1192.pdf), Abhiram Kothapalli, Srinath Setty. 2023 - [HyperNova: Recursive arguments for customizable constraint systems](https://eprint.iacr.org/2023/573.pdf), Abhiram Kothapalli, Srinath Setty. 2023 - -Work in progress: - - [ProtoGalaxy: Efficient ProtoStar-style folding of multiple instances](https://eprint.iacr.org/2023/1106.pdf), Liam Eagen, Ariel Gabizon. 2023 @@ -34,7 +31,7 @@ Work in progress: Frontends allow to define the circuit to be folded (ie. `FCircuit`). The recommended frontend is directly implementing the [`FCircuit` trait](https://github.com/privacy-scaling-explorations/sonobe/blob/main/folding-schemes/src/frontend/mod.rs#L16) with the Arkworks constraint system. -Alternatively, experimental frontends for [Circom](https://github.com/iden3/circom), [Noir](https://github.com/noir-lang/noir) and [Noname](https://github.com/zksecurity/noname) can be found at the [sonobe/frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/frontends) directory, which have some computational (and time) overhead. +Alternatively, experimental frontends for [Circom](https://github.com/iden3/circom), [Noir](https://github.com/noir-lang/noir) and [Noname](https://github.com/zksecurity/noname) can be found at the [sonobe/experimental-frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/experimental-frontends) directory, which have some computational (and time) overhead. More details about the frontend interface and the experimental frontends can be found at the [sonobe-docs/frontend](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/frontend.html) page. @@ -49,7 +46,7 @@ folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonob Available packages: - `folding-schemes`: main crate, contains the different scheme implementations, together with commitment schemes, frontend trait, arithmetization, transcript, etc. - `solidity-verifiers`: contains the templating logic to output the verifier contracts for the DeciderEth proofs. Currently only supports Nova+CycleFold DeciderEth proofs. -- `frontends`: contains the experimental frontends other than the arkworks frontend. More details at the [sonobe/frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/frontends) directory. +- `experimental-frontends`: contains the experimental frontends other than the arkworks frontend. More details at the [sonobe/experimental-frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/experimental-frontends) directory. Available features: - `parallel` enables some parallelization optimizations available in the crate. It is enabled by default. @@ -105,7 +102,7 @@ Sonobe is [MIT Licensed](https://github.com/privacy-scaling-explorations/sonobe/ ## Acknowledgments -This project builds on top of multiple [arkworks](https://github.com/arkworks-rs) libraries. It uses Espresso system's [virtual polynomial](https://github.com/EspressoSystems/hyperplonk/blob/main/arithmetic/src/virtual_polynomial.rs) abstraction and its [SumCheck](https://github.com/EspressoSystems/hyperplonk/tree/main/subroutines/src/poly_iop/sum_check) implementation. +This project builds on top of multiple [arkworks](https://github.com/arkworks-rs) libraries. It uses Espresso System's [virtual polynomial](https://github.com/EspressoSystems/hyperplonk/blob/main/arithmetic/src/virtual_polynomial.rs) abstraction and its [SumCheck](https://github.com/EspressoSystems/hyperplonk/tree/main/subroutines/src/poly_iop/sum_check) implementation. The Solidity templates used in `nova_cyclefold_verifier.sol`, use [iden3](https://github.com/iden3/snarkjs/blob/master/templates/verifier_groth16.sol.ejs)'s Groth16 implementation and a KZG10 Solidity template adapted from [weijiekoh/libkzg](https://github.com/weijiekoh/libkzg). diff --git a/examples/circom_full_flow.rs b/examples/circom_full_flow.rs index d9fdb0f8..16748b89 100644 --- a/examples/circom_full_flow.rs +++ b/examples/circom_full_flow.rs @@ -17,6 +17,7 @@ use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2}; use std::path::PathBuf; use std::time::Instant; +use experimental_frontends::circom::CircomFCircuit; use folding_schemes::{ commitment::{kzg::KZG, pedersen::Pedersen}, folding::{ @@ -28,9 +29,8 @@ use folding_schemes::{ }, frontend::FCircuit, transcript::poseidon::poseidon_canonical_config, - Decider, FoldingScheme, + Decider, Error, FoldingScheme, }; -use frontends::circom::CircomFCircuit; use solidity_verifiers::{ evm::{compile_solidity, Evm}, utils::get_function_selector_for_nova_cyclefold_verifier, @@ -38,7 +38,7 @@ use solidity_verifiers::{ NovaCycleFoldVerifierKey, }; -fn main() { +fn main() -> Result<(), Error> { // set the initial state let z_0 = vec![Fr::from(3_u32)]; @@ -58,13 +58,14 @@ fn main() { ]; // initialize the Circom circuit - let r1cs_path = PathBuf::from("./frontends/src/circom/test_folder/with_external_inputs.r1cs"); + let r1cs_path = + PathBuf::from("./experimental-frontends/src/circom/test_folder/with_external_inputs.r1cs"); let wasm_path = PathBuf::from( - "./frontends/src/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm", + "./experimental-frontends/src/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm", ); let f_circuit_params = (r1cs_path.into(), wasm_path.into(), 1, 2); - let f_circuit = CircomFCircuit::::new(f_circuit_params).unwrap(); + let f_circuit = CircomFCircuit::::new(f_circuit_params)?; pub type N = Nova, KZG<'static, Bn254>, Pedersen, false>; @@ -85,20 +86,18 @@ fn main() { // prepare the Nova prover & verifier params let nova_preprocess_params = PreprocessorParam::new(poseidon_config, f_circuit.clone()); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; // initialize the folding scheme engine, in our case we use Nova - let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap(); + let mut nova = N::init(&nova_params, f_circuit.clone(), z_0)?; // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = - D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params.clone(), nova.clone())?; // run n steps of the folding iteration for (i, external_inputs_at_step) in external_inputs.iter().enumerate() { let start = Instant::now(); - nova.prove_step(rng, external_inputs_at_step.clone(), None) - .unwrap(); + nova.prove_step(rng, external_inputs_at_step.clone(), None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } @@ -107,11 +106,10 @@ fn main() { N::verify( nova_params.1, // Nova's verifier params ivc_proof, - ) - .unwrap(); + )?; let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("generated Decider proof: {:?}", start.elapsed()); let verified = D::verify( @@ -122,8 +120,7 @@ fn main() { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider proof verification: {}", verified); @@ -139,8 +136,7 @@ fn main() { &nova.U_i, &nova.u_i, proof, - ) - .unwrap(); + )?; // prepare the setup params for the solidity verifier let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((decider_vp, f_circuit.state_len())); @@ -161,9 +157,9 @@ fn main() { fs::write( "./examples/nova-verifier.sol", decider_solidity_code.clone(), - ) - .unwrap(); - fs::write("./examples/solidity-calldata.calldata", calldata.clone()).unwrap(); + )?; + fs::write("./examples/solidity-calldata.calldata", calldata.clone())?; let s = solidity_verifiers::utils::get_formatted_calldata(calldata.clone()); fs::write("./examples/solidity-calldata.inputs", s.join(",\n")).expect(""); + Ok(()) } diff --git a/examples/full_flow.rs b/examples/full_flow.rs index 95b33ff4..a3860244 100644 --- a/examples/full_flow.rs +++ b/examples/full_flow.rs @@ -77,12 +77,12 @@ impl FCircuit for CubicFCircuit { } } -fn main() { +fn main() -> Result<(), Error> { let n_steps = 5; // set the initial state let z_0 = vec![Fr::from(3_u32)]; - let f_circuit = CubicFCircuit::::new(()).unwrap(); + let f_circuit = CubicFCircuit::::new(())?; pub type N = Nova, KZG<'static, Bn254>, Pedersen, false>; @@ -103,23 +103,23 @@ fn main() { // prepare the Nova prover & verifier params let nova_preprocess_params = PreprocessorParam::new(poseidon_config.clone(), f_circuit); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; // initialize the folding scheme engine, in our case we use Nova - let mut nova = N::init(&nova_params, f_circuit, z_0).unwrap(); + let mut nova = N::init(&nova_params, f_circuit, z_0)?; // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone())?; // run n steps of the folding iteration for i in 0..n_steps { let start = Instant::now(); - nova.prove_step(rng, vec![], None).unwrap(); + nova.prove_step(rng, vec![], None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("generated Decider proof: {:?}", start.elapsed()); let verified = D::verify( @@ -130,8 +130,7 @@ fn main() { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider proof verification: {}", verified); @@ -147,8 +146,7 @@ fn main() { &nova.U_i, &nova.u_i, proof, - ) - .unwrap(); + )?; // prepare the setup params for the solidity verifier let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((decider_vp, f_circuit.state_len())); @@ -169,9 +167,9 @@ fn main() { fs::write( "./examples/nova-verifier.sol", decider_solidity_code.clone(), - ) - .unwrap(); - fs::write("./examples/solidity-calldata.calldata", calldata.clone()).unwrap(); + )?; + fs::write("./examples/solidity-calldata.calldata", calldata.clone())?; let s = solidity_verifiers::utils::get_formatted_calldata(calldata.clone()); fs::write("./examples/solidity-calldata.inputs", s.join(",\n")).expect(""); + Ok(()) } diff --git a/examples/multi_inputs.rs b/examples/multi_inputs.rs index a337c894..b11f89ac 100644 --- a/examples/multi_inputs.rs +++ b/examples/multi_inputs.rs @@ -88,10 +88,10 @@ pub mod tests { // test to check that the MultiInputsFCircuit computes the same values inside and outside the circuit #[test] - fn test_f_circuit() { + fn test_f_circuit() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); - let circuit = MultiInputsFCircuit::::new(()).unwrap(); + let circuit = MultiInputsFCircuit::::new(())?; let z_i = vec![ Fr::from(1_u32), Fr::from(1_u32), @@ -100,18 +100,18 @@ pub mod tests { Fr::from(1_u32), ]; - let z_i1 = circuit.step_native(0, z_i.clone(), vec![]).unwrap(); + let z_i1 = circuit.step_native(0, z_i.clone(), vec![])?; - let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i)).unwrap(); - let computed_z_i1Var = circuit - .generate_step_constraints(cs.clone(), 0, z_iVar.clone(), vec![]) - .unwrap(); - assert_eq!(computed_z_i1Var.value().unwrap(), z_i1); + let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i))?; + let computed_z_i1Var = + circuit.generate_step_constraints(cs.clone(), 0, z_iVar.clone(), vec![])?; + assert_eq!(computed_z_i1Var.value()?, z_i1); + Ok(()) } } /// cargo run --release --example multi_inputs -fn main() { +fn main() -> Result<(), Error> { let num_steps = 10; let initial_state = vec![ Fr::from(1_u32), @@ -121,7 +121,7 @@ fn main() { Fr::from(1_u32), ]; - let F_circuit = MultiInputsFCircuit::::new(()).unwrap(); + let F_circuit = MultiInputsFCircuit::::new(())?; let poseidon_config = poseidon_canonical_config::(); let mut rng = rand::rngs::OsRng; @@ -142,15 +142,15 @@ fn main() { println!("Prepare Nova ProverParams & VerifierParams"); let nova_preprocess_params = PreprocessorParam::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; println!("Initialize FoldingScheme"); - let mut folding_scheme = N::init(&nova_params, F_circuit, initial_state.clone()).unwrap(); + let mut folding_scheme = N::init(&nova_params, F_circuit, initial_state.clone())?; // compute a step of the IVC for i in 0..num_steps { let start = Instant::now(); - folding_scheme.prove_step(rng, vec![], None).unwrap(); + folding_scheme.prove_step(rng, vec![], None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } @@ -159,6 +159,6 @@ fn main() { N::verify( nova_params.1, // Nova's verifier params ivc_proof, - ) - .unwrap(); + )?; + Ok(()) } diff --git a/examples/noir_full_flow.rs b/examples/noir_full_flow.rs index 871dd74d..aa2fc2da 100644 --- a/examples/noir_full_flow.rs +++ b/examples/noir_full_flow.rs @@ -14,6 +14,7 @@ use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1}; use ark_groth16::Groth16; use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2}; +use experimental_frontends::noir::NoirFCircuit; use folding_schemes::{ commitment::{kzg::KZG, pedersen::Pedersen}, folding::{ @@ -25,9 +26,8 @@ use folding_schemes::{ }, frontend::FCircuit, transcript::poseidon::poseidon_canonical_config, - Decider, FoldingScheme, + Decider, Error, FoldingScheme, }; -use frontends::noir::NoirFCircuit; use std::{path::Path, time::Instant}; use solidity_verifiers::{ @@ -37,17 +37,17 @@ use solidity_verifiers::{ NovaCycleFoldVerifierKey, }; -fn main() { +fn main() -> Result<(), Error> { // set the initial state let z_0 = vec![Fr::from(1)]; // initialize the noir fcircuit let f_circuit = NoirFCircuit::new(( - Path::new("./frontends/src/noir/test_folder/test_mimc/target/test_mimc.json").into(), + Path::new("./experimental-frontends/src/noir/test_folder/test_mimc/target/test_mimc.json") + .into(), 1, 0, - )) - .unwrap(); + ))?; pub type N = Nova, KZG<'static, Bn254>, Pedersen>; pub type D = DeciderEth< @@ -67,19 +67,18 @@ fn main() { // prepare the Nova prover & verifier params let nova_preprocess_params = PreprocessorParam::new(poseidon_config, f_circuit.clone()); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; // initialize the folding scheme engine, in our case we use Nova - let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap(); + let mut nova = N::init(&nova_params, f_circuit.clone(), z_0)?; // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = - D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params.clone(), nova.clone())?; // run n steps of the folding iteration for i in 0..5 { let start = Instant::now(); - nova.prove_step(rng, vec![], None).unwrap(); + nova.prove_step(rng, vec![], None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } // verify the last IVC proof @@ -87,11 +86,10 @@ fn main() { N::verify( nova_params.1, // Nova's verifier params ivc_proof, - ) - .unwrap(); + )?; let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("generated Decider proof: {:?}", start.elapsed()); let verified = D::verify( @@ -102,8 +100,7 @@ fn main() { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider proof verification: {}", verified); @@ -119,8 +116,7 @@ fn main() { &nova.U_i, &nova.u_i, proof, - ) - .unwrap(); + )?; // prepare the setup params for the solidity verifier let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((decider_vp, f_circuit.state_len())); @@ -141,9 +137,9 @@ fn main() { fs::write( "./examples/nova-verifier.sol", decider_solidity_code.clone(), - ) - .unwrap(); - fs::write("./examples/solidity-calldata.calldata", calldata.clone()).unwrap(); + )?; + fs::write("./examples/solidity-calldata.calldata", calldata.clone())?; let s = solidity_verifiers::utils::get_formatted_calldata(calldata.clone()); fs::write("./examples/solidity-calldata.inputs", s.join(",\n")).expect(""); + Ok(()) } diff --git a/examples/noname_full_flow.rs b/examples/noname_full_flow.rs index 0bb6e41a..0cf55e1d 100644 --- a/examples/noname_full_flow.rs +++ b/examples/noname_full_flow.rs @@ -15,6 +15,7 @@ use noname::backends::r1cs::R1csBn254Field; use ark_groth16::Groth16; use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2}; +use experimental_frontends::noname::NonameFCircuit; use folding_schemes::{ commitment::{kzg::KZG, pedersen::Pedersen}, folding::{ @@ -26,9 +27,8 @@ use folding_schemes::{ }, frontend::FCircuit, transcript::poseidon::poseidon_canonical_config, - Decider, FoldingScheme, + Decider, Error, FoldingScheme, }; -use frontends::noname::NonameFCircuit; use std::time::Instant; use solidity_verifiers::{ @@ -38,7 +38,7 @@ use solidity_verifiers::{ NovaCycleFoldVerifierKey, }; -fn main() { +fn main() -> Result<(), Error> { const NONAME_CIRCUIT_EXTERNAL_INPUTS: &str = "fn main(pub ivc_inputs: [Field; 2], external_inputs: [Field; 2]) -> [Field; 2] { let xx = external_inputs[0] + ivc_inputs[0]; @@ -59,7 +59,7 @@ fn main() { // initialize the noname circuit let f_circuit_params = (NONAME_CIRCUIT_EXTERNAL_INPUTS.to_owned(), 2, 2); - let f_circuit = NonameFCircuit::::new(f_circuit_params).unwrap(); + let f_circuit = NonameFCircuit::::new(f_circuit_params)?; pub type N = Nova< G1, @@ -87,20 +87,18 @@ fn main() { // prepare the Nova prover & verifier params let nova_preprocess_params = PreprocessorParam::new(poseidon_config, f_circuit.clone()); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; // initialize the folding scheme engine, in our case we use Nova - let mut nova = N::init(&nova_params, f_circuit.clone(), z_0).unwrap(); + let mut nova = N::init(&nova_params, f_circuit.clone(), z_0)?; // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = - D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params.clone(), nova.clone())?; // run n steps of the folding iteration for (i, external_inputs_at_step) in external_inputs.iter().enumerate() { let start = Instant::now(); - nova.prove_step(rng, external_inputs_at_step.clone(), None) - .unwrap(); + nova.prove_step(rng, external_inputs_at_step.clone(), None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } @@ -109,11 +107,10 @@ fn main() { N::verify( nova_params.1, // Nova's verifier params ivc_proof, - ) - .unwrap(); + )?; let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("generated Decider proof: {:?}", start.elapsed()); let verified = D::verify( @@ -124,8 +121,7 @@ fn main() { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider proof verification: {}", verified); @@ -141,8 +137,7 @@ fn main() { &nova.U_i, &nova.u_i, proof, - ) - .unwrap(); + )?; // prepare the setup params for the solidity verifier let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((decider_vp, f_circuit.state_len())); @@ -163,9 +158,9 @@ fn main() { fs::write( "./examples/nova-verifier.sol", decider_solidity_code.clone(), - ) - .unwrap(); - fs::write("./examples/solidity-calldata.calldata", calldata.clone()).unwrap(); + )?; + fs::write("./examples/solidity-calldata.calldata", calldata.clone())?; let s = solidity_verifiers::utils::get_formatted_calldata(calldata.clone()); fs::write("./examples/solidity-calldata.inputs", s.join(",\n")).expect(""); + Ok(()) } diff --git a/examples/sha256.rs b/examples/sha256.rs index 0df3a441..5ff35a55 100644 --- a/examples/sha256.rs +++ b/examples/sha256.rs @@ -88,28 +88,28 @@ pub mod tests { // test to check that the Sha256FCircuit computes the same values inside and outside the circuit #[test] - fn test_f_circuit() { + fn test_f_circuit() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); - let circuit = Sha256FCircuit::::new(()).unwrap(); + let circuit = Sha256FCircuit::::new(())?; let z_i = vec![Fr::from(1_u32)]; - let z_i1 = circuit.step_native(0, z_i.clone(), vec![]).unwrap(); + let z_i1 = circuit.step_native(0, z_i.clone(), vec![])?; - let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i)).unwrap(); - let computed_z_i1Var = circuit - .generate_step_constraints(cs.clone(), 0, z_iVar.clone(), vec![]) - .unwrap(); - assert_eq!(computed_z_i1Var.value().unwrap(), z_i1); + let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i))?; + let computed_z_i1Var = + circuit.generate_step_constraints(cs.clone(), 0, z_iVar.clone(), vec![])?; + assert_eq!(computed_z_i1Var.value()?, z_i1); + Ok(()) } } /// cargo run --release --example sha256 -fn main() { +fn main() -> Result<(), Error> { let num_steps = 10; let initial_state = vec![Fr::from(1_u32)]; - let F_circuit = Sha256FCircuit::::new(()).unwrap(); + let F_circuit = Sha256FCircuit::::new(())?; /// The idea here is that eventually we could replace the next line chunk that defines the /// `type N = Nova<...>` by using another folding scheme that fulfills the `FoldingScheme` @@ -130,14 +130,14 @@ fn main() { println!("Prepare Nova ProverParams & VerifierParams"); let nova_preprocess_params = PreprocessorParam::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap(); + let nova_params = N::preprocess(&mut rng, &nova_preprocess_params)?; println!("Initialize FoldingScheme"); - let mut folding_scheme = N::init(&nova_params, F_circuit, initial_state.clone()).unwrap(); + let mut folding_scheme = N::init(&nova_params, F_circuit, initial_state.clone())?; // compute a step of the IVC for i in 0..num_steps { let start = Instant::now(); - folding_scheme.prove_step(rng, vec![], None).unwrap(); + folding_scheme.prove_step(rng, vec![], None)?; println!("Nova::prove_step {}: {:?}", i, start.elapsed()); } @@ -146,6 +146,6 @@ fn main() { N::verify( nova_params.1, // Nova's verifier params ivc_proof, - ) - .unwrap(); + )?; + Ok(()) } diff --git a/frontends/Cargo.toml b/experimental-frontends/Cargo.toml similarity index 97% rename from frontends/Cargo.toml rename to experimental-frontends/Cargo.toml index faac937e..eadf7a3f 100644 --- a/frontends/Cargo.toml +++ b/experimental-frontends/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "frontends" +name = "experimental-frontends" version = "0.1.0" edition = "2021" diff --git a/frontends/README.md b/experimental-frontends/README.md similarity index 97% rename from frontends/README.md rename to experimental-frontends/README.md index e43cfa18..dedc9e77 100644 --- a/frontends/README.md +++ b/experimental-frontends/README.md @@ -1,9 +1,8 @@ -# frontends +# experimental-frontends This crate contains *experimental frontends* for Sonobe. The recommended frontend is to directly use [arkworks](https://github.com/arkworks-rs) to define the FCircuit, just following the [`FCircuit` trait](https://github.com/privacy-scaling-explorations/sonobe/blob/main/folding-schemes/src/frontend/mod.rs). -## Experimental frontends > Warning: the following frontends are experimental and some computational and time overhead is expected when using them compared to directly using the [arkworks frontend](https://github.com/privacy-scaling-explorations/sonobe/blob/main/folding-schemes/src/frontend/mod.rs). Available experimental frontends: diff --git a/frontends/src/circom/mod.rs b/experimental-frontends/src/circom/mod.rs similarity index 86% rename from frontends/src/circom/mod.rs rename to experimental-frontends/src/circom/mod.rs index 313a5602..f0bdd0cb 100644 --- a/frontends/src/circom/mod.rs +++ b/experimental-frontends/src/circom/mod.rs @@ -210,100 +210,99 @@ pub mod tests { // Tests the step_native function of CircomFCircuit. #[test] - fn test_circom_step_native() { + fn test_circom_step_native() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); let circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0 + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0))?; // state_len:1, external_inputs_len:0 let z_i = vec![Fr::from(3u32)]; - let z_i1 = circom_fcircuit.step_native(1, z_i, vec![]).unwrap(); + let z_i1 = circom_fcircuit.step_native(1, z_i, vec![])?; assert_eq!(z_i1, vec![Fr::from(35u32)]); + Ok(()) } // Tests the generate_step_constraints function of CircomFCircuit. #[test] - fn test_circom_step_constraints() { + fn test_circom_step_constraints() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); let circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0 + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0))?; // state_len:1, external_inputs_len:0 let cs = ConstraintSystem::::new_ref(); let z_i = vec![Fr::from(3u32)]; - let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i)).unwrap(); - let z_i1_var = circom_fcircuit - .generate_step_constraints(cs.clone(), 1, z_i_var, vec![]) - .unwrap(); - assert_eq!(z_i1_var.value().unwrap(), vec![Fr::from(35u32)]); + let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i))?; + let z_i1_var = circom_fcircuit.generate_step_constraints(cs.clone(), 1, z_i_var, vec![])?; + assert_eq!(z_i1_var.value()?, vec![Fr::from(35u32)]); + Ok(()) } // Tests the WrapperCircuit with CircomFCircuit. #[test] - fn test_wrapper_circomtofcircuit() { + fn test_wrapper_circomtofcircuit() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); let circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0 + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0))?; // state_len:1, external_inputs_len:0 // Allocates z_i1 by using step_native function. let z_i = vec![Fr::from(3_u32)]; let wrapper_circuit = folding_schemes::frontend::utils::WrapperCircuit { FC: circom_fcircuit.clone(), z_i: Some(z_i.clone()), - z_i1: Some(circom_fcircuit.step_native(0, z_i.clone(), vec![]).unwrap()), + z_i1: Some(circom_fcircuit.step_native(0, z_i.clone(), vec![])?), }; let cs = ConstraintSystem::::new_ref(); - wrapper_circuit.generate_constraints(cs.clone()).unwrap(); - assert!( - cs.is_satisfied().unwrap(), - "Constraint system is not satisfied" - ); + wrapper_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?, "Constraint system is not satisfied"); + Ok(()) } #[test] - fn test_circom_external_inputs() { + fn test_circom_external_inputs() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/with_external_inputs.r1cs"); let wasm_path = PathBuf::from( "./src/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm", ); let circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 2)).unwrap(); // state_len:1, external_inputs_len:2 + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 2))?; // state_len:1, external_inputs_len:2 let cs = ConstraintSystem::::new_ref(); let z_i = vec![Fr::from(3u32)]; let external_inputs = vec![Fr::from(6u32), Fr::from(7u32)]; // run native step - let z_i1_native = circom_fcircuit - .step_native(1, z_i.clone(), external_inputs.clone()) - .unwrap(); + let z_i1_native = circom_fcircuit.step_native(1, z_i.clone(), external_inputs.clone())?; // run gadget step - let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i)).unwrap(); + let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i))?; let external_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(external_inputs.clone())).unwrap(); - let z_i1_var = circom_fcircuit - .generate_step_constraints(cs.clone(), 1, z_i_var, external_inputs_var) - .unwrap(); + Vec::>::new_witness(cs.clone(), || Ok(external_inputs.clone()))?; + let z_i1_var = circom_fcircuit.generate_step_constraints( + cs.clone(), + 1, + z_i_var, + external_inputs_var, + )?; - assert_eq!(z_i1_var.value().unwrap(), z_i1_native); + assert_eq!(z_i1_var.value()?, z_i1_native); // re-init cs and run gadget step with wrong ivc inputs (first ivc should not be zero) let cs = ConstraintSystem::::new_ref(); let wrong_z_i = vec![Fr::from(0)]; - let wrong_z_i_var = Vec::>::new_witness(cs.clone(), || Ok(wrong_z_i)).unwrap(); + let wrong_z_i_var = Vec::>::new_witness(cs.clone(), || Ok(wrong_z_i))?; let external_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(external_inputs)).unwrap(); + Vec::>::new_witness(cs.clone(), || Ok(external_inputs))?; let _z_i1_var = circom_fcircuit.generate_step_constraints( cs.clone(), 1, @@ -313,48 +312,48 @@ pub mod tests { // TODO:: https://github.com/privacy-scaling-explorations/sonobe/issues/104 // Disable check for now // assert!(z_i1_var.is_err()); + Ok(()) } #[test] - fn test_circom_no_external_inputs() { + fn test_circom_no_external_inputs() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/no_external_inputs.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/no_external_inputs_js/no_external_inputs.wasm"); let circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 3, 0)).unwrap(); + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 3, 0))?; let cs = ConstraintSystem::::new_ref(); let z_i = vec![Fr::from(3u32), Fr::from(4u32), Fr::from(5u32)]; - let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone())).unwrap(); + let z_i_var = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone()))?; // run native step - let z_i1_native = circom_fcircuit.step_native(1, z_i.clone(), vec![]).unwrap(); + let z_i1_native = circom_fcircuit.step_native(1, z_i.clone(), vec![])?; // run gadget step - let z_i1_var = circom_fcircuit - .generate_step_constraints(cs.clone(), 1, z_i_var, vec![]) - .unwrap(); + let z_i1_var = circom_fcircuit.generate_step_constraints(cs.clone(), 1, z_i_var, vec![])?; - assert_eq!(z_i1_var.value().unwrap(), z_i1_native); + assert_eq!(z_i1_var.value()?, z_i1_native); // re-init cs and run gadget step with wrong ivc inputs (first ivc input should not be zero) let cs = ConstraintSystem::::new_ref(); let wrong_z_i = vec![Fr::from(0u32), Fr::from(4u32), Fr::from(5u32)]; - let wrong_z_i_var = Vec::>::new_witness(cs.clone(), || Ok(wrong_z_i)).unwrap(); + let wrong_z_i_var = Vec::>::new_witness(cs.clone(), || Ok(wrong_z_i))?; let _z_i1_var = circom_fcircuit.generate_step_constraints(cs.clone(), 1, wrong_z_i_var, vec![]); // TODO:: https://github.com/privacy-scaling-explorations/sonobe/issues/104 // Disable check for now // assert!(z_i1_var.is_err()) + Ok(()) } #[test] - fn test_custom_code() { + fn test_custom_code() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); let mut circom_fcircuit = - CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0 + CircomFCircuit::::new((r1cs_path.into(), wasm_path.into(), 1, 0))?; // state_len:1, external_inputs_len:0 circom_fcircuit.set_custom_step_native(Rc::new(|_i, z_i, _external| { let z = z_i[0]; @@ -366,15 +365,13 @@ pub mod tests { let wrapper_circuit = folding_schemes::frontend::utils::WrapperCircuit { FC: circom_fcircuit.clone(), z_i: Some(z_i.clone()), - z_i1: Some(circom_fcircuit.step_native(0, z_i.clone(), vec![]).unwrap()), + z_i1: Some(circom_fcircuit.step_native(0, z_i.clone(), vec![])?), }; let cs = ConstraintSystem::::new_ref(); - wrapper_circuit.generate_constraints(cs.clone()).unwrap(); - assert!( - cs.is_satisfied().unwrap(), - "Constraint system is not satisfied" - ); + wrapper_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?, "Constraint system is not satisfied"); + Ok(()) } } diff --git a/frontends/src/circom/test_folder/circuits/is_zero.circom b/experimental-frontends/src/circom/test_folder/circuits/is_zero.circom similarity index 100% rename from frontends/src/circom/test_folder/circuits/is_zero.circom rename to experimental-frontends/src/circom/test_folder/circuits/is_zero.circom diff --git a/frontends/src/circom/test_folder/compile.sh b/experimental-frontends/src/circom/test_folder/compile.sh similarity index 100% rename from frontends/src/circom/test_folder/compile.sh rename to experimental-frontends/src/circom/test_folder/compile.sh diff --git a/frontends/src/circom/test_folder/cubic_circuit.circom b/experimental-frontends/src/circom/test_folder/cubic_circuit.circom similarity index 100% rename from frontends/src/circom/test_folder/cubic_circuit.circom rename to experimental-frontends/src/circom/test_folder/cubic_circuit.circom diff --git a/frontends/src/circom/test_folder/no_external_inputs.circom b/experimental-frontends/src/circom/test_folder/no_external_inputs.circom similarity index 100% rename from frontends/src/circom/test_folder/no_external_inputs.circom rename to experimental-frontends/src/circom/test_folder/no_external_inputs.circom diff --git a/frontends/src/circom/test_folder/with_external_inputs.circom b/experimental-frontends/src/circom/test_folder/with_external_inputs.circom similarity index 100% rename from frontends/src/circom/test_folder/with_external_inputs.circom rename to experimental-frontends/src/circom/test_folder/with_external_inputs.circom diff --git a/frontends/src/circom/utils.rs b/experimental-frontends/src/circom/utils.rs similarity index 94% rename from frontends/src/circom/utils.rs rename to experimental-frontends/src/circom/utils.rs index 0050be5b..34448be0 100644 --- a/frontends/src/circom/utils.rs +++ b/experimental-frontends/src/circom/utils.rs @@ -145,7 +145,7 @@ mod tests { // Test the satisfication by using the CircomBuilder of circom-compat #[test] - fn test_circombuilder_satisfied() { + fn test_circombuilder_satisfied() -> Result<(), Error> { let cfg = CircomConfig::::new( "./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm", "./src/circom/test_folder/cubic_circuit.r1cs", @@ -156,21 +156,22 @@ mod tests { let circom = builder.build().unwrap(); let cs = ConstraintSystem::::new_ref(); - circom.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + circom.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); + Ok(()) } // Test the satisfication by using the CircomWrapper #[test] - fn test_extract_r1cs_and_witness() { + fn test_extract_r1cs_and_witness() -> Result<(), Error> { let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs"); let wasm_path = PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm"); let inputs = vec![("ivc_input".to_string(), vec![BigInt::from(3)])]; - let wrapper = CircomWrapper::::new(r1cs_path.into(), wasm_path.into()).unwrap(); + let wrapper = CircomWrapper::::new(r1cs_path.into(), wasm_path.into())?; - let (r1cs, witness) = wrapper.extract_r1cs_and_witness(&inputs).unwrap(); + let (r1cs, witness) = wrapper.extract_r1cs_and_witness(&inputs)?; let cs = ConstraintSystem::::new_ref(); @@ -181,7 +182,8 @@ mod tests { allocate_inputs_as_witnesses: false, }; - circom_circuit.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + circom_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); + Ok(()) } } diff --git a/frontends/src/lib.rs b/experimental-frontends/src/lib.rs similarity index 100% rename from frontends/src/lib.rs rename to experimental-frontends/src/lib.rs diff --git a/frontends/src/noir/bridge.rs b/experimental-frontends/src/noir/bridge.rs similarity index 100% rename from frontends/src/noir/bridge.rs rename to experimental-frontends/src/noir/bridge.rs diff --git a/frontends/src/noir/mod.rs b/experimental-frontends/src/noir/mod.rs similarity index 89% rename from frontends/src/noir/mod.rs rename to experimental-frontends/src/noir/mod.rs index d52758a0..4c7f58b8 100644 --- a/frontends/src/noir/mod.rs +++ b/experimental-frontends/src/noir/mod.rs @@ -236,54 +236,52 @@ mod tests { use ark_r1cs_std::R1CSVar; use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar}; use ark_relations::r1cs::ConstraintSystem; - use folding_schemes::frontend::FCircuit; + use folding_schemes::{frontend::FCircuit, Error}; use std::env; use crate::noir::NoirFCircuit; #[test] - fn test_step_native() { - let cur_path = env::current_dir().unwrap(); + fn test_step_native() -> Result<(), Error> { + let cur_path = env::current_dir()?; let noirfcircuit = NoirFCircuit::new(( cur_path .join("src/noir/test_folder/test_circuit/target/test_circuit.json") .into(), 2, 2, - )) - .unwrap(); + ))?; let inputs = vec![Fr::from(2), Fr::from(5)]; let res = noirfcircuit.step_native(0, inputs.clone(), inputs); assert!(res.is_ok()); - assert_eq!(res.unwrap(), vec![Fr::from(4), Fr::from(25)]); + assert_eq!(res?, vec![Fr::from(4), Fr::from(25)]); + Ok(()) } #[test] - fn test_step_constraints() { + fn test_step_constraints() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); - let cur_path = env::current_dir().unwrap(); + let cur_path = env::current_dir()?; let noirfcircuit = NoirFCircuit::new(( cur_path .join("src/noir/test_folder/test_circuit/target/test_circuit.json") .into(), 2, 2, - )) - .unwrap(); + ))?; let inputs = vec![Fr::from(2), Fr::from(5)]; - let z_i = Vec::>::new_witness(cs.clone(), || Ok(inputs.clone())).unwrap(); - let external_inputs = Vec::>::new_witness(cs.clone(), || Ok(inputs)).unwrap(); - let output = noirfcircuit - .generate_step_constraints(cs.clone(), 0, z_i, external_inputs) - .unwrap(); - assert_eq!(output[0].value().unwrap(), Fr::from(4)); - assert_eq!(output[1].value().unwrap(), Fr::from(25)); + let z_i = Vec::>::new_witness(cs.clone(), || Ok(inputs.clone()))?; + let external_inputs = Vec::>::new_witness(cs.clone(), || Ok(inputs))?; + let output = noirfcircuit.generate_step_constraints(cs.clone(), 0, z_i, external_inputs)?; + assert_eq!(output[0].value()?, Fr::from(4)); + assert_eq!(output[1].value()?, Fr::from(25)); + Ok(()) } #[test] - fn test_step_constraints_no_external_inputs() { + fn test_step_constraints_no_external_inputs() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); - let cur_path = env::current_dir().unwrap(); + let cur_path = env::current_dir()?; let noirfcircuit = NoirFCircuit::new(( cur_path .join("src/noir/test_folder/test_no_external_inputs/target/test_no_external_inputs.json") @@ -291,14 +289,13 @@ mod tests { 2, 0, )) - .unwrap(); + ?; let inputs = vec![Fr::from(2), Fr::from(5)]; - let z_i = Vec::>::new_witness(cs.clone(), || Ok(inputs.clone())).unwrap(); + let z_i = Vec::>::new_witness(cs.clone(), || Ok(inputs.clone()))?; let external_inputs = vec![]; - let output = noirfcircuit - .generate_step_constraints(cs.clone(), 0, z_i, external_inputs) - .unwrap(); - assert_eq!(output[0].value().unwrap(), Fr::from(4)); - assert_eq!(output[1].value().unwrap(), Fr::from(25)); + let output = noirfcircuit.generate_step_constraints(cs.clone(), 0, z_i, external_inputs)?; + assert_eq!(output[0].value()?, Fr::from(4)); + assert_eq!(output[1].value()?, Fr::from(25)); + Ok(()) } } diff --git a/frontends/src/noir/test_folder/compile.sh b/experimental-frontends/src/noir/test_folder/compile.sh similarity index 100% rename from frontends/src/noir/test_folder/compile.sh rename to experimental-frontends/src/noir/test_folder/compile.sh diff --git a/frontends/src/noir/test_folder/test_circuit/Nargo.toml b/experimental-frontends/src/noir/test_folder/test_circuit/Nargo.toml similarity index 100% rename from frontends/src/noir/test_folder/test_circuit/Nargo.toml rename to experimental-frontends/src/noir/test_folder/test_circuit/Nargo.toml diff --git a/frontends/src/noir/test_folder/test_circuit/src/main.nr b/experimental-frontends/src/noir/test_folder/test_circuit/src/main.nr similarity index 100% rename from frontends/src/noir/test_folder/test_circuit/src/main.nr rename to experimental-frontends/src/noir/test_folder/test_circuit/src/main.nr diff --git a/frontends/src/noir/test_folder/test_mimc/Nargo.toml b/experimental-frontends/src/noir/test_folder/test_mimc/Nargo.toml similarity index 100% rename from frontends/src/noir/test_folder/test_mimc/Nargo.toml rename to experimental-frontends/src/noir/test_folder/test_mimc/Nargo.toml diff --git a/frontends/src/noir/test_folder/test_mimc/src/main.nr b/experimental-frontends/src/noir/test_folder/test_mimc/src/main.nr similarity index 100% rename from frontends/src/noir/test_folder/test_mimc/src/main.nr rename to experimental-frontends/src/noir/test_folder/test_mimc/src/main.nr diff --git a/frontends/src/noir/test_folder/test_no_external_inputs/Nargo.toml b/experimental-frontends/src/noir/test_folder/test_no_external_inputs/Nargo.toml similarity index 100% rename from frontends/src/noir/test_folder/test_no_external_inputs/Nargo.toml rename to experimental-frontends/src/noir/test_folder/test_no_external_inputs/Nargo.toml diff --git a/frontends/src/noir/test_folder/test_no_external_inputs/src/main.nr b/experimental-frontends/src/noir/test_folder/test_no_external_inputs/src/main.nr similarity index 100% rename from frontends/src/noir/test_folder/test_no_external_inputs/src/main.nr rename to experimental-frontends/src/noir/test_folder/test_no_external_inputs/src/main.nr diff --git a/frontends/src/noname/bridge.rs b/experimental-frontends/src/noname/bridge.rs similarity index 100% rename from frontends/src/noname/bridge.rs rename to experimental-frontends/src/noname/bridge.rs diff --git a/frontends/src/noname/mod.rs b/experimental-frontends/src/noname/mod.rs similarity index 80% rename from frontends/src/noname/mod.rs rename to experimental-frontends/src/noname/mod.rs index 2e34a6d7..c48acb3f 100644 --- a/frontends/src/noname/mod.rs +++ b/experimental-frontends/src/noname/mod.rs @@ -120,7 +120,7 @@ mod tests { use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar}; use noname::backends::r1cs::R1csBn254Field; - use folding_schemes::frontend::FCircuit; + use folding_schemes::{frontend::FCircuit, Error}; use super::NonameFCircuit; use ark_relations::r1cs::ConstraintSystem; @@ -140,63 +140,65 @@ mod tests { }"; #[test] - fn test_step_native() { + fn test_step_native() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let params = (NONAME_CIRCUIT_EXTERNAL_INPUTS.to_owned(), 2, 2); - let circuit = NonameFCircuit::::new(params).unwrap(); + let circuit = NonameFCircuit::::new(params)?; let inputs_public = vec![Fr::from(2), Fr::from(5)]; let inputs_private = vec![Fr::from(8), Fr::from(2)]; let ivc_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(inputs_public.clone())).unwrap(); + Vec::>::new_witness(cs.clone(), || Ok(inputs_public.clone()))?; let external_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(inputs_private.clone())).unwrap(); - - let z_i1 = circuit - .generate_step_constraints(cs.clone(), 0, ivc_inputs_var, external_inputs_var) - .unwrap(); - let z_i1_native = circuit - .step_native(0, inputs_public, inputs_private) - .unwrap(); - - assert_eq!(z_i1[0].value().unwrap(), z_i1_native[0]); - assert_eq!(z_i1[1].value().unwrap(), z_i1_native[1]); + Vec::>::new_witness(cs.clone(), || Ok(inputs_private.clone()))?; + + let z_i1 = circuit.generate_step_constraints( + cs.clone(), + 0, + ivc_inputs_var, + external_inputs_var, + )?; + let z_i1_native = circuit.step_native(0, inputs_public, inputs_private)?; + + assert_eq!(z_i1[0].value()?, z_i1_native[0]); + assert_eq!(z_i1[1].value()?, z_i1_native[1]); + Ok(()) } #[test] - fn test_step_constraints() { + fn test_step_constraints() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let params = (NONAME_CIRCUIT_EXTERNAL_INPUTS.to_owned(), 2, 2); - let circuit = NonameFCircuit::::new(params).unwrap(); + let circuit = NonameFCircuit::::new(params)?; let inputs_public = vec![Fr::from(2), Fr::from(5)]; let inputs_private = vec![Fr::from(8), Fr::from(2)]; - let ivc_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(inputs_public)).unwrap(); - let external_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(inputs_private)).unwrap(); - - let z_i1 = circuit - .generate_step_constraints(cs.clone(), 0, ivc_inputs_var, external_inputs_var) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); - assert_eq!(z_i1[0].value().unwrap(), Fr::from(10_u8)); - assert_eq!(z_i1[1].value().unwrap(), Fr::from(10_u8)); + let ivc_inputs_var = Vec::>::new_witness(cs.clone(), || Ok(inputs_public))?; + let external_inputs_var = Vec::>::new_witness(cs.clone(), || Ok(inputs_private))?; + + let z_i1 = circuit.generate_step_constraints( + cs.clone(), + 0, + ivc_inputs_var, + external_inputs_var, + )?; + assert!(cs.is_satisfied()?); + assert_eq!(z_i1[0].value()?, Fr::from(10_u8)); + assert_eq!(z_i1[1].value()?, Fr::from(10_u8)); + Ok(()) } #[test] - fn test_generate_constraints_no_external_inputs() { + fn test_generate_constraints_no_external_inputs() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let params = (NONAME_CIRCUIT_NO_EXTERNAL_INPUTS.to_owned(), 2, 0); let inputs_public = vec![Fr::from(2), Fr::from(5)]; - let ivc_inputs_var = - Vec::>::new_witness(cs.clone(), || Ok(inputs_public)).unwrap(); + let ivc_inputs_var = Vec::>::new_witness(cs.clone(), || Ok(inputs_public))?; - let f_circuit = NonameFCircuit::::new(params).unwrap(); - f_circuit - .generate_step_constraints(cs.clone(), 0, ivc_inputs_var, vec![]) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + let f_circuit = NonameFCircuit::::new(params)?; + f_circuit.generate_step_constraints(cs.clone(), 0, ivc_inputs_var, vec![])?; + assert!(cs.is_satisfied()?); + Ok(()) } } diff --git a/frontends/src/noname/utils.rs b/experimental-frontends/src/noname/utils.rs similarity index 100% rename from frontends/src/noname/utils.rs rename to experimental-frontends/src/noname/utils.rs diff --git a/folding-schemes/src/arith/ccs/mod.rs b/folding-schemes/src/arith/ccs/mod.rs index eba51c4a..666ef9e2 100644 --- a/folding-schemes/src/arith/ccs/mod.rs +++ b/folding-schemes/src/arith/ccs/mod.rs @@ -135,24 +135,26 @@ pub mod tests { } #[test] - fn test_eval_ccs_relation() { + fn test_eval_ccs_relation() -> Result<(), Error> { let ccs = get_test_ccs::(); let (_, x, mut w) = get_test_z_split(3); - let f_w = ccs.eval_relation(&w, &x).unwrap(); + let f_w = ccs.eval_relation(&w, &x)?; assert!(is_zero_vec(&f_w)); w[1] = Fr::from(111); - let f_w = ccs.eval_relation(&w, &x).unwrap(); + let f_w = ccs.eval_relation(&w, &x)?; assert!(!is_zero_vec(&f_w)); + Ok(()) } /// Test that a basic CCS relation can be satisfied #[test] - fn test_check_ccs_relation() { + fn test_check_ccs_relation() -> Result<(), Error> { let ccs = get_test_ccs::(); let (_, x, w) = get_test_z_split(3); - ccs.check_relation(&w, &x).unwrap(); + ccs.check_relation(&w, &x)?; + Ok(()) } } diff --git a/folding-schemes/src/arith/r1cs/circuits.rs b/folding-schemes/src/arith/r1cs/circuits.rs index 0e0d7763..bacd79b4 100644 --- a/folding-schemes/src/arith/r1cs/circuits.rs +++ b/folding-schemes/src/arith/r1cs/circuits.rs @@ -129,89 +129,90 @@ pub mod tests { utils::{CubicFCircuit, CustomFCircuit, WrapperCircuit}, FCircuit, }; + use crate::Error; fn prepare_instances, R: Rng>( mut rng: R, r1cs: &R1CS, z: &[C::ScalarField], - ) -> (Witness, CommittedInstance) { + ) -> Result<(Witness, CommittedInstance), Error> { let (w, x) = r1cs.split_z(z); - let (cs_pp, _) = CS::setup(&mut rng, max(w.len(), r1cs.A.n_rows)).unwrap(); + let (cs_pp, _) = CS::setup(&mut rng, max(w.len(), r1cs.A.n_rows))?; let mut w = Witness::new::(w, r1cs.A.n_rows, &mut rng); - w.E = r1cs.eval_at_z(z).unwrap(); - let mut u = w.commit::(&cs_pp, x).unwrap(); + w.E = r1cs.eval_at_z(z)?; + let mut u = w.commit::(&cs_pp, x)?; u.u = z[0]; - (w, u) + Ok((w, u)) } #[test] - fn test_relaxed_r1cs_small_gadget_handcrafted() { + fn test_relaxed_r1cs_small_gadget_handcrafted() -> Result<(), Error> { let rng = &mut thread_rng(); let r1cs: R1CS = get_test_r1cs(); let mut z = get_test_z(3); z[0] = Fr::rand(rng); - let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z); + let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z)?; let cs = ConstraintSystem::::new_ref(); - let wVar = WitnessVar::new_witness(cs.clone(), || Ok(w)).unwrap(); - let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(u)).unwrap(); - let r1csVar = - R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs)).unwrap(); + let wVar = WitnessVar::new_witness(cs.clone(), || Ok(w))?; + let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(u))?; + let r1csVar = R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs))?; - r1csVar.enforce_relation(&wVar, &uVar).unwrap(); - assert!(cs.is_satisfied().unwrap()); + r1csVar.enforce_relation(&wVar, &uVar)?; + assert!(cs.is_satisfied()?); + Ok(()) } // gets as input a circuit that implements the ConstraintSynthesizer trait, and that has been // initialized. - fn test_relaxed_r1cs_gadget>(circuit: CS) { + fn test_relaxed_r1cs_gadget>(circuit: CS) -> Result<(), Error> { let rng = &mut thread_rng(); let cs = ConstraintSystem::::new_ref(); - circuit.generate_constraints(cs.clone()).unwrap(); + circuit.generate_constraints(cs.clone())?; cs.finalize(); - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); - let cs = cs.into_inner().unwrap(); + let cs = cs.into_inner().ok_or(Error::NoInnerConstraintSystem)?; - let r1cs = extract_r1cs::(&cs).unwrap(); + let r1cs = extract_r1cs::(&cs)?; let (w, x) = extract_w_x::(&cs); - r1cs.check_relation(&w, &x).unwrap(); + r1cs.check_relation(&w, &x)?; let mut z = [vec![Fr::one()], x, w].concat(); z[0] = Fr::rand(rng); - let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z); - r1cs.check_relation(&w, &u).unwrap(); + let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z)?; + r1cs.check_relation(&w, &u)?; // set new CS for the circuit that checks the RelaxedR1CS of our original circuit let cs = ConstraintSystem::::new_ref(); // prepare the inputs for our circuit - let wVar = WitnessVar::new_witness(cs.clone(), || Ok(w)).unwrap(); - let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(u)).unwrap(); - let r1csVar = - R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs)).unwrap(); + let wVar = WitnessVar::new_witness(cs.clone(), || Ok(w))?; + let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(u))?; + let r1csVar = R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs))?; - r1csVar.enforce_relation(&wVar, &uVar).unwrap(); - assert!(cs.is_satisfied().unwrap()); + r1csVar.enforce_relation(&wVar, &uVar)?; + assert!(cs.is_satisfied()?); + Ok(()) } #[test] - fn test_relaxed_r1cs_small_gadget_arkworks() { + fn test_relaxed_r1cs_small_gadget_arkworks() -> Result<(), Error> { let z_i = vec![Fr::from(3_u32)]; - let cubic_circuit = CubicFCircuit::::new(()).unwrap(); + let cubic_circuit = CubicFCircuit::::new(())?; let circuit = WrapperCircuit::> { FC: cubic_circuit, z_i: Some(z_i.clone()), - z_i1: Some(cubic_circuit.step_native(0, z_i, vec![]).unwrap()), + z_i1: Some(cubic_circuit.step_native(0, z_i, vec![])?), }; - test_relaxed_r1cs_gadget(circuit); + test_relaxed_r1cs_gadget(circuit) } struct Sha256TestCircuit { @@ -231,7 +232,7 @@ pub mod tests { } } #[test] - fn test_relaxed_r1cs_medium_gadget_arkworks() { + fn test_relaxed_r1cs_medium_gadget_arkworks() -> Result<(), Error> { let x = Fr::from(5_u32).into_bigint().to_bytes_le(); let y = ::evaluate(&(), x.clone()).unwrap(); @@ -240,62 +241,60 @@ pub mod tests { x, y, }; - test_relaxed_r1cs_gadget(circuit); + test_relaxed_r1cs_gadget(circuit) } #[test] - fn test_relaxed_r1cs_custom_circuit() { + fn test_relaxed_r1cs_custom_circuit() -> Result<(), Error> { let n_constraints = 10_000; - let custom_circuit = CustomFCircuit::::new(n_constraints).unwrap(); + let custom_circuit = CustomFCircuit::::new(n_constraints)?; let z_i = vec![Fr::from(5_u32)]; let circuit = WrapperCircuit::> { FC: custom_circuit, z_i: Some(z_i.clone()), - z_i1: Some(custom_circuit.step_native(0, z_i, vec![]).unwrap()), + z_i1: Some(custom_circuit.step_native(0, z_i, vec![])?), }; - test_relaxed_r1cs_gadget(circuit); + test_relaxed_r1cs_gadget(circuit) } #[test] - fn test_relaxed_r1cs_nonnative_circuit() { + fn test_relaxed_r1cs_nonnative_circuit() -> Result<(), Error> { let rng = &mut thread_rng(); let cs = ConstraintSystem::::new_ref(); // in practice we would use CycleFoldCircuit, but is a very big circuit (when computed // non-natively inside the RelaxedR1CS circuit), so in order to have a short test we use a // custom circuit. - let custom_circuit = CustomFCircuit::::new(10).unwrap(); + let custom_circuit = CustomFCircuit::::new(10)?; let z_i = vec![Fq::from(5_u32)]; let circuit = WrapperCircuit::> { FC: custom_circuit, z_i: Some(z_i.clone()), - z_i1: Some(custom_circuit.step_native(0, z_i, vec![]).unwrap()), + z_i1: Some(custom_circuit.step_native(0, z_i, vec![])?), }; - circuit.generate_constraints(cs.clone()).unwrap(); + circuit.generate_constraints(cs.clone())?; cs.finalize(); - let cs = cs.into_inner().unwrap(); - let r1cs = extract_r1cs::(&cs).unwrap(); + let cs = cs.into_inner().ok_or(Error::NoInnerConstraintSystem)?; + let r1cs = extract_r1cs::(&cs)?; let (w, x) = extract_w_x::(&cs); let z = [vec![Fq::rand(rng)], x, w].concat(); - let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z); + let (w, u) = prepare_instances::<_, Pedersen, _>(rng, &r1cs, &z)?; // natively let cs = ConstraintSystem::::new_ref(); - let wVar = WitnessVar::new_witness(cs.clone(), || Ok(&w)).unwrap(); - let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(&u)).unwrap(); - let r1csVar = - R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(&r1cs)).unwrap(); - r1csVar.enforce_relation(&wVar, &uVar).unwrap(); + let wVar = WitnessVar::new_witness(cs.clone(), || Ok(&w))?; + let uVar = CommittedInstanceVar::new_witness(cs.clone(), || Ok(&u))?; + let r1csVar = R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(&r1cs))?; + r1csVar.enforce_relation(&wVar, &uVar)?; // non-natively let cs = ConstraintSystem::::new_ref(); - let wVar = CycleFoldWitnessVar::new_witness(cs.clone(), || Ok(w)).unwrap(); - let uVar = - CycleFoldCommittedInstanceVar::<_, GVar2>::new_witness(cs.clone(), || Ok(u)).unwrap(); + let wVar = CycleFoldWitnessVar::new_witness(cs.clone(), || Ok(w))?; + let uVar = CycleFoldCommittedInstanceVar::<_, GVar2>::new_witness(cs.clone(), || Ok(u))?; let r1csVar = - R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs)) - .unwrap(); - r1csVar.enforce_relation(&wVar, &uVar).unwrap(); + R1CSMatricesVar::>::new_witness(cs.clone(), || Ok(r1cs))?; + r1csVar.enforce_relation(&wVar, &uVar)?; + Ok(()) } } diff --git a/folding-schemes/src/arith/r1cs/mod.rs b/folding-schemes/src/arith/r1cs/mod.rs index 362567de..683d0888 100644 --- a/folding-schemes/src/arith/r1cs/mod.rs +++ b/folding-schemes/src/arith/r1cs/mod.rs @@ -232,23 +232,25 @@ pub mod tests { } #[test] - fn test_eval_r1cs_relation() { + fn test_eval_r1cs_relation() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let r1cs = get_test_r1cs::(); let (_, x, mut w) = get_test_z_split::(rng.gen::() as usize); - let f_w = r1cs.eval_relation(&w, &x).unwrap(); + let f_w = r1cs.eval_relation(&w, &x)?; assert!(is_zero_vec(&f_w)); w[1] = Fr::from(111); - let f_w = r1cs.eval_relation(&w, &x).unwrap(); + let f_w = r1cs.eval_relation(&w, &x)?; assert!(!is_zero_vec(&f_w)); + Ok(()) } #[test] - fn test_check_r1cs_relation() { + fn test_check_r1cs_relation() -> Result<(), Error> { let r1cs = get_test_r1cs::(); let (_, x, w) = get_test_z_split(5); - r1cs.check_relation(&w, &x).unwrap(); + r1cs.check_relation(&w, &x)?; + Ok(()) } } diff --git a/folding-schemes/src/commitment/ipa.rs b/folding-schemes/src/commitment/ipa.rs index c7c52b54..743a6d1f 100644 --- a/folding-schemes/src/commitment/ipa.rs +++ b/folding-schemes/src/commitment/ipa.rs @@ -573,18 +573,19 @@ mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_ipa() { - test_ipa_opt::(); - test_ipa_opt::(); + fn test_ipa() -> Result<(), Error> { + let _ = test_ipa_opt::()?; + let _ = test_ipa_opt::()?; + Ok(()) } - fn test_ipa_opt() { + fn test_ipa_opt() -> Result<(), Error> { let mut rng = ark_std::test_rng(); const k: usize = 4; const d: usize = 2_u64.pow(k as u32) as usize; // setup params - let (params, _) = IPA::::setup(&mut rng, d).unwrap(); + let (params, _) = IPA::::setup(&mut rng, d)?; let poseidon_config = poseidon_canonical_config::(); // init Prover's transcript @@ -601,7 +602,7 @@ mod tests { } else { Fr::zero() }; - let cm = IPA::::commit(¶ms, &a, &r_blind).unwrap(); + let cm = IPA::::commit(¶ms, &a, &r_blind)?; let proof = IPA::::prove( ¶ms, @@ -610,25 +611,26 @@ mod tests { &a, &r_blind, Some(&mut rng), - ) - .unwrap(); + )?; - IPA::::verify(¶ms, &mut transcript_v, &cm, &proof).unwrap(); + IPA::::verify(¶ms, &mut transcript_v, &cm, &proof)?; + Ok(()) } #[test] - fn test_ipa_gadget() { - test_ipa_gadget_opt::(); - test_ipa_gadget_opt::(); + fn test_ipa_gadget() -> Result<(), Error> { + let _ = test_ipa_gadget_opt::()?; + let _ = test_ipa_gadget_opt::()?; + Ok(()) } - fn test_ipa_gadget_opt() { + fn test_ipa_gadget_opt() -> Result<(), Error> { let mut rng = ark_std::test_rng(); const k: usize = 3; const d: usize = 2_u64.pow(k as u32) as usize; // setup params - let (params, _) = IPA::::setup(&mut rng, d).unwrap(); + let (params, _) = IPA::::setup(&mut rng, d)?; let poseidon_config = poseidon_canonical_config::(); // init Prover's transcript @@ -645,7 +647,7 @@ mod tests { } else { Fr::zero() }; - let cm = IPA::::commit(¶ms, &a, &r_blind).unwrap(); + let cm = IPA::::commit(¶ms, &a, &r_blind)?; let proof = IPA::::prove( ¶ms, @@ -654,10 +656,9 @@ mod tests { &a, &r_blind, Some(&mut rng), - ) - .unwrap(); + )?; - IPA::::verify(¶ms, &mut transcript_v, &cm, &proof).unwrap(); + IPA::::verify(¶ms, &mut transcript_v, &cm, &proof)?; // circuit let cs = ConstraintSystem::::new_ref(); @@ -675,18 +676,16 @@ mod tests { } // prepare inputs - let gVar = Vec::::new_constant(cs.clone(), params.generators).unwrap(); - let hVar = GVar::new_constant(cs.clone(), params.h).unwrap(); - let challengeVar = - EmulatedFpVar::::new_witness(cs.clone(), || Ok(challenge)).unwrap(); - let vVar = EmulatedFpVar::::new_witness(cs.clone(), || Ok(proof.1)).unwrap(); - let cmVar = GVar::new_witness(cs.clone(), || Ok(cm)).unwrap(); - let proofVar = - ProofVar::::new_witness(cs.clone(), || Ok(proof.0)).unwrap(); - let r_blindVar = EmulatedFpVar::::new_witness(cs.clone(), || Ok(r_blind)).unwrap(); - let uVar_vec = Vec::>::new_witness(cs.clone(), || Ok(u)).unwrap(); + let gVar = Vec::::new_constant(cs.clone(), params.generators)?; + let hVar = GVar::new_constant(cs.clone(), params.h)?; + let challengeVar = EmulatedFpVar::::new_witness(cs.clone(), || Ok(challenge))?; + let vVar = EmulatedFpVar::::new_witness(cs.clone(), || Ok(proof.1))?; + let cmVar = GVar::new_witness(cs.clone(), || Ok(cm))?; + let proofVar = ProofVar::::new_witness(cs.clone(), || Ok(proof.0))?; + let r_blindVar = EmulatedFpVar::::new_witness(cs.clone(), || Ok(r_blind))?; + let uVar_vec = Vec::>::new_witness(cs.clone(), || Ok(u))?; let uVar: [EmulatedFpVar; k] = uVar_vec.try_into().unwrap(); - let UVar = GVar::new_witness(cs.clone(), || Ok(U)).unwrap(); + let UVar = GVar::new_witness(cs.clone(), || Ok(U))?; let v = IPAGadget::::verify::( &gVar, @@ -698,9 +697,9 @@ mod tests { &r_blindVar, &uVar, &UVar, - ) - .unwrap(); - v.enforce_equal(&Boolean::TRUE).unwrap(); - assert!(cs.is_satisfied().unwrap()); + )?; + v.enforce_equal(&Boolean::TRUE)?; + assert!(cs.is_satisfied()?); + Ok(()) } } diff --git a/folding-schemes/src/commitment/kzg.rs b/folding-schemes/src/commitment/kzg.rs index 5bfce046..84bde282 100644 --- a/folding-schemes/src/commitment/kzg.rs +++ b/folding-schemes/src/commitment/kzg.rs @@ -293,22 +293,22 @@ mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_kzg_commitment_scheme() { + fn test_kzg_commitment_scheme() -> Result<(), Error> { let mut rng = &mut test_rng(); let poseidon_config = poseidon_canonical_config::(); let transcript_p = &mut PoseidonSponge::::new(&poseidon_config); let transcript_v = &mut PoseidonSponge::::new(&poseidon_config); let n = 10; - let (pk, vk): (ProverKey, VerifierKey) = - KZG::::setup(&mut rng, n).unwrap(); + let (pk, vk): (ProverKey, VerifierKey) = KZG::::setup(&mut rng, n)?; let v: Vec = std::iter::repeat_with(|| Fr::rand(rng)).take(n).collect(); - let cm = KZG::::commit(&pk, &v, &Fr::zero()).unwrap(); + let cm = KZG::::commit(&pk, &v, &Fr::zero())?; - let proof = KZG::::prove(&pk, transcript_p, &cm, &v, &Fr::zero(), None).unwrap(); + let proof = KZG::::prove(&pk, transcript_p, &cm, &v, &Fr::zero(), None)?; // verify the proof: - KZG::::verify(&vk, transcript_v, &cm, &proof).unwrap(); + KZG::::verify(&vk, transcript_v, &cm, &proof)?; + Ok(()) } } diff --git a/folding-schemes/src/commitment/mod.rs b/folding-schemes/src/commitment/mod.rs index 0ee52ba6..a6de1f7d 100644 --- a/folding-schemes/src/commitment/mod.rs +++ b/folding-schemes/src/commitment/mod.rs @@ -86,7 +86,7 @@ mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_homomorphic_property_using_Commitment_trait() { + fn test_homomorphic_property_using_Commitment_trait() -> Result<(), Error> { let mut rng = &mut test_rng(); let poseidon_config = poseidon_canonical_config::(); let n: usize = 128; @@ -98,37 +98,37 @@ mod tests { let r = Fr::rand(rng); // setup params for Pedersen & KZG - let (pedersen_params, _) = Pedersen::::setup(&mut rng, n).unwrap(); - let (kzg_pk, kzg_vk): (ProverKey, VerifierKey) = - KZG::::setup(rng, n).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, n)?; + let (kzg_pk, kzg_vk): (ProverKey, VerifierKey) = KZG::::setup(rng, n)?; // test with Pedersen - test_homomorphic_property_using_Commitment_trait_opt::>( + let _ = test_homomorphic_property_using_Commitment_trait_opt::>( &poseidon_config, &pedersen_params, &pedersen_params, r, &v_1, &v_2, - ); + )?; // test with IPA - test_homomorphic_property_using_Commitment_trait_opt::>( + let _ = test_homomorphic_property_using_Commitment_trait_opt::>( &poseidon_config, &pedersen_params, &pedersen_params, r, &v_1, &v_2, - ); + )?; // test with KZG - test_homomorphic_property_using_Commitment_trait_opt::>( + let _ = test_homomorphic_property_using_Commitment_trait_opt::>( &poseidon_config, &kzg_pk, &kzg_vk, r, &v_1, &v_2, - ); + )?; + Ok(()) } fn test_homomorphic_property_using_Commitment_trait_opt< @@ -141,12 +141,13 @@ mod tests { r: C::ScalarField, v_1: &[C::ScalarField], v_2: &[C::ScalarField], - ) where + ) -> Result<(), Error> + where C::ScalarField: Absorb, { // compute the commitment of the two vectors using the given CommitmentScheme - let cm_1 = CS::commit(prover_params, v_1, &C::ScalarField::zero()).unwrap(); - let cm_2 = CS::commit(prover_params, v_2, &C::ScalarField::zero()).unwrap(); + let cm_1 = CS::commit(prover_params, v_1, &C::ScalarField::zero())?; + let cm_2 = CS::commit(prover_params, v_2, &C::ScalarField::zero())?; // random linear combination of the commitments and their witnesses (vectors v_i) let cm_3 = cm_1 + cm_2.mul(r); @@ -161,11 +162,11 @@ mod tests { &v_3, &C::ScalarField::zero(), None, - ) - .unwrap(); + )?; // verify the opening proof let transcript_v = &mut PoseidonSponge::::new(poseidon_config); - CS::verify(verifier_params, transcript_v, &cm_3, &proof).unwrap(); + CS::verify(verifier_params, transcript_v, &cm_3, &proof)?; + Ok(()) } } diff --git a/folding-schemes/src/commitment/pedersen.rs b/folding-schemes/src/commitment/pedersen.rs index 35aa1ae6..7ad1674b 100644 --- a/folding-schemes/src/commitment/pedersen.rs +++ b/folding-schemes/src/commitment/pedersen.rs @@ -219,16 +219,17 @@ mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_pedersen() { - test_pedersen_opt::(); - test_pedersen_opt::(); + fn test_pedersen() -> Result<(), Error> { + let _ = test_pedersen_opt::()?; + let _ = test_pedersen_opt::()?; + Ok(()) } - fn test_pedersen_opt() { + fn test_pedersen_opt() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let n: usize = 10; // setup params - let (params, _) = Pedersen::::setup(&mut rng, n).unwrap(); + let (params, _) = Pedersen::::setup(&mut rng, n)?; let poseidon_config = poseidon_canonical_config::(); // init Prover's transcript @@ -245,24 +246,25 @@ mod tests { } else { Fr::zero() }; - let cm = Pedersen::::commit(¶ms, &v, &r).unwrap(); + let cm = Pedersen::::commit(¶ms, &v, &r)?; let proof = - Pedersen::::prove(¶ms, &mut transcript_p, &cm, &v, &r, None) - .unwrap(); - Pedersen::::verify(¶ms, &mut transcript_v, &cm, &proof).unwrap(); + Pedersen::::prove(¶ms, &mut transcript_p, &cm, &v, &r, None)?; + Pedersen::::verify(¶ms, &mut transcript_v, &cm, &proof)?; + Ok(()) } #[test] - fn test_pedersen_circuit() { - test_pedersen_circuit_opt::(); - test_pedersen_circuit_opt::(); + fn test_pedersen_circuit() -> Result<(), Error> { + let _ = test_pedersen_circuit_opt::()?; + let _ = test_pedersen_circuit_opt::()?; + Ok(()) } - fn test_pedersen_circuit_opt() { + fn test_pedersen_circuit_opt() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let n: usize = 8; // setup params - let (params, _) = Pedersen::::setup(&mut rng, n).unwrap(); + let (params, _) = Pedersen::::setup(&mut rng, n)?; let v: Vec = std::iter::repeat_with(|| Fr::rand(&mut rng)) .take(n) @@ -273,7 +275,7 @@ mod tests { } else { Fr::zero() }; - let cm = Pedersen::::commit(¶ms, &v, &r).unwrap(); + let cm = Pedersen::::commit(¶ms, &v, &r)?; let v_bits: Vec> = v.iter().map(|val| val.into_bigint().to_bits_le()).collect(); let r_bits: Vec = r.into_bigint().to_bits_le(); @@ -288,14 +290,14 @@ mod tests { Vec::>::new_witness(cs.clone(), || Ok(val_bits.clone())).unwrap() }) .collect(); - let rVar = Vec::>::new_witness(cs.clone(), || Ok(r_bits)).unwrap(); - let gVar = Vec::::new_witness(cs.clone(), || Ok(params.generators)).unwrap(); - let hVar = GVar::new_witness(cs.clone(), || Ok(params.h)).unwrap(); - let expected_cmVar = GVar::new_witness(cs.clone(), || Ok(cm)).unwrap(); + let rVar = Vec::>::new_witness(cs.clone(), || Ok(r_bits))?; + let gVar = Vec::::new_witness(cs.clone(), || Ok(params.generators))?; + let hVar = GVar::new_witness(cs.clone(), || Ok(params.h))?; + let expected_cmVar = GVar::new_witness(cs.clone(), || Ok(cm))?; // use the gadget - let cmVar = - PedersenGadget::::commit(&hVar, &gVar, &vVar, &rVar).unwrap(); - cmVar.enforce_equal(&expected_cmVar).unwrap(); + let cmVar = PedersenGadget::::commit(&hVar, &gVar, &vVar, &rVar)?; + cmVar.enforce_equal(&expected_cmVar)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/circuits/cyclefold.rs b/folding-schemes/src/folding/circuits/cyclefold.rs index 49bb3349..555b8f6b 100644 --- a/folding-schemes/src/folding/circuits/cyclefold.rs +++ b/folding-schemes/src/folding/circuits/cyclefold.rs @@ -707,7 +707,7 @@ pub mod tests { } #[test] - fn test_committed_instance_cyclefold_var() { + fn test_committed_instance_cyclefold_var() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let ci = CycleFoldCommittedInstance:: { @@ -722,14 +722,14 @@ pub mod tests { let ciVar = CommittedInstanceInCycleFoldVar::::new_witness(cs.clone(), || { Ok(ci.clone()) - }) - .unwrap(); - assert_eq!(ciVar.cmE.value().unwrap(), ci.cmE); - assert_eq!(ciVar.cmW.value().unwrap(), ci.cmW); + })?; + assert_eq!(ciVar.cmE.value()?, ci.cmE); + assert_eq!(ciVar.cmW.value()?, ci.cmW); + Ok(()) } #[test] - fn test_CycleFoldCircuit_n_points_constraints() { + fn test_CycleFoldCircuit_n_points_constraints() -> Result<(), Error> { const n: usize = 16; let mut rng = ark_std::test_rng(); @@ -741,8 +741,10 @@ pub mod tests { use std::ops::Mul; let rho_raw = Fq::rand(&mut rng); let rho_bits = rho_raw.into_bigint().to_bits_le()[..NOVA_N_BITS_RO].to_vec(); - let rho_Fq = Fq::from_bigint(BigInteger::from_bits_le(&rho_bits)).unwrap(); - let rho_Fr = Fr::from_bigint(BigInteger::from_bits_le(&rho_bits)).unwrap(); + let rho_Fq = + Fq::from_bigint(BigInteger::from_bits_le(&rho_bits)).ok_or(Error::OutOfBounds)?; + let rho_Fr = + Fr::from_bigint(BigInteger::from_bits_le(&rho_bits)).ok_or(Error::OutOfBounds)?; let mut res = Projective::zero(); use ark_std::One; let mut rho_i = Fr::one(); @@ -767,12 +769,13 @@ pub mod tests { points: Some(points), x: Some(x.clone()), }; - cf_circuit.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + cf_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); + Ok(()) } #[test] - fn test_nifs_full_gadget() { + fn test_nifs_full_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); @@ -801,35 +804,31 @@ pub mod tests { &ci1, &ci2, &cmT, - ) - .unwrap(); + )?; let cs = ConstraintSystem::::new_ref(); - let r_bitsVar = Vec::>::new_witness(cs.clone(), || Ok(r_bits)).unwrap(); + let r_bitsVar = Vec::>::new_witness(cs.clone(), || Ok(r_bits))?; let ci1Var = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(ci1.clone()) - }) - .unwrap(); + })?; let ci2Var = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(ci2.clone()) - }) - .unwrap(); + })?; let ci3Var = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(ci3.clone()) - }) - .unwrap(); - let cmTVar = GVar::new_witness(cs.clone(), || Ok(cmT)).unwrap(); + })?; + let cmTVar = GVar::new_witness(cs.clone(), || Ok(cmT))?; - NIFSFullGadget::::verify(r_bitsVar, cmTVar, ci1Var, ci2Var, ci3Var) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + NIFSFullGadget::::verify(r_bitsVar, cmTVar, ci1Var, ci2Var, ci3Var)?; + assert!(cs.is_satisfied()?); + Ok(()) } #[test] - fn test_cyclefold_challenge_gadget() { + fn test_cyclefold_challenge_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); let mut transcript = PoseidonSponge::::new(&poseidon_config); @@ -866,37 +865,35 @@ pub mod tests { let u_iVar = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(u_i.clone()) - }) - .unwrap(); + })?; let U_iVar = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(U_i.clone()) - }) - .unwrap(); - let cmTVar = GVar::new_witness(cs.clone(), || Ok(cmT)).unwrap(); + })?; + let cmTVar = GVar::new_witness(cs.clone(), || Ok(cmT))?; let mut transcript_var = PoseidonSpongeVar::::new(ConstraintSystem::::new_ref(), &poseidon_config); - let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash)).unwrap(); + let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash))?; let r_bitsVar = CycleFoldChallengeGadget::::get_challenge_gadget( &mut transcript_var, pp_hashVar, - U_iVar.to_native_sponge_field_elements().unwrap(), + U_iVar.to_native_sponge_field_elements()?, u_iVar, cmTVar, - ) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + )?; + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - let rVar = Boolean::le_bits_to_fp(&r_bitsVar).unwrap(); - let r = Fq::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); - assert_eq!(rVar.value().unwrap(), r); - assert_eq!(r_bitsVar.value().unwrap(), r_bits); + let rVar = Boolean::le_bits_to_fp(&r_bitsVar)?; + let r = Fq::from_bigint(BigInteger::from_bits_le(&r_bits)).ok_or(Error::OutOfBounds)?; + assert_eq!(rVar.value()?, r); + assert_eq!(r_bitsVar.value()?, r_bits); + Ok(()) } #[test] - fn test_cyclefold_hash_gadget() { + fn test_cyclefold_hash_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); let sponge = PoseidonSponge::::new(&poseidon_config); @@ -916,17 +913,14 @@ pub mod tests { let U_iVar = CycleFoldCommittedInstanceVar::::new_witness(cs.clone(), || { Ok(U_i.clone()) - }) - .unwrap(); - let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash)).unwrap(); - let (hVar, _) = U_iVar - .hash( - &PoseidonSpongeVar::new(cs.clone(), &poseidon_config), - pp_hashVar, - ) - .unwrap(); - hVar.enforce_equal(&FpVar::new_witness(cs.clone(), || Ok(h)).unwrap()) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + })?; + let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash))?; + let (hVar, _) = U_iVar.hash( + &PoseidonSpongeVar::new(cs.clone(), &poseidon_config), + pp_hashVar, + )?; + hVar.enforce_equal(&FpVar::new_witness(cs.clone(), || Ok(h))?)?; + assert!(cs.is_satisfied()?); + Ok(()) } } diff --git a/folding-schemes/src/folding/circuits/decider/mod.rs b/folding-schemes/src/folding/circuits/decider/mod.rs index 9460742f..68b8657b 100644 --- a/folding-schemes/src/folding/circuits/decider/mod.rs +++ b/folding-schemes/src/folding/circuits/decider/mod.rs @@ -155,7 +155,7 @@ pub mod tests { // checks that the gadget and native implementations of the challenge computation match #[test] - fn test_kzg_challenge_gadget() { + fn test_kzg_challenge_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); let mut transcript = PoseidonSponge::::new(&poseidon_config); @@ -172,20 +172,20 @@ pub mod tests { let cs = ConstraintSystem::::new_ref(); let U_iVar = - CommittedInstanceVar::::new_witness(cs.clone(), || Ok(U_i.clone())) - .unwrap(); + CommittedInstanceVar::::new_witness(cs.clone(), || Ok(U_i.clone()))?; let mut transcript_var = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); let challenges_var = - KZGChallengesGadget::get_challenges_gadget(&mut transcript_var, &U_iVar).unwrap(); - assert!(cs.is_satisfied().unwrap()); + KZGChallengesGadget::get_challenges_gadget(&mut transcript_var, &U_iVar)?; + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(challenges_var.value().unwrap(), challenges); + assert_eq!(challenges_var.value()?, challenges); + Ok(()) } #[test] - fn test_polynomial_interpolation() { + fn test_polynomial_interpolation() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let n = 12; let l = 1 << n; @@ -196,16 +196,17 @@ pub mod tests { let challenge = Fr::rand(&mut rng); use ark_poly::Polynomial; - let polynomial = poly_from_vec(v.to_vec()).unwrap(); + let polynomial = poly_from_vec(v.to_vec())?; let eval = polynomial.evaluate(&challenge); let cs = ConstraintSystem::::new_ref(); - let vVar = Vec::>::new_witness(cs.clone(), || Ok(v)).unwrap(); - let challengeVar = FpVar::::new_witness(cs.clone(), || Ok(challenge)).unwrap(); + let vVar = Vec::>::new_witness(cs.clone(), || Ok(v))?; + let challengeVar = FpVar::::new_witness(cs.clone(), || Ok(challenge))?; - let evalVar = EvalGadget::evaluate_gadget(&vVar, &challengeVar).unwrap(); + let evalVar = EvalGadget::evaluate_gadget(&vVar, &challengeVar)?; - assert_eq!(evalVar.value().unwrap(), eval); - assert!(cs.is_satisfied().unwrap()); + assert_eq!(evalVar.value()?, eval); + assert!(cs.is_satisfied()?); + Ok(()) } } diff --git a/folding-schemes/src/folding/circuits/nonnative/affine.rs b/folding-schemes/src/folding/circuits/nonnative/affine.rs index 3f1c6a02..91392b30 100644 --- a/folding-schemes/src/folding/circuits/nonnative/affine.rs +++ b/folding-schemes/src/folding/circuits/nonnative/affine.rs @@ -201,11 +201,13 @@ impl AbsorbNonNativeGadget for NonNativeAffineVar #[cfg(test)] mod tests { - use super::*; use ark_pallas::{Fr, Projective}; use ark_relations::r1cs::ConstraintSystem; use ark_std::UniformRand; + use super::*; + use crate::Error; + #[test] fn test_alloc_zero() { let cs = ConstraintSystem::::new_ref(); @@ -216,33 +218,29 @@ mod tests { } #[test] - fn test_improved_to_constraint_field() { + fn test_improved_to_constraint_field() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); // check that point_to_nonnative_limbs returns the expected values let mut rng = ark_std::test_rng(); let p = Projective::rand(&mut rng); - let pVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(p)).unwrap(); + let pVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(p))?; let (x, y) = nonnative_affine_to_field_elements(p); - assert_eq!( - pVar.to_constraint_field().unwrap().value().unwrap(), - [x, y].concat() - ); + assert_eq!(pVar.to_constraint_field()?.value()?, [x, y].concat()); + Ok(()) } #[test] - fn test_inputize() { + fn test_inputize() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); // check that point_to_nonnative_limbs returns the expected values let mut rng = ark_std::test_rng(); let p = Projective::rand(&mut rng); - let pVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(p)).unwrap(); + let pVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(p))?; let xy = p.inputize(); - assert_eq!( - [pVar.x.0.value().unwrap(), pVar.y.0.value().unwrap()].concat(), - xy - ); + assert_eq!([pVar.x.0.value()?, pVar.y.0.value()?].concat(), xy); + Ok(()) } } diff --git a/folding-schemes/src/folding/circuits/nonnative/uint.rs b/folding-schemes/src/folding/circuits/nonnative/uint.rs index bc66d84c..d2193177 100644 --- a/folding-schemes/src/folding/circuits/nonnative/uint.rs +++ b/folding-schemes/src/folding/circuits/nonnative/uint.rs @@ -947,16 +947,16 @@ impl MatrixGadget> for SparseMatrixVar Result<(), Box> { + fn test_mul_biguint() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let size = 256; @@ -992,7 +992,7 @@ mod tests { } #[test] - fn test_mul_fq() -> Result<(), Box> { + fn test_mul_fq() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let rng = &mut test_rng(); @@ -1023,7 +1023,7 @@ mod tests { } #[test] - fn test_pow() -> Result<(), Box> { + fn test_pow() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let rng = &mut test_rng(); @@ -1043,7 +1043,7 @@ mod tests { } #[test] - fn test_vec_vec_mul() -> Result<(), Box> { + fn test_vec_vec_mul() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let len = 1000; diff --git a/folding-schemes/src/folding/circuits/sum_check.rs b/folding-schemes/src/folding/circuits/sum_check.rs index 75c7b43c..09a940b7 100644 --- a/folding-schemes/src/folding/circuits/sum_check.rs +++ b/folding-schemes/src/folding/circuits/sum_check.rs @@ -186,7 +186,7 @@ mod tests { use super::*; use crate::{ transcript::poseidon::poseidon_canonical_config, - utils::virtual_polynomial::VirtualPolynomial, + utils::virtual_polynomial::VirtualPolynomial, Error, }; pub type TestSumCheckProof = (VirtualPolynomial, PoseidonConfig, IOPProof); @@ -195,7 +195,7 @@ mod tests { /// Returns a random virtual polynomial, the poseidon config used and the associated sumcheck proof pub fn get_test_sumcheck_proof( num_vars: usize, - ) -> TestSumCheckProof { + ) -> Result, Error> { let mut rng = ark_std::test_rng(); let poseidon_config: PoseidonConfig = poseidon_canonical_config::(); let mut poseidon_transcript_prove = PoseidonSponge::::new(&poseidon_config); @@ -204,24 +204,22 @@ mod tests { let sum_check: IOPProof = IOPSumCheck::>::prove( &virtual_poly, &mut poseidon_transcript_prove, - ) - .unwrap(); - (virtual_poly, poseidon_config, sum_check) + )?; + Ok((virtual_poly, poseidon_config, sum_check)) } #[test] - fn test_sum_check_circuit() { + fn test_sum_check_circuit() -> Result<(), Error> { for num_vars in 1..15 { let cs = ConstraintSystem::::new_ref(); let (virtual_poly, poseidon_config, sum_check) = - get_test_sumcheck_proof::(num_vars); + get_test_sumcheck_proof::(num_vars)?; let mut poseidon_var: PoseidonSpongeVar = PoseidonSpongeVar::new(cs.clone(), &poseidon_config); - let iop_proof_var = - IOPProofVar::::new_witness(cs.clone(), || Ok(&sum_check)).unwrap(); + let iop_proof_var = IOPProofVar::::new_witness(cs.clone(), || Ok(&sum_check))?; let poly_aux_info_var = - VPAuxInfoVar::::new_witness(cs.clone(), || Ok(virtual_poly.aux_info)).unwrap(); - let enabled = Boolean::::new_witness(cs.clone(), || Ok(true)).unwrap(); + VPAuxInfoVar::::new_witness(cs.clone(), || Ok(virtual_poly.aux_info))?; + let enabled = Boolean::::new_witness(cs.clone(), || Ok(true))?; let res = SumCheckVerifierGadget::::verify( &iop_proof_var, &poly_aux_info_var, @@ -230,11 +228,11 @@ mod tests { ); assert!(res.is_ok()); - let (circuit_evals, r_challenges) = res.unwrap(); + let (circuit_evals, r_challenges) = res?; // 1. assert claim from circuit is equal to the one from the sum-check let claim: Fr = IOPSumCheck::>::extract_sum(&sum_check); - assert_eq!(circuit_evals[0].value().unwrap(), claim); + assert_eq!(circuit_evals[0].value()?, claim); // 2. assert that all in-circuit evaluations are equal to the ones from the sum-check for ((proof, point), circuit_eval) in sum_check @@ -246,15 +244,16 @@ mod tests { { let poly = DensePolynomial::from_coefficients_slice(&proof.coeffs); let eval = poly.evaluate(point); - assert_eq!(eval, circuit_eval.value().unwrap()); + assert_eq!(eval, circuit_eval.value()?); } // 3. assert that all challenges are equal to the ones from the sum-check for (point, r_challenge) in sum_check.point.iter().zip(r_challenges.iter()) { - assert_eq!(*point, r_challenge.value().unwrap()); + assert_eq!(*point, r_challenge.value()?); } - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); } + Ok(()) } } diff --git a/folding-schemes/src/folding/circuits/utils.rs b/folding-schemes/src/folding/circuits/utils.rs index 5035e2a2..f2924acd 100644 --- a/folding-schemes/src/folding/circuits/utils.rs +++ b/folding-schemes/src/folding/circuits/utils.rs @@ -38,9 +38,10 @@ mod tests { use super::EqEvalGadget; use crate::utils::virtual_polynomial::eq_eval; + use crate::Error; #[test] - pub fn test_eq_eval_gadget() { + pub fn test_eq_eval_gadget() -> Result<(), Error> { let mut rng = test_rng(); let cs = ConstraintSystem::::new_ref(); @@ -55,9 +56,9 @@ mod tests { .iter() .map(|y| FpVar::::new_witness(cs.clone(), || Ok(y)).unwrap()) .collect(); - let expected_eq_eval = eq_eval::(&x_vec, &y_vec).unwrap(); - let gadget_eq_eval: FpVar = EqEvalGadget::::eq_eval(&x, &y).unwrap(); - assert_eq!(expected_eq_eval, gadget_eq_eval.value().unwrap()); + let expected_eq_eval = eq_eval::(&x_vec, &y_vec)?; + let gadget_eq_eval: FpVar = EqEvalGadget::::eq_eval(&x, &y)?; + assert_eq!(expected_eq_eval, gadget_eq_eval.value()?); } let x: Vec> = vec![]; @@ -66,9 +67,9 @@ mod tests { assert!(gadget_eq_eval.is_err()); let x: Vec> = vec![]; - let y: Vec> = - vec![FpVar::::new_witness(cs.clone(), || Ok(&Fr::ONE)).unwrap()]; + let y: Vec> = vec![FpVar::::new_witness(cs.clone(), || Ok(&Fr::ONE))?]; let gadget_eq_eval = EqEvalGadget::::eq_eval(&x, &y); assert!(gadget_eq_eval.is_err()); + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/cccs.rs b/folding-schemes/src/folding/hypernova/cccs.rs index d797ee76..488ac9ff 100644 --- a/folding-schemes/src/folding/hypernova/cccs.rs +++ b/folding-schemes/src/folding/hypernova/cccs.rs @@ -172,38 +172,39 @@ pub mod tests { /// Do some sanity checks on q(x). It's a multivariable polynomial and it should evaluate to zero inside the /// hypercube, but to not-zero outside the hypercube. #[test] - fn test_compute_q() { + fn test_compute_q() -> Result<(), Error> { let mut rng = test_rng(); let ccs = get_test_ccs::(); let z = get_test_z(3); - let q = ccs.compute_q(&z).unwrap(); + let q = ccs.compute_q(&z)?; // Evaluate inside the hypercube for x in BooleanHypercube::new(ccs.s) { - assert_eq!(Fr::zero(), q.evaluate(&x).unwrap()); + assert_eq!(Fr::zero(), q.evaluate(&x)?); } // Evaluate outside the hypercube let beta: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); - assert_ne!(Fr::zero(), q.evaluate(&beta).unwrap()); + assert_ne!(Fr::zero(), q.evaluate(&beta)?); + Ok(()) } /// Perform some sanity checks on Q(x). #[test] - fn test_compute_Q() { + fn test_compute_Q() -> Result<(), Error> { let mut rng = test_rng(); let ccs: CCS = get_test_ccs(); let z = get_test_z(3); let (w, x) = ccs.split_z(&z); - ccs.check_relation(&w, &x).unwrap(); + ccs.check_relation(&w, &x)?; let beta: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); // Compute Q(x) = eq(beta, x) * q(x). - let Q = ccs.compute_Q(&z, &beta).unwrap(); + let Q = ccs.compute_Q(&z, &beta)?; // Let's consider the multilinear polynomial G(x) = \sum_{y \in {0, 1}^s} eq(x, y) q(y) // which interpolates the multivariate polynomial q(x) inside the hypercube. @@ -218,44 +219,53 @@ pub mod tests { // Now sum Q(x) evaluations in the hypercube and expect it to be 0 let r = BooleanHypercube::new(ccs.s) - .map(|x| Q.evaluate(&x).unwrap()) + .map(|x| Q.evaluate(&x)) + .collect::, _>>()? + .into_iter() .fold(Fr::zero(), |acc, result| acc + result); assert_eq!(r, Fr::zero()); + Ok(()) } /// The polynomial G(x) (see above) interpolates q(x) inside the hypercube. /// Summing Q(x) over the hypercube is equivalent to evaluating G(x) at some point. /// This test makes sure that G(x) agrees with q(x) inside the hypercube, but not outside #[test] - fn test_Q_against_q() { + fn test_Q_against_q() -> Result<(), Error> { let mut rng = test_rng(); let ccs: CCS = get_test_ccs(); let z = get_test_z(3); let (w, x) = ccs.split_z(&z); - ccs.check_relation(&w, &x).unwrap(); + ccs.check_relation(&w, &x)?; // Now test that if we create Q(x) with eq(d,y) where d is inside the hypercube, \sum Q(x) should be G(d) which // should be equal to q(d), since G(x) interpolates q(x) inside the hypercube - let q = ccs.compute_q(&z).unwrap(); + let q = ccs.compute_q(&z)?; for d in BooleanHypercube::new(ccs.s) { - let Q_at_d = ccs.compute_Q(&z, &d).unwrap(); + let Q_at_d = ccs.compute_Q(&z, &d)?; // Get G(d) by summing over Q_d(x) over the hypercube let G_at_d = BooleanHypercube::new(ccs.s) - .map(|x| Q_at_d.evaluate(&x).unwrap()) + .map(|x| Q_at_d.evaluate(&x)) + .collect::, _>>()? + .into_iter() .fold(Fr::zero(), |acc, result| acc + result); - assert_eq!(G_at_d, q.evaluate(&d).unwrap()); + assert_eq!(G_at_d, q.evaluate(&d)?); } // Now test that they should disagree outside of the hypercube let r: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); - let Q_at_r = ccs.compute_Q(&z, &r).unwrap(); + let Q_at_r = ccs.compute_Q(&z, &r)?; // Get G(d) by summing over Q_d(x) over the hypercube let G_at_r = BooleanHypercube::new(ccs.s) - .map(|x| Q_at_r.evaluate(&x).unwrap()) + .map(|x| Q_at_r.evaluate(&x)) + .collect::, _>>()? + .into_iter() .fold(Fr::zero(), |acc, result| acc + result); - assert_ne!(G_at_r, q.evaluate(&r).unwrap()); + + assert_ne!(G_at_r, q.evaluate(&r)?); + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/circuits.rs b/folding-schemes/src/folding/hypernova/circuits.rs index 63ea62bc..a52e2e8d 100644 --- a/folding-schemes/src/folding/hypernova/circuits.rs +++ b/folding-schemes/src/folding/hypernova/circuits.rs @@ -567,7 +567,7 @@ where ccs: Option>, ) -> Result { let initial_ccs = CCS { - // m, n, s, s_prime and M will be overwritten by the `upper_bound_ccs' method + // m, n, s, s_prime and M will be overwritten by the `compute_concrete_ccs' method m: 0, n: 0, l: 2, // io_len @@ -583,7 +583,7 @@ where let mut augmented_f_circuit = Self::default(poseidon_config, F, initial_ccs)?; augmented_f_circuit.ccs = ccs .ok_or(()) - .or_else(|_| augmented_f_circuit.upper_bound_ccs())?; + .or_else(|_| augmented_f_circuit.compute_concrete_ccs())?; Ok(augmented_f_circuit) } @@ -591,7 +591,7 @@ where /// dependency between the AugmentedFCircuit CCS and the CCS parameters m & n & s & s'. /// For a stable FCircuit circuit, the CCS parameters can be computed in advance and can be /// feed in as parameter for the AugmentedFCircuit::empty method to avoid computing them there. - pub fn upper_bound_ccs(&self) -> Result, Error> { + pub fn compute_concrete_ccs(&self) -> Result, Error> { let r1cs = get_r1cs_from_cs::>(self.clone())?; let mut ccs = CCS::from(r1cs); @@ -668,8 +668,6 @@ where U_i = LCCCS::::dummy(&ccs); } Ok(ccs) - - // Ok(augmented_f_circuit.compute_cs_ccs()?.1) } /// Returns the cs (ConstraintSystem) and the CCS out of the AugmentedFCircuit @@ -914,7 +912,7 @@ mod tests { }; #[test] - pub fn test_compute_c_gadget() { + pub fn test_compute_c_gadget() -> Result<(), Error> { // number of LCCCS & CCCS instances to fold in a single step let mu = 32; let nu = 42; @@ -937,27 +935,27 @@ mod tests { let beta: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); let r_x_prime: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; // Create the LCCCS instances out of z_lcccs let mut lcccs_instances = Vec::new(); for z_i in z_lcccs.iter() { - let (inst, _) = ccs - .to_lcccs::<_, _, Pedersen, true>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (inst, _) = ccs.to_lcccs::<_, _, Pedersen, true>( + &mut rng, + &pedersen_params, + z_i, + )?; lcccs_instances.push(inst); } // Create the CCCS instance out of z_cccs let mut cccs_instances = Vec::new(); for z_i in z_cccs.iter() { - let (inst, _) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (inst, _) = + ccs.to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i)?; cccs_instances.push(inst); } - let sigmas_thetas = compute_sigmas_thetas(&ccs, &z_lcccs, &z_cccs, &r_x_prime).unwrap(); + let sigmas_thetas = compute_sigmas_thetas(&ccs, &z_lcccs, &z_cccs, &r_x_prime)?; let expected_c = compute_c( &ccs, @@ -969,19 +967,20 @@ mod tests { .map(|lcccs| lcccs.r_x.clone()) .collect(), &r_x_prime, - ) - .unwrap(); + )?; let cs = ConstraintSystem::::new_ref(); let mut vec_sigmas = Vec::new(); let mut vec_thetas = Vec::new(); for sigmas in sigmas_thetas.0 { - vec_sigmas - .push(Vec::>::new_witness(cs.clone(), || Ok(sigmas.clone())).unwrap()); + vec_sigmas.push(Vec::>::new_witness(cs.clone(), || { + Ok(sigmas.clone()) + })?); } for thetas in sigmas_thetas.1 { - vec_thetas - .push(Vec::>::new_witness(cs.clone(), || Ok(thetas.clone())).unwrap()); + vec_thetas.push(Vec::>::new_witness(cs.clone(), || { + Ok(thetas.clone()) + })?); } let vec_r_x: Vec>> = lcccs_instances .iter() @@ -989,10 +988,9 @@ mod tests { Vec::>::new_witness(cs.clone(), || Ok(lcccs.r_x.clone())).unwrap() }) .collect(); - let vec_r_x_prime = - Vec::>::new_witness(cs.clone(), || Ok(r_x_prime.clone())).unwrap(); - let gamma_var = FpVar::::new_witness(cs.clone(), || Ok(gamma)).unwrap(); - let beta_var = Vec::>::new_witness(cs.clone(), || Ok(beta.clone())).unwrap(); + let vec_r_x_prime = Vec::>::new_witness(cs.clone(), || Ok(r_x_prime.clone()))?; + let gamma_var = FpVar::::new_witness(cs.clone(), || Ok(gamma))?; + let beta_var = Vec::>::new_witness(cs.clone(), || Ok(beta.clone()))?; let computed_c = compute_c_gadget( cs.clone(), @@ -1003,22 +1001,21 @@ mod tests { beta_var, vec_r_x, vec_r_x_prime, - ) - .unwrap(); + )?; - assert_eq!(expected_c, computed_c.value().unwrap()); + assert_eq!(expected_c, computed_c.value()?); + Ok(()) } /// Test that generates mu>1 and nu>1 instances, and folds them in a single multifolding step, /// to verify the folding in the NIMFSGadget circuit #[test] - pub fn test_nimfs_gadget_verify() { + pub fn test_nimfs_gadget_verify() -> Result<(), Error> { let mut rng = test_rng(); // Create a basic CCS circuit let ccs = get_test_ccs::(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; let mu = 32; let nu = 42; @@ -1039,13 +1036,11 @@ mod tests { let mut lcccs_instances = Vec::new(); let mut w_lcccs = Vec::new(); for z_i in z_lcccs.iter() { - let (running_instance, w) = ccs - .to_lcccs::<_, _, Pedersen, false>( - &mut rng, - &pedersen_params, - z_i, - ) - .unwrap(); + let (running_instance, w) = ccs.to_lcccs::<_, _, Pedersen, false>( + &mut rng, + &pedersen_params, + z_i, + )?; lcccs_instances.push(running_instance); w_lcccs.push(w); } @@ -1053,9 +1048,8 @@ mod tests { let mut cccs_instances = Vec::new(); let mut w_cccs = Vec::new(); for z_i in z_cccs.iter() { - let (new_instance, w) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (new_instance, w) = + ccs.to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i)?; cccs_instances.push(new_instance); w_cccs.push(w); } @@ -1073,8 +1067,7 @@ mod tests { &cccs_instances, &w_lcccs, &w_cccs, - ) - .unwrap(); + )?; // Verifier's transcript let mut transcript_v: PoseidonSponge = PoseidonSponge::::new(&poseidon_config); @@ -1086,26 +1079,22 @@ mod tests { &lcccs_instances, &cccs_instances, proof.clone(), - ) - .unwrap(); + )?; assert_eq!(folded_lcccs, folded_lcccs_v); // Check that the folded LCCCS instance is a valid instance with respect to the folded witness - ccs.check_relation(&folded_witness, &folded_lcccs).unwrap(); + ccs.check_relation(&folded_witness, &folded_lcccs)?; // allocate circuit inputs let cs = ConstraintSystem::::new_ref(); let lcccs_instancesVar = - Vec::>::new_witness(cs.clone(), || Ok(lcccs_instances.clone())) - .unwrap(); + Vec::>::new_witness(cs.clone(), || Ok(lcccs_instances.clone()))?; let cccs_instancesVar = - Vec::>::new_witness(cs.clone(), || Ok(cccs_instances.clone())) - .unwrap(); - let proofVar = - ProofVar::::new_witness(cs.clone(), || Ok(proof.clone())).unwrap(); + Vec::>::new_witness(cs.clone(), || Ok(cccs_instances.clone()))?; + let proofVar = ProofVar::::new_witness(cs.clone(), || Ok(proof.clone()))?; let mut transcriptVar = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); - let enabled = Boolean::::new_witness(cs.clone(), || Ok(true)).unwrap(); + let enabled = Boolean::::new_witness(cs.clone(), || Ok(true))?; let (folded_lcccsVar, _) = NIMFSGadget::::verify( cs.clone(), &ccs, @@ -1114,46 +1103,48 @@ mod tests { &cccs_instancesVar, proofVar, enabled, - ) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); - assert_eq!(folded_lcccsVar.u.value().unwrap(), folded_lcccs.u); + )?; + assert!(cs.is_satisfied()?); + assert_eq!(folded_lcccsVar.u.value()?, folded_lcccs.u); + Ok(()) } /// test that checks the native LCCCS.to_sponge_{bytes,field_elements} vs /// the R1CS constraints version #[test] - pub fn test_lcccs_to_sponge_preimage() { + pub fn test_lcccs_to_sponge_preimage() -> Result<(), Error> { let mut rng = test_rng(); let ccs = get_test_ccs(); let z1 = get_test_z::(3); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; - let (lcccs, _) = ccs - .to_lcccs::<_, _, Pedersen, true>(&mut rng, &pedersen_params, &z1) - .unwrap(); + let (lcccs, _) = ccs.to_lcccs::<_, _, Pedersen, true>( + &mut rng, + &pedersen_params, + &z1, + )?; let bytes = lcccs.to_sponge_bytes_as_vec(); let field_elements = lcccs.to_sponge_field_elements_as_vec(); let cs = ConstraintSystem::::new_ref(); - let lcccsVar = LCCCSVar::::new_witness(cs.clone(), || Ok(lcccs)).unwrap(); - let bytes_var = lcccsVar.to_sponge_bytes().unwrap(); - let field_elements_var = lcccsVar.to_sponge_field_elements().unwrap(); + let lcccsVar = LCCCSVar::::new_witness(cs.clone(), || Ok(lcccs))?; + let bytes_var = lcccsVar.to_sponge_bytes()?; + let field_elements_var = lcccsVar.to_sponge_field_elements()?; - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(bytes_var.value().unwrap(), bytes); - assert_eq!(field_elements_var.value().unwrap(), field_elements); + assert_eq!(bytes_var.value()?, bytes); + assert_eq!(field_elements_var.value()?, field_elements); + Ok(()) } /// test that checks the native LCCCS.hash vs the R1CS constraints version #[test] - pub fn test_lcccs_hash() { + pub fn test_lcccs_hash() -> Result<(), Error> { let mut rng = test_rng(); let poseidon_config = poseidon_canonical_config::(); let sponge = PoseidonSponge::::new(&poseidon_config); @@ -1161,38 +1152,39 @@ mod tests { let ccs = get_test_ccs(); let z1 = get_test_z::(3); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; let pp_hash = Fr::from(42u32); // only for test let i = Fr::from(3_u32); let z_0 = vec![Fr::from(3_u32)]; let z_i = vec![Fr::from(3_u32)]; - let (lcccs, _) = ccs - .to_lcccs::<_, _, Pedersen, true>(&mut rng, &pedersen_params, &z1) - .unwrap(); + let (lcccs, _) = ccs.to_lcccs::<_, _, Pedersen, true>( + &mut rng, + &pedersen_params, + &z1, + )?; let h = lcccs.clone().hash(&sponge, pp_hash, i, &z_0, &z_i); let cs = ConstraintSystem::::new_ref(); let spongeVar = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); - let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash)).unwrap(); - let iVar = FpVar::::new_witness(cs.clone(), || Ok(i)).unwrap(); - let z_0Var = Vec::>::new_witness(cs.clone(), || Ok(z_0.clone())).unwrap(); - let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone())).unwrap(); - let lcccsVar = LCCCSVar::::new_witness(cs.clone(), || Ok(lcccs)).unwrap(); + let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash))?; + let iVar = FpVar::::new_witness(cs.clone(), || Ok(i))?; + let z_0Var = Vec::>::new_witness(cs.clone(), || Ok(z_0.clone()))?; + let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone()))?; + let lcccsVar = LCCCSVar::::new_witness(cs.clone(), || Ok(lcccs))?; let (hVar, _) = lcccsVar .clone() - .hash(&spongeVar, &pp_hashVar, &iVar, &z_0Var, &z_iVar) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + .hash(&spongeVar, &pp_hashVar, &iVar, &z_0Var, &z_iVar)?; + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(hVar.value().unwrap(), h); + assert_eq!(hVar.value()?, h); + Ok(()) } #[test] - pub fn test_augmented_f_circuit() { + pub fn test_augmented_f_circuit() -> Result<(), Error> { let mut rng = test_rng(); let poseidon_config = poseidon_canonical_config::(); let sponge = PoseidonSponge::::new(&poseidon_config); @@ -1201,14 +1193,13 @@ mod tests { const NU: usize = 3; let start = Instant::now(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let mut augmented_f_circuit = AugmentedFCircuit::, MU, NU>::empty( &poseidon_config, F_circuit, None, - ) - .unwrap(); + )?; let ccs = augmented_f_circuit.ccs.clone(); println!("AugmentedFCircuit & CCS generation: {:?}", start.elapsed()); println!("CCS m x n: {} x {}", ccs.m, ccs.n); @@ -1216,19 +1207,15 @@ mod tests { // CycleFold circuit let cs2 = ConstraintSystem::::new_ref(); let cf_circuit = HyperNovaCycleFoldCircuit::::empty(); - cf_circuit.generate_constraints(cs2.clone()).unwrap(); + cf_circuit.generate_constraints(cs2.clone())?; cs2.finalize(); - let cs2 = cs2 - .into_inner() - .ok_or(Error::NoInnerConstraintSystem) - .unwrap(); - let cf_r1cs = extract_r1cs::(&cs2).unwrap(); + let cs2 = cs2.into_inner().ok_or(Error::NoInnerConstraintSystem)?; + let cf_r1cs = extract_r1cs::(&cs2)?; println!("CF m x n: {} x {}", cf_r1cs.A.n_rows, cf_r1cs.A.n_cols); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; let (cf_pedersen_params, _) = - Pedersen::::setup(&mut rng, cf_r1cs.A.n_cols - cf_r1cs.l - 1).unwrap(); + Pedersen::::setup(&mut rng, cf_r1cs.A.n_cols - cf_r1cs.l - 1)?; // public params hash let pp_hash = Fr::from(42u32); // only for test @@ -1274,7 +1261,7 @@ mod tests { let all_Ws = [vec![W_i.clone()], Ws].concat(); let all_ws = [vec![w_i.clone()], ws].concat(); - let z_i1 = F_circuit.step_native(i, z_i.clone(), vec![]).unwrap(); + let z_i1 = F_circuit.step_native(i, z_i.clone(), vec![])?; let (U_i1, W_i1); @@ -1333,16 +1320,16 @@ mod tests { &all_us, &all_Ws, &all_ws, - ) - .unwrap(); + )?; // sanity check: check the folded instance relation - ccs.check_relation(&W_i1, &U_i1).unwrap(); + ccs.check_relation(&W_i1, &U_i1)?; let u_i1_x = U_i1.hash(&sponge, pp_hash, iFr + Fr::one(), &z_0, &z_i1); let rho_bits = rho.into_bigint().to_bits_le()[..NOVA_N_BITS_RO].to_vec(); - let rho_Fq = Fq::from_bigint(BigInteger::from_bits_le(&rho_bits)).unwrap(); + let rho_Fq = Fq::from_bigint(BigInteger::from_bits_le(&rho_bits)) + .ok_or(Error::OutOfBounds)?; // CycleFold part: // get the vector used as public inputs 'x' in the CycleFold circuit @@ -1399,8 +1386,7 @@ mod tests { cf_u_i_x, // CycleFold incoming instance cf_circuit, &mut rng, - ) - .unwrap(); + )?; // hash the CycleFold folded instance, which is used as the 2nd public input in the // AugmentedFCircuit @@ -1445,18 +1431,20 @@ mod tests { cf_U_i = cf_U_i1; } - let (cs, _) = augmented_f_circuit.compute_cs_ccs().unwrap(); - assert!(cs.is_satisfied().unwrap()); + let (cs, _) = augmented_f_circuit.compute_cs_ccs()?; + assert!(cs.is_satisfied()?); let (r1cs_w_i1, r1cs_x_i1) = extract_w_x::(&cs); // includes 1 and public inputs assert_eq!(r1cs_x_i1[0], augmented_f_circuit.x.unwrap()); let r1cs_z = [vec![Fr::one()], r1cs_x_i1.clone(), r1cs_w_i1.clone()].concat(); // compute committed instances, w_{i+1}, u_{i+1}, which will be used as w_i, u_i, so we // assign them directly to w_i, u_i. - (u_i, w_i) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &r1cs_z) - .unwrap(); - ccs.check_relation(&w_i, &u_i).unwrap(); + (u_i, w_i) = ccs.to_cccs::<_, _, Pedersen, false>( + &mut rng, + &pedersen_params, + &r1cs_z, + )?; + ccs.check_relation(&w_i, &u_i)?; // sanity checks assert_eq!(w_i.w, r1cs_w_i1); @@ -1477,14 +1465,15 @@ mod tests { W_i = W_i1.clone(); // check the new LCCCS instance relation - ccs.check_relation(&W_i, &U_i).unwrap(); + ccs.check_relation(&W_i, &U_i)?; // check the new CCCS instance relation - ccs.check_relation(&w_i, &u_i).unwrap(); + ccs.check_relation(&w_i, &u_i)?; // check the CycleFold instance relation - cf_r1cs.check_relation(&cf_W_i, &cf_U_i).unwrap(); + cf_r1cs.check_relation(&cf_W_i, &cf_U_i)?; println!("augmented_f_circuit step {}: {:?}", i, start.elapsed()); } + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/decider_eth.rs b/folding-schemes/src/folding/hypernova/decider_eth.rs index c8b84524..51dddfde 100644 --- a/folding-schemes/src/folding/hypernova/decider_eth.rs +++ b/folding-schemes/src/folding/hypernova/decider_eth.rs @@ -238,7 +238,7 @@ pub mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_decider() { + fn test_decider() -> Result<(), Error> { const MU: usize = 1; const NU: usize = 1; // use HyperNova as FoldingScheme @@ -271,26 +271,22 @@ pub mod tests { let mut rng = rand::rngs::OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let prep_param = PreprocessorParam::new(poseidon_config, F_circuit); - let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap(); + let hypernova_params = HN::preprocess(&mut rng, &prep_param)?; - let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap(); - hypernova - .prove_step(&mut rng, vec![], Some((vec![], vec![]))) - .unwrap(); - hypernova - .prove_step(&mut rng, vec![], Some((vec![], vec![]))) - .unwrap(); // do a 2nd step + let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone())?; + hypernova.prove_step(&mut rng, vec![], Some((vec![], vec![])))?; + hypernova.prove_step(&mut rng, vec![], Some((vec![], vec![])))?; // do a 2nd step // prepare the Decider prover & verifier params let (decider_pp, decider_vp) = - D::preprocess(&mut rng, hypernova_params, hypernova.clone()).unwrap(); + D::preprocess(&mut rng, hypernova_params, hypernova.clone())?; // decider proof generation - let proof = D::prove(rng, decider_pp, hypernova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, hypernova.clone())?; // decider proof verification let verified = D::verify( @@ -301,13 +297,13 @@ pub mod tests { &hypernova.U_i.get_commitments(), &hypernova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } #[test] - fn test_decider_serialization() { + fn test_decider_serialization() -> Result<(), Error> { const MU: usize = 1; const NU: usize = 1; // use HyperNova as FoldingScheme @@ -340,61 +336,53 @@ pub mod tests { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let prep_param = PreprocessorParam::new(poseidon_config.clone(), F_circuit); - let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap(); + let hypernova_params = HN::preprocess(&mut rng, &prep_param)?; - let hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap(); + let hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone())?; let mut rng = rand::rngs::OsRng; // prepare the Decider prover & verifier params let (decider_pp, decider_vp) = - D::preprocess(&mut rng, hypernova_params.clone(), hypernova.clone()).unwrap(); + D::preprocess(&mut rng, hypernova_params.clone(), hypernova.clone())?; let mut hypernova_pp_serialized = vec![]; hypernova_params .0 .clone() - .serialize_compressed(&mut hypernova_pp_serialized) - .unwrap(); + .serialize_compressed(&mut hypernova_pp_serialized)?; let mut hypernova_vp_serialized = vec![]; hypernova_params .1 .clone() - .serialize_compressed(&mut hypernova_vp_serialized) - .unwrap(); + .serialize_compressed(&mut hypernova_vp_serialized)?; let hypernova_pp_deserialized = HN::pp_deserialize_with_mode( hypernova_pp_serialized.as_slice(), Compress::Yes, Validate::No, (), // FCircuit's Params - ) - .unwrap(); + )?; let hypernova_vp_deserialized = HN::vp_deserialize_with_mode( hypernova_vp_serialized.as_slice(), Compress::Yes, Validate::No, (), // FCircuit's Params - ) - .unwrap(); + )?; let hypernova_params = (hypernova_pp_deserialized, hypernova_vp_deserialized); - let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap(); + let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone())?; - hypernova - .prove_step(&mut rng, vec![], Some((vec![], vec![]))) - .unwrap(); - hypernova - .prove_step(&mut rng, vec![], Some((vec![], vec![]))) - .unwrap(); + hypernova.prove_step(&mut rng, vec![], Some((vec![], vec![])))?; + hypernova.prove_step(&mut rng, vec![], Some((vec![], vec![])))?; // decider proof generation - let proof = D::prove(rng, decider_pp, hypernova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, hypernova.clone())?; let verified = D::verify( decider_vp.clone(), @@ -404,8 +392,7 @@ pub mod tests { &hypernova.U_i.get_commitments(), &hypernova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); // The rest of this test will serialize the data and deserialize it back, and use it to @@ -413,33 +400,26 @@ pub mod tests { // serialize the verifier_params, proof and public inputs let mut decider_vp_serialized = vec![]; - decider_vp - .serialize_compressed(&mut decider_vp_serialized) - .unwrap(); + decider_vp.serialize_compressed(&mut decider_vp_serialized)?; let mut proof_serialized = vec![]; - proof.serialize_compressed(&mut proof_serialized).unwrap(); + proof.serialize_compressed(&mut proof_serialized)?; // serialize the public inputs in a single packet let mut public_inputs_serialized = vec![]; hypernova .i - .serialize_compressed(&mut public_inputs_serialized) - .unwrap(); + .serialize_compressed(&mut public_inputs_serialized)?; hypernova .z_0 - .serialize_compressed(&mut public_inputs_serialized) - .unwrap(); + .serialize_compressed(&mut public_inputs_serialized)?; hypernova .z_i - .serialize_compressed(&mut public_inputs_serialized) - .unwrap(); + .serialize_compressed(&mut public_inputs_serialized)?; hypernova .U_i - .serialize_compressed(&mut public_inputs_serialized) - .unwrap(); + .serialize_compressed(&mut public_inputs_serialized)?; hypernova .u_i - .serialize_compressed(&mut public_inputs_serialized) - .unwrap(); + .serialize_compressed(&mut public_inputs_serialized)?; // deserialize back the verifier_params, proof and public inputs let decider_vp_deserialized = @@ -447,21 +427,19 @@ pub mod tests { Projective, as CommitmentScheme>::VerifierParams, as SNARK>::VerifyingKey, - >::deserialize_compressed(&mut decider_vp_serialized.as_slice()) - .unwrap(); + >::deserialize_compressed(&mut decider_vp_serialized.as_slice())?; let proof_deserialized = Proof::, Groth16>::deserialize_compressed( &mut proof_serialized.as_slice(), - ) - .unwrap(); + )?; let mut reader = public_inputs_serialized.as_slice(); - let i_deserialized = Fr::deserialize_compressed(&mut reader).unwrap(); - let z_0_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); - let z_i_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); - let _U_i = LCCCS::::deserialize_compressed(&mut reader).unwrap(); - let _u_i = CCCS::::deserialize_compressed(&mut reader).unwrap(); + let i_deserialized = Fr::deserialize_compressed(&mut reader)?; + let z_0_deserialized = Vec::::deserialize_compressed(&mut reader)?; + let z_i_deserialized = Vec::::deserialize_compressed(&mut reader)?; + let _U_i = LCCCS::::deserialize_compressed(&mut reader)?; + let _u_i = CCCS::::deserialize_compressed(&mut reader)?; let verified = D::verify( decider_vp_deserialized, @@ -471,8 +449,8 @@ pub mod tests { &hypernova.U_i.get_commitments(), &hypernova.u_i.get_commitments(), &proof_deserialized, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/decider_eth_circuit.rs b/folding-schemes/src/folding/hypernova/decider_eth_circuit.rs index 0485fe84..03c016e2 100644 --- a/folding-schemes/src/folding/hypernova/decider_eth_circuit.rs +++ b/folding-schemes/src/folding/hypernova/decider_eth_circuit.rs @@ -249,7 +249,7 @@ pub mod tests { use crate::FoldingScheme; #[test] - fn test_lcccs_checker_gadget() { + fn test_lcccs_checker_gadget() -> Result<(), Error> { let mut rng = test_rng(); let n_rows = 2_u32.pow(5) as usize; let n_cols = 2_u32.pow(5) as usize; @@ -257,31 +257,33 @@ pub mod tests { let ccs = CCS::from(r1cs); let z: Vec = (0..n_cols).map(|_| Fr::rand(&mut rng)).collect(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; - let (lcccs, w) = ccs - .to_lcccs::<_, Projective, Pedersen, false>(&mut rng, &pedersen_params, &z) - .unwrap(); + let (lcccs, w) = ccs.to_lcccs::<_, Projective, Pedersen, false>( + &mut rng, + &pedersen_params, + &z, + )?; let cs = ConstraintSystem::::new_ref(); // CCS's (sparse) matrices are constants in the circuit - let ccs_mat = CCSMatricesVar::::new_constant(cs.clone(), ccs.clone()).unwrap(); - let w_var = WitnessVar::new_witness(cs.clone(), || Ok(w)).unwrap(); - let lcccs_var = LCCCSVar::new_input(cs.clone(), || Ok(lcccs)).unwrap(); + let ccs_mat = CCSMatricesVar::::new_constant(cs.clone(), ccs.clone())?; + let w_var = WitnessVar::new_witness(cs.clone(), || Ok(w))?; + let lcccs_var = LCCCSVar::new_input(cs.clone(), || Ok(lcccs))?; - ccs_mat.enforce_relation(&w_var, &lcccs_var).unwrap(); + ccs_mat.enforce_relation(&w_var, &lcccs_var)?; - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); + Ok(()) } #[test] - fn test_decider_circuit() { + fn test_decider_circuit() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; const MU: usize = 1; @@ -307,24 +309,25 @@ pub mod tests { Pedersen, false, >::new(poseidon_config, F_circuit); - let hn_params = HN::preprocess(&mut rng, &prep_param).unwrap(); + let hn_params = HN::preprocess(&mut rng, &prep_param)?; // generate a Nova instance and do a step of it - let mut hypernova = HN::init(&hn_params, F_circuit, z_0.clone()).unwrap(); - hypernova.prove_step(&mut rng, vec![], None).unwrap(); + let mut hypernova = HN::init(&hn_params, F_circuit, z_0.clone())?; + hypernova.prove_step(&mut rng, vec![], None)?; let ivc_proof = hypernova.ivc_proof(); - HN::verify(hn_params.1, ivc_proof).unwrap(); + HN::verify(hn_params.1, ivc_proof)?; // load the DeciderEthCircuit from the generated Nova instance let decider_circuit = - DeciderEthCircuit::::try_from(hypernova).unwrap(); + DeciderEthCircuit::::try_from(hypernova)?; let cs = ConstraintSystem::::new_ref(); // generate the constraints and check that are satisfied by the inputs - decider_circuit.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + decider_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); dbg!(cs.num_constraints()); + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/lcccs.rs b/folding-schemes/src/folding/hypernova/lcccs.rs index 40034da3..1393d84f 100644 --- a/folding-schemes/src/folding/hypernova/lcccs.rs +++ b/folding-schemes/src/folding/hypernova/lcccs.rs @@ -187,28 +187,27 @@ pub mod tests { ccs: &CCS, lcccs: &LCCCS, z: &[C::ScalarField], - ) -> Vec> { - let eq_rx = build_eq_x_r_vec(&lcccs.r_x).unwrap(); + ) -> Result>, Error> { + let eq_rx = build_eq_x_r_vec(&lcccs.r_x)?; let eq_rx_mle = dense_vec_to_dense_mle(ccs.s, &eq_rx); let mut Ls = Vec::with_capacity(ccs.t); for M_j in ccs.M.iter() { let mut L = VirtualPolynomial::::new(ccs.s); - let mut Mz = vec![dense_vec_to_dense_mle(ccs.s, &mat_vec_mul(M_j, z).unwrap())]; + let mut Mz = vec![dense_vec_to_dense_mle(ccs.s, &mat_vec_mul(M_j, z)?)]; Mz.push(eq_rx_mle.clone()); L.add_mle_list( Mz.iter().map(|v| Arc::new(v.clone())), C::ScalarField::one(), - ) - .unwrap(); + )?; Ls.push(L); } - Ls + Ok(Ls) } #[test] /// Test linearized CCCS v_j against the L_j(x) - fn test_lcccs_v_j() { + fn test_lcccs_v_j() -> Result<(), Error> { let mut rng = test_rng(); let n_rows = 2_u32.pow(5) as usize; @@ -217,39 +216,39 @@ pub mod tests { let ccs = CCS::from(r1cs); let z: Vec = (0..n_cols).map(|_| Fr::rand(&mut rng)).collect(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; - let (lcccs, _) = ccs - .to_lcccs::<_, Projective, Pedersen, false>( - &mut rng, - &pedersen_params, - &z, - ) - .unwrap(); + let (lcccs, _) = ccs.to_lcccs::<_, Projective, Pedersen, false>( + &mut rng, + &pedersen_params, + &z, + )?; // with our test vector coming from R1CS, v should have length 3 assert_eq!(lcccs.v.len(), 3); - let vec_L_j_x = compute_Ls(&ccs, &lcccs, &z); + let vec_L_j_x = compute_Ls(&ccs, &lcccs, &z)?; assert_eq!(vec_L_j_x.len(), lcccs.v.len()); for (v_i, L_j_x) in lcccs.v.into_iter().zip(vec_L_j_x) { let sum_L_j_x = BooleanHypercube::new(ccs.s) - .map(|y| L_j_x.evaluate(&y).unwrap()) + .map(|y| L_j_x.evaluate(&y)) + .collect::, _>>()? + .into_iter() .fold(Fr::zero(), |acc, result| acc + result); assert_eq!(v_i, sum_L_j_x); } + Ok(()) } /// Given a bad z, check that the v_j should not match with the L_j(x) #[test] - fn test_bad_v_j() { + fn test_bad_v_j() -> Result<(), Error> { let mut rng = test_rng(); let ccs = get_test_ccs(); let z = get_test_z(3); let (w, x) = ccs.split_z(&z); - ccs.check_relation(&w, &x).unwrap(); + ccs.check_relation(&w, &x)?; // Mutate z so that the relation does not hold let mut bad_z = z.clone(); @@ -257,17 +256,18 @@ pub mod tests { let (bad_w, bad_x) = ccs.split_z(&bad_z); assert!(ccs.check_relation(&bad_w, &bad_x).is_err()); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; // Compute v_j with the right z - let (lcccs, _) = ccs - .to_lcccs::<_, Projective, Pedersen, false>(&mut rng, &pedersen_params, &z) - .unwrap(); + let (lcccs, _) = ccs.to_lcccs::<_, Projective, Pedersen, false>( + &mut rng, + &pedersen_params, + &z, + )?; // with our test vector coming from R1CS, v should have length 3 assert_eq!(lcccs.v.len(), 3); // Bad compute L_j(x) with the bad z - let vec_L_j_x = compute_Ls(&ccs, &lcccs, &bad_z); + let vec_L_j_x = compute_Ls(&ccs, &lcccs, &bad_z)?; assert_eq!(vec_L_j_x.len(), lcccs.v.len()); // Make sure that the LCCCS is not satisfied given these L_j(x) @@ -275,12 +275,15 @@ pub mod tests { let mut satisfied = true; for (v_i, L_j_x) in lcccs.v.into_iter().zip(vec_L_j_x) { let sum_L_j_x = BooleanHypercube::new(ccs.s) - .map(|y| L_j_x.evaluate(&y).unwrap()) + .map(|y| L_j_x.evaluate(&y)) + .collect::, _>>()? + .into_iter() .fold(Fr::zero(), |acc, result| acc + result); if v_i != sum_L_j_x { satisfied = false; } } assert!(!satisfied); + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/mod.rs b/folding-schemes/src/folding/hypernova/mod.rs index 0eaf4ff9..957342fe 100644 --- a/folding-schemes/src/folding/hypernova/mod.rs +++ b/folding-schemes/src/folding/hypernova/mod.rs @@ -1108,25 +1108,27 @@ mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - pub fn test_ivc() { + pub fn test_ivc() -> Result<(), Error> { let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; // run the test using Pedersen commitments on both sides of the curve cycle - test_ivc_opt::, Pedersen, false>( + let _ = test_ivc_opt::, Pedersen, false>( poseidon_config.clone(), F_circuit, - ); + )?; - test_ivc_opt::, Pedersen, true>( + let _ = test_ivc_opt::, Pedersen, true>( poseidon_config.clone(), F_circuit, - ); + )?; // run the test using KZG for the commitments on the main curve, and Pedersen for the // commitments on the secondary curve - test_ivc_opt::, Pedersen, false>(poseidon_config, F_circuit); + let _ = + test_ivc_opt::, Pedersen, false>(poseidon_config, F_circuit)?; + Ok(()) } #[allow(clippy::type_complexity)] @@ -1138,7 +1140,7 @@ mod tests { >( poseidon_config: PoseidonConfig, F_circuit: CubicFCircuit, - ) { + ) -> Result<(), Error> { let mut rng = ark_std::test_rng(); const MU: usize = 2; @@ -1152,10 +1154,10 @@ mod tests { poseidon_config.clone(), F_circuit, ); - let hypernova_params = HN::preprocess(&mut rng, &prep_param).unwrap(); + let hypernova_params = HN::preprocess(&mut rng, &prep_param)?; let z_0 = vec![Fr::from(3_u32)]; - let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone()).unwrap(); + let mut hypernova = HN::init(&hypernova_params, F_circuit, z_0.clone())?; let (w_i_blinding, W_i_blinding) = if H { (Fr::rand(&mut rng), Fr::rand(&mut rng)) @@ -1171,23 +1173,17 @@ mod tests { let mut lcccs = vec![]; for j in 0..MU - 1 { let instance_state = vec![Fr::from(j as u32 + 85_u32)]; - let (U, W) = hypernova - .new_running_instance(&mut rng, instance_state, vec![]) - .unwrap(); + let (U, W) = hypernova.new_running_instance(&mut rng, instance_state, vec![])?; lcccs.push((U, W)); } let mut cccs = vec![]; for j in 0..NU - 1 { let instance_state = vec![Fr::from(j as u32 + 15_u32)]; - let (u, w) = hypernova - .new_incoming_instance(&mut rng, instance_state, vec![]) - .unwrap(); + let (u, w) = hypernova.new_incoming_instance(&mut rng, instance_state, vec![])?; cccs.push((u, w)); } - hypernova - .prove_step(&mut rng, vec![], Some((lcccs, cccs))) - .unwrap(); + hypernova.prove_step(&mut rng, vec![], Some((lcccs, cccs)))?; } assert_eq!(Fr::from(num_steps as u32), hypernova.i); @@ -1195,7 +1191,7 @@ mod tests { HN::verify( hypernova_params.1.clone(), // verifier_params ivc_proof, - ) - .unwrap(); + )?; + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/nimfs.rs b/folding-schemes/src/folding/hypernova/nimfs.rs index 40bf5717..9e1e944e 100644 --- a/folding-schemes/src/folding/hypernova/nimfs.rs +++ b/folding-schemes/src/folding/hypernova/nimfs.rs @@ -415,33 +415,35 @@ pub mod tests { use ark_pallas::{Fr, Projective}; #[test] - fn test_fold() { + fn test_fold() -> Result<(), Error> { let ccs = get_test_ccs(); let z1 = get_test_z::(3); let z2 = get_test_z::(4); let (w1, x1) = ccs.split_z(&z1); let (w2, x2) = ccs.split_z(&z2); - ccs.check_relation(&w1, &x1).unwrap(); - ccs.check_relation(&w2, &x2).unwrap(); + ccs.check_relation(&w1, &x1)?; + ccs.check_relation(&w2, &x2)?; let mut rng = test_rng(); let r_x_prime: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); - let sigmas_thetas = - compute_sigmas_thetas(&ccs, &[z1.clone()], &[z2.clone()], &r_x_prime).unwrap(); + let sigmas_thetas = compute_sigmas_thetas(&ccs, &[z1.clone()], &[z2.clone()], &r_x_prime)?; - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; - let (lcccs, w1) = ccs - .to_lcccs::<_, Projective, Pedersen, false>(&mut rng, &pedersen_params, &z1) - .unwrap(); - let (cccs, w2) = ccs - .to_cccs::<_, Projective, Pedersen, false>(&mut rng, &pedersen_params, &z2) - .unwrap(); + let (lcccs, w1) = ccs.to_lcccs::<_, Projective, Pedersen, false>( + &mut rng, + &pedersen_params, + &z1, + )?; + let (cccs, w2) = ccs.to_cccs::<_, Projective, Pedersen, false>( + &mut rng, + &pedersen_params, + &z2, + )?; - ccs.check_relation(&w1, &lcccs).unwrap(); - ccs.check_relation(&w2, &cccs).unwrap(); + ccs.check_relation(&w1, &lcccs)?; + ccs.check_relation(&w2, &cccs)?; let mut rng = test_rng(); let rho = Fr::rand(&mut rng); @@ -457,18 +459,18 @@ pub mod tests { let w_folded = NIMFS::>::fold_witness(&[w1], &[w2], rho); // check lcccs relation - ccs.check_relation(&w_folded, &folded).unwrap(); + ccs.check_relation(&w_folded, &folded)?; + Ok(()) } /// Perform multifolding of an LCCCS instance with a CCCS instance (as described in the paper) #[test] - pub fn test_basic_multifolding() { + pub fn test_basic_multifolding() -> Result<(), Error> { let mut rng = test_rng(); // Create a basic CCS circuit let ccs = get_test_ccs::(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; // Generate a satisfying witness let z_1 = get_test_z(3); @@ -476,13 +478,11 @@ pub mod tests { let z_2 = get_test_z(4); // Create the LCCCS instance out of z_1 - let (running_instance, w1) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_1) - .unwrap(); + let (running_instance, w1) = + ccs.to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_1)?; // Create the CCCS instance out of z_2 - let (new_instance, w2) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_2) - .unwrap(); + let (new_instance, w2) = + ccs.to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_2)?; // Prover's transcript let poseidon_config = poseidon_canonical_config::(); @@ -498,8 +498,7 @@ pub mod tests { &[new_instance.clone()], &[w1], &[w2], - ) - .unwrap(); + )?; // Verifier's transcript let mut transcript_v: PoseidonSponge = PoseidonSponge::::new(&poseidon_config); @@ -512,29 +511,27 @@ pub mod tests { &[running_instance.clone()], &[new_instance.clone()], proof, - ) - .unwrap(); + )?; assert_eq!(folded_lcccs, folded_lcccs_v); // Check that the folded LCCCS instance is a valid instance with respect to the folded witness - ccs.check_relation(&folded_witness, &folded_lcccs).unwrap(); + ccs.check_relation(&folded_witness, &folded_lcccs)?; + Ok(()) } /// Perform multiple steps of multifolding of an LCCCS instance with a CCCS instance #[test] - pub fn test_multifolding_two_instances_multiple_steps() { + pub fn test_multifolding_two_instances_multiple_steps() -> Result<(), Error> { let mut rng = test_rng(); let ccs = get_test_ccs::(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; // LCCCS witness let z_1 = get_test_z(2); - let (mut running_instance, mut w1) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_1) - .unwrap(); + let (mut running_instance, mut w1) = + ccs.to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_1)?; let poseidon_config = poseidon_canonical_config::(); @@ -549,9 +546,8 @@ pub mod tests { // CCS witness let z_2 = get_test_z(i); - let (new_instance, w2) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_2) - .unwrap(); + let (new_instance, w2) = + ccs.to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z_2)?; // run the prover side of the multifolding let (proof, folded_lcccs, folded_witness, _) = @@ -562,8 +558,7 @@ pub mod tests { &[new_instance.clone()], &[w1], &[w2], - ) - .unwrap(); + )?; // run the verifier side of the multifolding let folded_lcccs_v = NIMFS::>::verify( @@ -572,27 +567,26 @@ pub mod tests { &[running_instance.clone()], &[new_instance.clone()], proof, - ) - .unwrap(); + )?; assert_eq!(folded_lcccs, folded_lcccs_v); // check that the folded instance with the folded witness holds the LCCCS relation - ccs.check_relation(&folded_witness, &folded_lcccs).unwrap(); + ccs.check_relation(&folded_witness, &folded_lcccs)?; running_instance = folded_lcccs; w1 = folded_witness; } + Ok(()) } /// Test that generates mu>1 and nu>1 instances, and folds them in a single multifolding step. #[test] - pub fn test_multifolding_mu_nu_instances() { + pub fn test_multifolding_mu_nu_instances() -> Result<(), Error> { let mut rng = test_rng(); // Create a basic CCS circuit let ccs = get_test_ccs::(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; let mu = 10; let nu = 15; @@ -613,9 +607,8 @@ pub mod tests { let mut lcccs_instances = Vec::new(); let mut w_lcccs = Vec::new(); for z_i in z_lcccs.iter() { - let (running_instance, w) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (running_instance, w) = + ccs.to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i)?; lcccs_instances.push(running_instance); w_lcccs.push(w); } @@ -623,9 +616,8 @@ pub mod tests { let mut cccs_instances = Vec::new(); let mut w_cccs = Vec::new(); for z_i in z_cccs.iter() { - let (new_instance, w) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (new_instance, w) = + ccs.to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i)?; cccs_instances.push(new_instance); w_cccs.push(w); } @@ -644,8 +636,7 @@ pub mod tests { &cccs_instances, &w_lcccs, &w_cccs, - ) - .unwrap(); + )?; // Verifier's transcript let mut transcript_v: PoseidonSponge = PoseidonSponge::::new(&poseidon_config); @@ -658,24 +649,23 @@ pub mod tests { &lcccs_instances, &cccs_instances, proof, - ) - .unwrap(); + )?; assert_eq!(folded_lcccs, folded_lcccs_v); // Check that the folded LCCCS instance is a valid instance with respect to the folded witness - ccs.check_relation(&folded_witness, &folded_lcccs).unwrap(); + ccs.check_relation(&folded_witness, &folded_lcccs)?; + Ok(()) } /// Test that generates mu>1 and nu>1 instances, and folds them in a single multifolding step /// and repeats the process doing multiple steps. #[test] - pub fn test_multifolding_mu_nu_instances_multiple_steps() { + pub fn test_multifolding_mu_nu_instances_multiple_steps() -> Result<(), Error> { let mut rng = test_rng(); // Create a basic CCS circuit let ccs = get_test_ccs::(); - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; let poseidon_config = poseidon_canonical_config::(); // Prover's transcript @@ -709,9 +699,11 @@ pub mod tests { let mut lcccs_instances = Vec::new(); let mut w_lcccs = Vec::new(); for z_i in z_lcccs.iter() { - let (running_instance, w) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (running_instance, w) = ccs.to_lcccs::<_, _, Pedersen, false>( + &mut rng, + &pedersen_params, + z_i, + )?; lcccs_instances.push(running_instance); w_lcccs.push(w); } @@ -719,9 +711,11 @@ pub mod tests { let mut cccs_instances = Vec::new(); let mut w_cccs = Vec::new(); for z_i in z_cccs.iter() { - let (new_instance, w) = ccs - .to_cccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, z_i) - .unwrap(); + let (new_instance, w) = ccs.to_cccs::<_, _, Pedersen, false>( + &mut rng, + &pedersen_params, + z_i, + )?; cccs_instances.push(new_instance); w_cccs.push(w); } @@ -735,8 +729,7 @@ pub mod tests { &cccs_instances, &w_lcccs, &w_cccs, - ) - .unwrap(); + )?; // Run the verifier side of the multifolding let folded_lcccs_v = NIMFS::>::verify( @@ -745,13 +738,13 @@ pub mod tests { &lcccs_instances, &cccs_instances, proof, - ) - .unwrap(); + )?; assert_eq!(folded_lcccs, folded_lcccs_v); // Check that the folded LCCCS instance is a valid instance with respect to the folded witness - ccs.check_relation(&folded_witness, &folded_lcccs).unwrap(); + ccs.check_relation(&folded_witness, &folded_lcccs)?; } + Ok(()) } } diff --git a/folding-schemes/src/folding/hypernova/utils.rs b/folding-schemes/src/folding/hypernova/utils.rs index 18a92224..40f256e4 100644 --- a/folding-schemes/src/folding/hypernova/utils.rs +++ b/folding-schemes/src/folding/hypernova/utils.rs @@ -197,7 +197,7 @@ pub mod tests { /// of the matrix and the z vector. This technique is also used extensively in "An Algebraic Framework for /// Universal and Updatable SNARKs". #[test] - fn test_compute_M_r_y_compression() { + fn test_compute_M_r_y_compression() -> Result<(), Error> { let mut rng = test_rng(); // s = 2, s' = 3 @@ -222,17 +222,18 @@ pub mod tests { assert_eq!(M_r_y.evaluations[j], rlc); } + Ok(()) } #[test] - fn test_compute_sigmas_thetas() { + fn test_compute_sigmas_thetas() -> Result<(), Error> { let ccs = get_test_ccs(); let z1 = get_test_z(3); let z2 = get_test_z(4); let (w1, x1) = ccs.split_z(&z1); let (w2, x2) = ccs.split_z(&z2); - ccs.check_relation(&w1, &x1).unwrap(); - ccs.check_relation(&w2, &x2).unwrap(); + ccs.check_relation(&w1, &x1)?; + ccs.check_relation(&w2, &x2)?; let mut rng = test_rng(); let gamma: Fr = Fr::rand(&mut rng); @@ -240,14 +241,11 @@ pub mod tests { let r_x_prime: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); // Initialize a multifolding object - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); - let (lcccs_instance, _) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z1) - .unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; + let (lcccs_instance, _) = + ccs.to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z1)?; - let sigmas_thetas = - compute_sigmas_thetas(&ccs, &[z1.clone()], &[z2.clone()], &r_x_prime).unwrap(); + let sigmas_thetas = compute_sigmas_thetas(&ccs, &[z1.clone()], &[z2.clone()], &r_x_prime)?; let g = compute_g( &ccs, @@ -256,13 +254,12 @@ pub mod tests { &[z2.clone()], gamma, &beta, - ) - .unwrap(); + )?; // we expect g(r_x_prime) to be equal to: // c = (sum gamma^j * e1 * sigma_j) + gamma^{t+1} * e2 * sum c_i * prod theta_j // from compute_c - let expected_c = g.evaluate(&r_x_prime).unwrap(); + let expected_c = g.evaluate(&r_x_prime)?; let c = compute_c::( &ccs, &sigmas_thetas, @@ -270,13 +267,13 @@ pub mod tests { &beta, &vec![lcccs_instance.r_x], &r_x_prime, - ) - .unwrap(); + )?; assert_eq!(c, expected_c); + Ok(()) } #[test] - fn test_compute_g() { + fn test_compute_g() -> Result<(), Error> { let mut rng = test_rng(); // generate test CCS & z vectors @@ -285,18 +282,16 @@ pub mod tests { let z2 = get_test_z(4); let (w1, x1) = ccs.split_z(&z1); let (w2, x2) = ccs.split_z(&z2); - ccs.check_relation(&w1, &x1).unwrap(); - ccs.check_relation(&w2, &x2).unwrap(); + ccs.check_relation(&w1, &x1)?; + ccs.check_relation(&w2, &x2)?; let gamma: Fr = Fr::rand(&mut rng); let beta: Vec = (0..ccs.s).map(|_| Fr::rand(&mut rng)).collect(); // Initialize a multifolding object - let (pedersen_params, _) = - Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1).unwrap(); - let (lcccs_instance, _) = ccs - .to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z1) - .unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, ccs.n - ccs.l - 1)?; + let (lcccs_instance, _) = + ccs.to_lcccs::<_, _, Pedersen, false>(&mut rng, &pedersen_params, &z1)?; // Compute g(x) with that r_x let g = compute_g::( @@ -306,13 +301,12 @@ pub mod tests { &[z2.clone()], gamma, &beta, - ) - .unwrap(); + )?; // evaluate g(x) over x \in {0,1}^s let mut g_on_bhc = Fr::zero(); for x in BooleanHypercube::new(ccs.s) { - g_on_bhc += g.evaluate(&x).unwrap(); + g_on_bhc += g.evaluate(&x)?; } // Q(x) over bhc is assumed to be zero, as checked in the test 'test_compute_Q' @@ -330,16 +324,17 @@ pub mod tests { // evaluate sum_{j \in [t]} (gamma^j * Lj(x)) over x \in {0,1}^s let mut sum_Lj_on_bhc = Fr::zero(); - let vec_L = compute_Ls(&ccs, &lcccs_instance, &z1); + let vec_L = compute_Ls(&ccs, &lcccs_instance, &z1)?; for x in BooleanHypercube::new(ccs.s) { for (j, Lj) in vec_L.iter().enumerate() { let gamma_j = gamma.pow([j as u64]); - sum_Lj_on_bhc += Lj.evaluate(&x).unwrap() * gamma_j; + sum_Lj_on_bhc += Lj.evaluate(&x)? * gamma_j; } } // evaluating g(x) over the boolean hypercube should give the same result as evaluating the // sum of gamma^j * Lj(x) over the boolean hypercube assert_eq!(g_on_bhc, sum_Lj_on_bhc); + Ok(()) } } diff --git a/folding-schemes/src/folding/mod.rs b/folding-schemes/src/folding/mod.rs index 32342886..255ca54f 100644 --- a/folding-schemes/src/folding/mod.rs +++ b/folding-schemes/src/folding/mod.rs @@ -28,15 +28,15 @@ pub mod tests { /// tests the IVC proofs and its serializers for the 3 implemented IVCs: Nova, HyperNova and /// ProtoGalaxy. #[test] - fn test_serialize_ivc_nova_hypernova_protogalaxy() { + fn test_serialize_ivc_nova_hypernova_protogalaxy() -> Result<(), Error> { let poseidon_config = poseidon_canonical_config::(); type FC = CubicFCircuit; - let f_circuit = FC::new(()).unwrap(); + let f_circuit = FC::new(())?; // test Nova type N = Nova, Pedersen, false>; let prep_param = NovaPreprocessorParam::new(poseidon_config.clone(), f_circuit); - test_serialize_ivc_opt::("nova".to_string(), prep_param.clone()).unwrap(); + test_serialize_ivc_opt::("nova".to_string(), prep_param.clone())?; // test HyperNova type HN = HyperNova< @@ -51,12 +51,13 @@ pub mod tests { 1, // nu false, >; - test_serialize_ivc_opt::("hypernova".to_string(), prep_param).unwrap(); + test_serialize_ivc_opt::("hypernova".to_string(), prep_param)?; // test ProtoGalaxy type P = ProtoGalaxy, Pedersen>; let prep_param = (poseidon_config, f_circuit); - test_serialize_ivc_opt::("protogalaxy".to_string(), prep_param).unwrap(); + test_serialize_ivc_opt::("protogalaxy".to_string(), prep_param)?; + Ok(()) } fn test_serialize_ivc_opt< @@ -79,17 +80,17 @@ pub mod tests { let fs_params = FS::preprocess(&mut rng, &prep_param)?; let z_0 = vec![C1::ScalarField::from(3_u32)]; - let mut fs = FS::init(&fs_params, F_circuit, z_0.clone()).unwrap(); + let mut fs = FS::init(&fs_params, F_circuit, z_0.clone())?; // perform multiple IVC steps (internally folding) let num_steps: usize = 3; for _ in 0..num_steps { - fs.prove_step(&mut rng, vec![], None).unwrap(); + fs.prove_step(&mut rng, vec![], None)?; } // verify the IVCProof let ivc_proof: FS::IVCProof = fs.ivc_proof(); - FS::verify(fs_params.1.clone(), ivc_proof.clone()).unwrap(); + FS::verify(fs_params.1.clone(), ivc_proof.clone())?; // serialize the IVCProof and store it in a file let mut writer = vec![]; @@ -98,31 +99,23 @@ pub mod tests { let mut file = std::fs::OpenOptions::new() .create(true) .write(true) - .open(format!("./ivc_proof-{}.serialized", name)) - .unwrap(); - file.write_all(&writer).unwrap(); + .open(format!("./ivc_proof-{}.serialized", name))?; + file.write_all(&writer)?; // read the IVCProof from the file deserializing it - let bytes = std::fs::read(format!("./ivc_proof-{}.serialized", name)).unwrap(); - let deserialized_ivc_proof = - FS::IVCProof::deserialize_compressed(bytes.as_slice()).unwrap(); + let bytes = std::fs::read(format!("./ivc_proof-{}.serialized", name))?; + let deserialized_ivc_proof = FS::IVCProof::deserialize_compressed(bytes.as_slice())?; // verify deserialized IVCProof - FS::verify(fs_params.1.clone(), deserialized_ivc_proof.clone()).unwrap(); + FS::verify(fs_params.1.clone(), deserialized_ivc_proof.clone())?; // build the FS from the given IVCProof, FC::Params, ProverParams and VerifierParams - let mut new_fs = FS::from_ivc_proof(deserialized_ivc_proof, (), fs_params.clone()).unwrap(); + let mut new_fs = FS::from_ivc_proof(deserialized_ivc_proof, (), fs_params.clone())?; // serialize the Nova params let mut fs_pp_serialized = vec![]; - fs_params - .0 - .serialize_compressed(&mut fs_pp_serialized) - .unwrap(); + fs_params.0.serialize_compressed(&mut fs_pp_serialized)?; let mut fs_vp_serialized = vec![]; - fs_params - .1 - .serialize_compressed(&mut fs_vp_serialized) - .unwrap(); + fs_params.1.serialize_compressed(&mut fs_vp_serialized)?; // deserialize the Nova params. This would be done by the client reading from a file let _fs_pp_deserialized = FS::pp_deserialize_with_mode( @@ -130,15 +123,14 @@ pub mod tests { ark_serialize::Compress::Yes, ark_serialize::Validate::Yes, (), // FCircuit's Params - ) - .unwrap(); + )?; // perform several IVC steps on both the original FS instance and the recovered from the // serialization new FS instance let num_steps: usize = 3; for _ in 0..num_steps { - new_fs.prove_step(&mut rng, vec![], None).unwrap(); - fs.prove_step(&mut rng, vec![], None).unwrap(); + new_fs.prove_step(&mut rng, vec![], None)?; + fs.prove_step(&mut rng, vec![], None)?; } // check that the IVCProofs from both FS instances are equal @@ -149,8 +141,7 @@ pub mod tests { ark_serialize::Compress::Yes, ark_serialize::Validate::Yes, (), // fcircuit_params - ) - .unwrap(); + )?; // get the IVCProof let ivc_proof: FS::IVCProof = new_fs.ivc_proof(); @@ -162,10 +153,10 @@ pub mod tests { .is_ok()); // deserialize IVCProof let ivc_proof_deserialized = - FS::IVCProof::deserialize_compressed(ivc_proof_serialized.as_slice()).unwrap(); + FS::IVCProof::deserialize_compressed(ivc_proof_serialized.as_slice())?; // verify the last IVCProof from the recovered from serialization FS - FS::verify(fs_vp_deserialized.clone(), ivc_proof_deserialized).unwrap(); + FS::verify(fs_vp_deserialized.clone(), ivc_proof_deserialized)?; Ok(()) } diff --git a/folding-schemes/src/folding/nova/circuits.rs b/folding-schemes/src/folding/nova/circuits.rs index b0f2c44f..48aa2025 100644 --- a/folding-schemes/src/folding/nova/circuits.rs +++ b/folding-schemes/src/folding/nova/circuits.rs @@ -350,10 +350,11 @@ pub mod tests { use crate::folding::nova::nifs::nova::ChallengeGadget; use crate::transcript::poseidon::poseidon_canonical_config; + use crate::Error; // checks that the gadget and native implementations of the challenge computation match #[test] - fn test_challenge_gadget() { + fn test_challenge_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); let mut transcript = PoseidonSponge::::new(&poseidon_config); @@ -383,25 +384,23 @@ pub mod tests { &u_i, Some(&cmT), ); - let r = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); + let r = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).ok_or(Error::OutOfBounds)?; let cs = ConstraintSystem::::new_ref(); - let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash)).unwrap(); + let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash))?; let u_iVar = - CommittedInstanceVar::::new_witness(cs.clone(), || Ok(u_i.clone())) - .unwrap(); + CommittedInstanceVar::::new_witness(cs.clone(), || Ok(u_i.clone()))?; let U_iVar = - CommittedInstanceVar::::new_witness(cs.clone(), || Ok(U_i.clone())) - .unwrap(); - let cmTVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(cmT)).unwrap(); + CommittedInstanceVar::::new_witness(cs.clone(), || Ok(U_i.clone()))?; + let cmTVar = NonNativeAffineVar::::new_witness(cs.clone(), || Ok(cmT))?; let mut transcriptVar = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); // compute the challenge in-circuit let U_iVar_vec = [ vec![U_iVar.u.clone()], U_iVar.x.clone(), - U_iVar.cmE.to_constraint_field().unwrap(), - U_iVar.cmW.to_constraint_field().unwrap(), + U_iVar.cmE.to_constraint_field()?, + U_iVar.cmW.to_constraint_field()?, ] .concat(); let r_bitsVar = @@ -411,13 +410,13 @@ pub mod tests { U_iVar_vec, u_iVar, Some(cmTVar), - ) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + )?; + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - let rVar = Boolean::le_bits_to_fp(&r_bitsVar).unwrap(); - assert_eq!(rVar.value().unwrap(), r); - assert_eq!(r_bitsVar.value().unwrap(), r_bits); + let rVar = Boolean::le_bits_to_fp(&r_bitsVar)?; + assert_eq!(rVar.value()?, r); + assert_eq!(r_bitsVar.value()?, r_bits); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/decider.rs b/folding-schemes/src/folding/nova/decider.rs index 4a1e6f39..ef24d928 100644 --- a/folding-schemes/src/folding/nova/decider.rs +++ b/folding-schemes/src/folding/nova/decider.rs @@ -359,7 +359,7 @@ pub mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_decider() { + fn test_decider() -> Result<(), Error> { // use Nova as FoldingScheme type N = Nova< Projective, @@ -387,32 +387,32 @@ pub mod tests { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let start = Instant::now(); let prep_param = PreprocessorParam::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &prep_param).unwrap(); + let nova_params = N::preprocess(&mut rng, &prep_param)?; println!("Nova preprocess, {:?}", start.elapsed()); let start = Instant::now(); - let mut nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap(); + let mut nova = N::init(&nova_params, F_circuit, z_0.clone())?; println!("Nova initialized, {:?}", start.elapsed()); let start = Instant::now(); - nova.prove_step(&mut rng, vec![], None).unwrap(); + nova.prove_step(&mut rng, vec![], None)?; println!("prove_step, {:?}", start.elapsed()); - nova.prove_step(&mut rng, vec![], None).unwrap(); // do a 2nd step + nova.prove_step(&mut rng, vec![], None)?; // do a 2nd step let mut rng = rand::rngs::OsRng; // prepare the Decider prover & verifier params let start = Instant::now(); - let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone())?; println!("Decider preprocess, {:?}", start.elapsed()); // decider proof generation let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("Decider prove, {:?}", start.elapsed()); // decider proof verification @@ -425,9 +425,9 @@ pub mod tests { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider verify, {:?}", start.elapsed()); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/decider_circuits.rs b/folding-schemes/src/folding/nova/decider_circuits.rs index 23615cfc..95825475 100644 --- a/folding-schemes/src/folding/nova/decider_circuits.rs +++ b/folding-schemes/src/folding/nova/decider_circuits.rs @@ -179,11 +179,11 @@ pub mod tests { use crate::FoldingScheme; #[test] - fn test_decider_circuits() { + fn test_decider_circuits() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; type N = Nova< @@ -205,26 +205,27 @@ pub mod tests { Pedersen, false, >::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &prep_param).unwrap(); + let nova_params = N::preprocess(&mut rng, &prep_param)?; // generate a Nova instance and do a step of it - let mut nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap(); - nova.prove_step(&mut rng, vec![], None).unwrap(); + let mut nova = N::init(&nova_params, F_circuit, z_0.clone())?; + nova.prove_step(&mut rng, vec![], None)?; // verify the IVC let ivc_proof = nova.ivc_proof(); - N::verify(nova_params.1, ivc_proof).unwrap(); + N::verify(nova_params.1, ivc_proof)?; // load the DeciderCircuit 1 & 2 from the Nova instance let decider_circuit1 = - DeciderCircuit1::::try_from(nova.clone()).unwrap(); - let decider_circuit2 = DeciderCircuit2::::try_from(nova).unwrap(); + DeciderCircuit1::::try_from(nova.clone())?; + let decider_circuit2 = DeciderCircuit2::::try_from(nova)?; // generate the constraints of both circuits and check that are satisfied by the inputs let cs1 = ConstraintSystem::::new_ref(); - decider_circuit1.generate_constraints(cs1.clone()).unwrap(); - assert!(cs1.is_satisfied().unwrap()); + decider_circuit1.generate_constraints(cs1.clone())?; + assert!(cs1.is_satisfied()?); let cs2 = ConstraintSystem::::new_ref(); - decider_circuit2.generate_constraints(cs2.clone()).unwrap(); - assert!(cs2.is_satisfied().unwrap()); + decider_circuit2.generate_constraints(cs2.clone())?; + assert!(cs2.is_satisfied()?); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/decider_eth.rs b/folding-schemes/src/folding/nova/decider_eth.rs index 0963dcb0..e5c0fb69 100644 --- a/folding-schemes/src/folding/nova/decider_eth.rs +++ b/folding-schemes/src/folding/nova/decider_eth.rs @@ -323,7 +323,7 @@ pub mod tests { use crate::transcript::poseidon::poseidon_canonical_config; #[test] - fn test_decider() { + fn test_decider() -> Result<(), Error> { // use Nova as FoldingScheme type N = Nova< Projective, @@ -350,27 +350,27 @@ pub mod tests { let mut rng = rand::rngs::OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let preprocessor_param = PreprocessorParam::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &preprocessor_param).unwrap(); + let nova_params = N::preprocess(&mut rng, &preprocessor_param)?; let start = Instant::now(); - let mut nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap(); + let mut nova = N::init(&nova_params, F_circuit, z_0.clone())?; println!("Nova initialized, {:?}", start.elapsed()); // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params, nova.clone())?; let start = Instant::now(); - nova.prove_step(&mut rng, vec![], None).unwrap(); + nova.prove_step(&mut rng, vec![], None)?; println!("prove_step, {:?}", start.elapsed()); - nova.prove_step(&mut rng, vec![], None).unwrap(); // do a 2nd step + nova.prove_step(&mut rng, vec![], None)?; // do a 2nd step // decider proof generation let start = Instant::now(); - let proof = D::prove(rng, decider_pp, nova.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, nova.clone())?; println!("Decider prove, {:?}", start.elapsed()); // decider proof verification @@ -383,8 +383,7 @@ pub mod tests { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider verify, {:?}", start.elapsed()); @@ -397,16 +396,16 @@ pub mod tests { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } // Test to check the serialization and deserialization of diverse Decider related parameters. // This test is the same test as `test_decider` but it serializes values and then uses the // deserialized values to continue the checks. #[test] - fn test_decider_serialization() { + fn test_decider_serialization() -> Result<(), Error> { // use Nova as FoldingScheme type N = Nova< Projective, @@ -433,32 +432,29 @@ pub mod tests { let mut rng = rand::rngs::OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let preprocessor_param = PreprocessorParam::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &preprocessor_param).unwrap(); + let nova_params = N::preprocess(&mut rng, &preprocessor_param)?; let start = Instant::now(); - let nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap(); + let nova = N::init(&nova_params, F_circuit, z_0.clone())?; println!("Nova initialized, {:?}", start.elapsed()); // prepare the Decider prover & verifier params - let (decider_pp, decider_vp) = - D::preprocess(&mut rng, nova_params.clone(), nova.clone()).unwrap(); + let (decider_pp, decider_vp) = D::preprocess(&mut rng, nova_params.clone(), nova.clone())?; // serialize the Nova params. These params are the trusted setup of the commitment schemes used // (ie. KZG & Pedersen in this case) let mut nova_pp_serialized = vec![]; nova_params .0 - .serialize_compressed(&mut nova_pp_serialized) - .unwrap(); + .serialize_compressed(&mut nova_pp_serialized)?; let mut nova_vp_serialized = vec![]; nova_params .1 - .serialize_compressed(&mut nova_vp_serialized) - .unwrap(); + .serialize_compressed(&mut nova_vp_serialized)?; // deserialize the Nova params. This would be done by the client reading from a file let nova_pp_deserialized = NovaProverParams::< Projective, @@ -467,8 +463,7 @@ pub mod tests { Pedersen, >::deserialize_compressed( &mut nova_pp_serialized.as_slice() - ) - .unwrap(); + )?; let nova_vp_deserialized = as CommitmentScheme>::VerifierParams, as SNARK>::VerifyingKey, - >::deserialize_compressed(&mut decider_vp_serialized.as_slice()) - .unwrap(); + >::deserialize_compressed(&mut decider_vp_serialized.as_slice())?; let proof_deserialized = Proof::, Groth16>::deserialize_compressed( &mut proof_serialized.as_slice(), - ) - .unwrap(); + )?; // deserialize the public inputs from the single packet 'public_inputs_serialized' let mut reader = public_inputs_serialized.as_slice(); - let i_deserialized = Fr::deserialize_compressed(&mut reader).unwrap(); - let z_0_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); - let z_i_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); + let i_deserialized = Fr::deserialize_compressed(&mut reader)?; + let z_0_deserialized = Vec::::deserialize_compressed(&mut reader)?; + let z_i_deserialized = Vec::::deserialize_compressed(&mut reader)?; // decider proof verification using the deserialized data let verified = D::verify( @@ -561,8 +546,8 @@ pub mod tests { &nova.U_i.get_commitments(), &nova.u_i.get_commitments(), &proof_deserialized, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/decider_eth_circuit.rs b/folding-schemes/src/folding/nova/decider_eth_circuit.rs index 9735a3f1..745aecd9 100644 --- a/folding-schemes/src/folding/nova/decider_eth_circuit.rs +++ b/folding-schemes/src/folding/nova/decider_eth_circuit.rs @@ -227,11 +227,11 @@ pub mod tests { use crate::FoldingScheme; #[test] - fn test_decider_circuit() { + fn test_decider_circuit() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; type N = Nova< @@ -253,22 +253,23 @@ pub mod tests { Pedersen, false, >::new(poseidon_config, F_circuit); - let nova_params = N::preprocess(&mut rng, &prep_param).unwrap(); + let nova_params = N::preprocess(&mut rng, &prep_param)?; // generate a Nova instance and do a step of it - let mut nova = N::init(&nova_params, F_circuit, z_0.clone()).unwrap(); - nova.prove_step(&mut rng, vec![], None).unwrap(); + let mut nova = N::init(&nova_params, F_circuit, z_0.clone())?; + nova.prove_step(&mut rng, vec![], None)?; let ivc_proof = nova.ivc_proof(); - N::verify(nova_params.1, ivc_proof).unwrap(); + N::verify(nova_params.1, ivc_proof)?; // load the DeciderEthCircuit from the generated Nova instance - let decider_circuit = - DeciderEthCircuit::::try_from(nova).unwrap(); + let decider_circuit = DeciderEthCircuit::::try_from(nova)?; let cs = ConstraintSystem::::new_ref(); // generate the constraints and check that are satisfied by the inputs - decider_circuit.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + decider_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); + + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/mod.rs b/folding-schemes/src/folding/nova/mod.rs index 9592f041..53577a5c 100644 --- a/folding-schemes/src/folding/nova/mod.rs +++ b/folding-schemes/src/folding/nova/mod.rs @@ -879,7 +879,7 @@ where augmented_F_circuit.generate_constraints(cs.clone())?; #[cfg(test)] - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); let cs = cs.into_inner().ok_or(Error::NoInnerConstraintSystem)?; let (w_i1, x_i1) = extract_w_x::(&cs); @@ -1166,27 +1166,32 @@ pub mod tests { /// This test tests the Nova+CycleFold IVC, and by consequence it is also testing the /// AugmentedFCircuit #[test] - fn test_ivc() { + fn test_ivc() -> Result<(), Error> { let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; // run the test using Pedersen commitments on both sides of the curve cycle - test_ivc_opt::, Pedersen, false>( + let _ = test_ivc_opt::, Pedersen, false>( poseidon_config.clone(), F_circuit, 3, - ); + )?; - test_ivc_opt::, Pedersen, true>( + let _ = test_ivc_opt::, Pedersen, true>( poseidon_config.clone(), F_circuit, 3, - ); + )?; // run the test using KZG for the commitments on the main curve, and Pedersen for the // commitments on the secondary curve - test_ivc_opt::, Pedersen, false>(poseidon_config, F_circuit, 3); + let _ = test_ivc_opt::, Pedersen, false>( + poseidon_config, + F_circuit, + 3, + )?; + Ok(()) } // test_ivc allowing to choose the CommitmentSchemes @@ -1199,10 +1204,13 @@ pub mod tests { poseidon_config: PoseidonConfig, F_circuit: CubicFCircuit, num_steps: usize, - ) -> ( - Vec, - Nova, CS1, CS2, H>, - ) { + ) -> Result< + ( + Vec, + Nova, CS1, CS2, H>, + ), + Error, + > { let mut rng = ark_std::test_rng(); let prep_param = @@ -1223,8 +1231,7 @@ pub mod tests { CS1, CS2, H, - >::preprocess(&mut rng, &prep_param) - .unwrap(); + >::preprocess(&mut rng, &prep_param)?; let z_0 = vec![Fr::from(3_u32)]; let mut nova = @@ -1232,11 +1239,10 @@ pub mod tests { &nova_params, F_circuit, z_0.clone(), - ) - .unwrap(); + )?; for _ in 0..num_steps { - nova.prove_step(&mut rng, vec![], None).unwrap(); + nova.prove_step(&mut rng, vec![], None)?; } assert_eq!(Fr::from(num_steps as u32), nova.i); @@ -1244,20 +1250,17 @@ pub mod tests { let mut nova_pp_serialized = vec![]; nova_params .0 - .serialize_compressed(&mut nova_pp_serialized) - .unwrap(); + .serialize_compressed(&mut nova_pp_serialized)?; let mut nova_vp_serialized = vec![]; nova_params .1 - .serialize_compressed(&mut nova_vp_serialized) - .unwrap(); + .serialize_compressed(&mut nova_vp_serialized)?; // deserialize the Nova params let _nova_pp_deserialized = ProverParams::::deserialize_compressed( &mut nova_pp_serialized.as_slice(), - ) - .unwrap(); + )?; let nova_vp_deserialized = Nova::< Projective, GVar, @@ -1272,8 +1275,7 @@ pub mod tests { ark_serialize::Compress::Yes, ark_serialize::Validate::Yes, (), // fcircuit_params - ) - .unwrap(); + )?; let ivc_proof = nova.ivc_proof(); @@ -1295,15 +1297,13 @@ pub mod tests { > as FoldingScheme>>::IVCProof::deserialize_compressed( ivc_proof_serialized.as_slice() ) - .unwrap(); + ?; // verify the deserialized IVCProof with the deserialized VerifierParams Nova::, CS1, CS2, H>::verify( nova_vp_deserialized, // Nova's verifier params ivc_proof_deserialized, - ) - .unwrap(); - - (z_0, nova) + )?; + Ok((z_0, nova)) } } diff --git a/folding-schemes/src/folding/nova/nifs/mod.rs b/folding-schemes/src/folding/nova/nifs/mod.rs index ad3e4fa0..1f890acf 100644 --- a/folding-schemes/src/folding/nova/nifs/mod.rs +++ b/folding-schemes/src/folding/nova/nifs/mod.rs @@ -151,11 +151,11 @@ pub mod tests { /// so that their relation can be checked. pub(crate) fn test_nifs_opt< N: NIFSTrait, PoseidonSponge>, - >() -> (N::Witness, N::CommittedInstance) { + >() -> Result<(N::Witness, N::CommittedInstance), Error> { let r1cs: R1CS = get_test_r1cs(); let mut rng = ark_std::test_rng(); - let (pedersen_params, _) = Pedersen::::setup(&mut rng, r1cs.A.n_cols).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, r1cs.A.n_cols)?; let poseidon_config = poseidon_canonical_config::(); let mut transcript_p = PoseidonSponge::::new(&poseidon_config); @@ -166,7 +166,7 @@ pub mod tests { let z = get_test_z(3); let (w, x) = r1cs.split_z(&z); let mut W_i = N::new_witness(w.clone(), r1cs.A.n_rows, test_rng()); - let mut U_i = N::new_instance(&mut rng, &pedersen_params, &W_i, x, vec![]).unwrap(); + let mut U_i = N::new_instance(&mut rng, &pedersen_params, &W_i, x, vec![])?; let num_iters = 10; for i in 0..num_iters { @@ -174,7 +174,7 @@ pub mod tests { let incoming_instance_z = get_test_z(i + 4); let (w, x) = r1cs.split_z(&incoming_instance_z); let w_i = N::new_witness(w.clone(), r1cs.A.n_rows, test_rng()); - let u_i = N::new_instance(&mut rng, &pedersen_params, &w_i, x, vec![]).unwrap(); + let u_i = N::new_instance(&mut rng, &pedersen_params, &w_i, x, vec![])?; // NIFS.P let (folded_witness, _, proof, _) = N::prove( @@ -186,19 +186,18 @@ pub mod tests { &U_i, &w_i, &u_i, - ) - .unwrap(); + )?; // NIFS.V let (folded_committed_instance, _) = - N::verify(&mut transcript_v, pp_hash, &U_i, &u_i, &proof).unwrap(); + N::verify(&mut transcript_v, pp_hash, &U_i, &u_i, &proof)?; // set running_instance for next loop iteration W_i = folded_witness; U_i = folded_committed_instance; } - (W_i, U_i) + Ok((W_i, U_i)) } /// Test method used to test the different implementations of the NIFSGadgetTrait (ie. Nova, @@ -252,7 +251,9 @@ pub mod tests { /// test that checks the native CommittedInstance.to_sponge_{bytes,field_elements} /// vs the R1CS constraints version - pub(crate) fn test_committed_instance_to_sponge_preimage_opt(ci: N::CommittedInstance) + pub(crate) fn test_committed_instance_to_sponge_preimage_opt( + ci: N::CommittedInstance, + ) -> Result<(), Error> where N: NIFSTrait, PoseidonSponge>, NG: NIFSGadgetTrait< @@ -267,18 +268,21 @@ pub mod tests { let cs = ConstraintSystem::::new_ref(); - let ciVar = NG::CommittedInstanceVar::new_witness(cs.clone(), || Ok(ci.clone())).unwrap(); - let bytes_var = ciVar.to_sponge_bytes().unwrap(); - let field_elements_var = ciVar.to_sponge_field_elements().unwrap(); + let ciVar = NG::CommittedInstanceVar::new_witness(cs.clone(), || Ok(ci.clone()))?; + let bytes_var = ciVar.to_sponge_bytes()?; + let field_elements_var = ciVar.to_sponge_field_elements()?; - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(bytes_var.value().unwrap(), bytes); - assert_eq!(field_elements_var.value().unwrap(), field_elements); + assert_eq!(bytes_var.value()?, bytes); + assert_eq!(field_elements_var.value()?, field_elements); + Ok(()) } - pub(crate) fn test_committed_instance_hash_opt(ci: NG::CommittedInstance) + pub(crate) fn test_committed_instance_hash_opt( + ci: NG::CommittedInstance, + ) -> Result<(), Error> where N: NIFSTrait, PoseidonSponge>, NG: NIFSGadgetTrait< @@ -302,21 +306,20 @@ pub mod tests { let cs = ConstraintSystem::::new_ref(); - let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash)).unwrap(); - let iVar = FpVar::::new_witness(cs.clone(), || Ok(i)).unwrap(); - let z_0Var = Vec::>::new_witness(cs.clone(), || Ok(z_0.clone())).unwrap(); - let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone())).unwrap(); - let ciVar = NG::CommittedInstanceVar::new_witness(cs.clone(), || Ok(ci.clone())).unwrap(); + let pp_hashVar = FpVar::::new_witness(cs.clone(), || Ok(pp_hash))?; + let iVar = FpVar::::new_witness(cs.clone(), || Ok(i))?; + let z_0Var = Vec::>::new_witness(cs.clone(), || Ok(z_0.clone()))?; + let z_iVar = Vec::>::new_witness(cs.clone(), || Ok(z_i.clone()))?; + let ciVar = NG::CommittedInstanceVar::new_witness(cs.clone(), || Ok(ci.clone()))?; let sponge = PoseidonSpongeVar::::new(cs.clone(), &poseidon_config); // compute the CommittedInstance hash in-circuit - let (hVar, _) = ciVar - .hash(&sponge, &pp_hashVar, &iVar, &z_0Var, &z_iVar) - .unwrap(); - assert!(cs.is_satisfied().unwrap()); + let (hVar, _) = ciVar.hash(&sponge, &pp_hashVar, &iVar, &z_0Var, &z_iVar)?; + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(hVar.value().unwrap(), h); + assert_eq!(hVar.value()?, h); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/mova.rs b/folding-schemes/src/folding/nova/nifs/mova.rs index 1242d6da..d06e57e8 100644 --- a/folding-schemes/src/folding/nova/nifs/mova.rs +++ b/folding-schemes/src/folding/nova/nifs/mova.rs @@ -398,11 +398,12 @@ pub mod tests { use crate::folding::nova::nifs::tests::test_nifs_opt; #[test] - fn test_nifs_mova() { - let (W, U) = test_nifs_opt::, PoseidonSponge>>(); + fn test_nifs_mova() -> Result<(), Error> { + let (W, U) = test_nifs_opt::, PoseidonSponge>>()?; // check the last folded instance relation let r1cs = get_test_r1cs(); - r1cs.check_relation(&W, &U).unwrap(); + r1cs.check_relation(&W, &U)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/nova.rs b/folding-schemes/src/folding/nova/nifs/nova.rs index 40aedcbc..3e885f64 100644 --- a/folding-schemes/src/folding/nova/nifs/nova.rs +++ b/folding-schemes/src/folding/nova/nifs/nova.rs @@ -302,11 +302,12 @@ pub mod tests { use crate::folding::nova::nifs::tests::test_nifs_opt; #[test] - fn test_nifs_nova() { - let (W, U) = test_nifs_opt::, PoseidonSponge>>(); + fn test_nifs_nova() -> Result<(), Error> { + let (W, U) = test_nifs_opt::, PoseidonSponge>>()?; // check the last folded instance relation let r1cs = get_test_r1cs(); - r1cs.check_relation(&W, &U).unwrap(); + r1cs.check_relation(&W, &U)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/nova_circuits.rs b/folding-schemes/src/folding/nova/nifs/nova_circuits.rs index 58beae0a..a4757648 100644 --- a/folding-schemes/src/folding/nova/nifs/nova_circuits.rs +++ b/folding-schemes/src/folding/nova/nifs/nova_circuits.rs @@ -179,9 +179,10 @@ pub mod tests { test_nifs_gadget_opt, }, }; + use crate::Error; #[test] - fn test_nifs_gadget() { + fn test_nifs_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); // prepare the committed instances to test in-circuit let ci: Vec> = (0..2) @@ -198,14 +199,14 @@ pub mod tests { let (ci_out, ciVar_out) = test_nifs_gadget_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci, cmT) - .unwrap(); - assert_eq!(ciVar_out.u.value().unwrap(), ci_out.u); - assert_eq!(ciVar_out.x.value().unwrap(), ci_out.x); + >(ci, cmT)?; + assert_eq!(ciVar_out.u.value()?, ci_out.u); + assert_eq!(ciVar_out.x.value()?, ci_out.x); + Ok(()) } #[test] - fn test_committed_instance_to_sponge_preimage() { + fn test_committed_instance_to_sponge_preimage() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let ci = CommittedInstance:: { cmE: Projective::rand(&mut rng), @@ -217,11 +218,12 @@ pub mod tests { test_committed_instance_to_sponge_preimage_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci); + >(ci)?; + Ok(()) } #[test] - fn test_committed_instance_hash() { + fn test_committed_instance_hash() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let ci = CommittedInstance:: { cmE: Projective::rand(&mut rng), @@ -232,6 +234,7 @@ pub mod tests { test_committed_instance_hash_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci); + >(ci)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/ova.rs b/folding-schemes/src/folding/nova/nifs/ova.rs index a19a2a36..a0750d05 100644 --- a/folding-schemes/src/folding/nova/nifs/ova.rs +++ b/folding-schemes/src/folding/nova/nifs/ova.rs @@ -300,14 +300,14 @@ pub mod tests { } #[test] - fn test_nifs_ova() { - let (W, U) = test_nifs_opt::, PoseidonSponge>>(); + fn test_nifs_ova() -> Result<(), Error> { + let (W, U) = test_nifs_opt::, PoseidonSponge>>()?; // check the last folded instance relation let r1cs = get_test_r1cs(); let z: Vec = [&[U.u][..], &U.x, &W.w].concat(); - let e = compute_E::(&r1cs, &z, U.u).unwrap(); - r1cs.check_relation(&TestingWitness:: { e, w: W.w.clone() }, &U) - .unwrap(); + let e = compute_E::(&r1cs, &z, U.u)?; + r1cs.check_relation(&TestingWitness:: { e, w: W.w.clone() }, &U)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/ova_circuits.rs b/folding-schemes/src/folding/nova/nifs/ova_circuits.rs index abb2de5e..64f72d49 100644 --- a/folding-schemes/src/folding/nova/nifs/ova_circuits.rs +++ b/folding-schemes/src/folding/nova/nifs/ova_circuits.rs @@ -170,9 +170,10 @@ pub mod tests { test_nifs_gadget_opt, }, }; + use crate::Error; #[test] - fn test_nifs_gadget() { + fn test_nifs_gadget() -> Result<(), Error> { let mut rng = ark_std::test_rng(); // prepare the committed instances to test in-circuit let ci: Vec> = (0..2) @@ -187,14 +188,14 @@ pub mod tests { let (ci_out, ciVar_out) = test_nifs_gadget_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci, Fr::zero()) - .unwrap(); - assert_eq!(ciVar_out.u.value().unwrap(), ci_out.u); - assert_eq!(ciVar_out.x.value().unwrap(), ci_out.x); + >(ci, Fr::zero())?; + assert_eq!(ciVar_out.u.value()?, ci_out.u); + assert_eq!(ciVar_out.x.value()?, ci_out.x); + Ok(()) } #[test] - fn test_committed_instance_to_sponge_preimage() { + fn test_committed_instance_to_sponge_preimage() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let ci = CommittedInstance:: { u: Fr::rand(&mut rng), @@ -205,11 +206,12 @@ pub mod tests { test_committed_instance_to_sponge_preimage_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci); + >(ci)?; + Ok(()) } #[test] - fn test_committed_instance_hash() { + fn test_committed_instance_hash() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let ci = CommittedInstance:: { u: Fr::rand(&mut rng), @@ -219,6 +221,7 @@ pub mod tests { test_committed_instance_hash_opt::< NIFS, PoseidonSponge>, NIFSGadget, PoseidonSpongeVar>, - >(ci); + >(ci)?; + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/nifs/pointvsline.rs b/folding-schemes/src/folding/nova/nifs/pointvsline.rs index caa47ec3..dc914e3b 100644 --- a/folding-schemes/src/folding/nova/nifs/pointvsline.rs +++ b/folding-schemes/src/folding/nova/nifs/pointvsline.rs @@ -179,17 +179,18 @@ fn compute_l(r1: &[F], r1_sub_r2: &[F], x: F) -> Result, E #[cfg(test)] mod tests { use super::{compute_h, compute_l}; + use crate::Error; use ark_pallas::Fq; use ark_poly::{DenseMultilinearExtension, DenseUVPolynomial}; #[test] - fn test_compute_h() { + fn test_compute_h() -> Result<(), Error> { let mle = DenseMultilinearExtension::from_evaluations_slice(1, &[Fq::from(1), Fq::from(2)]); let r0 = [Fq::from(5)]; let r1 = [Fq::from(6)]; let r1_sub_r0: Vec = r1.iter().zip(&r0).map(|(&x, y)| x - y).collect(); - let result = compute_h(&mle, &r0, &r1_sub_r0).unwrap(); + let result = compute_h(&mle, &r0, &r1_sub_r0)?; assert_eq!( result, DenseUVPolynomial::from_coefficients_slice(&[Fq::from(6), Fq::from(1)]) @@ -200,7 +201,7 @@ mod tests { let r1 = [Fq::from(7)]; let r1_sub_r0: Vec = r1.iter().zip(&r0).map(|(&x, y)| x - y).collect(); - let result = compute_h(&mle, &r0, &r1_sub_r0).unwrap(); + let result = compute_h(&mle, &r0, &r1_sub_r0)?; assert_eq!( result, DenseUVPolynomial::from_coefficients_slice(&[Fq::from(5), Fq::from(3)]) @@ -214,7 +215,7 @@ mod tests { let r1 = [Fq::from(2), Fq::from(7)]; let r1_sub_r0: Vec = r1.iter().zip(&r0).map(|(&x, y)| x - y).collect(); - let result = compute_h(&mle, &r0, &r1_sub_r0).unwrap(); + let result = compute_h(&mle, &r0, &r1_sub_r0)?; assert_eq!( result, DenseUVPolynomial::from_coefficients_slice(&[Fq::from(14), Fq::from(3)]) @@ -236,11 +237,12 @@ mod tests { let r1 = [Fq::from(5), Fq::from(6), Fq::from(7)]; let r1_sub_r0: Vec = r1.iter().zip(&r0).map(|(&x, y)| x - y).collect(); - let result = compute_h(&mle, &r0, &r1_sub_r0).unwrap(); + let result = compute_h(&mle, &r0, &r1_sub_r0)?; assert_eq!( result, DenseUVPolynomial::from_coefficients_slice(&[Fq::from(18), Fq::from(28)]) ); + Ok(()) } #[test] @@ -264,7 +266,7 @@ mod tests { } #[test] - fn test_compute_l() { + fn test_compute_l() -> Result<(), Error> { // Test with simple non-zero values let r1 = vec![Fq::from(1), Fq::from(2), Fq::from(3)]; let r1_sub_r2 = vec![Fq::from(4), Fq::from(5), Fq::from(6)]; @@ -276,7 +278,8 @@ mod tests { Fq::from(3) + Fq::from(2) * Fq::from(6), ]; - let result = compute_l(&r1, &r1_sub_r2, x).unwrap(); + let result = compute_l(&r1, &r1_sub_r2, x)?; assert_eq!(result, expected); + Ok(()) } } diff --git a/folding-schemes/src/folding/nova/zk.rs b/folding-schemes/src/folding/nova/zk.rs index 656e71d7..b4aa63d8 100644 --- a/folding-schemes/src/folding/nova/zk.rs +++ b/folding-schemes/src/folding/nova/zk.rs @@ -232,17 +232,17 @@ pub mod tests { // Tests zk proof generation and verification for a valid nova IVC proof #[test] - fn test_zk_nova_ivc() { + fn test_zk_nova_ivc() -> Result<(), Error> { let mut rng = OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); - let (_, nova) = test_ivc_opt::, Pedersen, true>( - poseidon_config.clone(), - F_circuit, - 3, - ); + let F_circuit = CubicFCircuit::::new(())?; + let (_, nova) = test_ivc_opt::< + Pedersen, + Pedersen, + true, + >(poseidon_config.clone(), F_circuit, 3)?; - let proof = RandomizedIVCProof::new(&nova, &mut rng).unwrap(); + let proof = RandomizedIVCProof::new(&nova, &mut rng)?; let verify = RandomizedIVCProof::verify::< Pedersen, GVar2, @@ -258,20 +258,21 @@ pub mod tests { &proof, ); assert!(verify.is_ok()); + Ok(()) } #[test] - fn test_zk_nova_when_i_is_zero() { + fn test_zk_nova_when_i_is_zero() -> Result<(), Error> { let mut rng = OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); - let (_, nova) = test_ivc_opt::, Pedersen, true>( - poseidon_config.clone(), - F_circuit, - 0, - ); + let F_circuit = CubicFCircuit::::new(())?; + let (_, nova) = test_ivc_opt::< + Pedersen, + Pedersen, + true, + >(poseidon_config.clone(), F_circuit, 0)?; - let proof = RandomizedIVCProof::new(&nova, &mut rng).unwrap(); + let proof = RandomizedIVCProof::new(&nova, &mut rng)?; let verify = RandomizedIVCProof::verify::< Pedersen, GVar2, @@ -287,28 +288,28 @@ pub mod tests { &proof, ); assert!(verify.is_ok()); + Ok(()) } #[test] - fn test_zk_nova_verification_fails_with_wrong_running_instance() { + fn test_zk_nova_verification_fails_with_wrong_running_instance() -> Result<(), Error> { let mut rng = OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); - let (_, nova) = test_ivc_opt::, Pedersen, true>( - poseidon_config.clone(), - F_circuit, - 3, - ); + let F_circuit = CubicFCircuit::::new(())?; + let (_, nova) = test_ivc_opt::< + Pedersen, + Pedersen, + true, + >(poseidon_config.clone(), F_circuit, 3)?; let (_, sampled_committed_instance) = nova .r1cs - .sample_witness_instance::>(&nova.cs_pp, rng) - .unwrap(); + .sample_witness_instance::>(&nova.cs_pp, rng)?; // proof verification fails with incorrect running instance let mut nova_with_incorrect_running_instance = nova.clone(); nova_with_incorrect_running_instance.U_i = sampled_committed_instance; let incorrect_proof = - RandomizedIVCProof::new(&nova_with_incorrect_running_instance, &mut rng).unwrap(); + RandomizedIVCProof::new(&nova_with_incorrect_running_instance, &mut rng)?; let verify = RandomizedIVCProof::verify::< Pedersen, GVar2, @@ -324,28 +325,28 @@ pub mod tests { &incorrect_proof, ); assert!(verify.is_err()); + Ok(()) } #[test] - fn test_zk_nova_verification_fails_with_wrong_running_witness() { + fn test_zk_nova_verification_fails_with_wrong_running_witness() -> Result<(), Error> { let mut rng = OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); - let (_, nova) = test_ivc_opt::, Pedersen, true>( - poseidon_config.clone(), - F_circuit, - 3, - ); + let F_circuit = CubicFCircuit::::new(())?; + let (_, nova) = test_ivc_opt::< + Pedersen, + Pedersen, + true, + >(poseidon_config.clone(), F_circuit, 3)?; let (sampled_committed_witness, _) = nova .r1cs - .sample_witness_instance::>(&nova.cs_pp, rng) - .unwrap(); + .sample_witness_instance::>(&nova.cs_pp, rng)?; // proof generation fails with incorrect running witness let mut nova_with_incorrect_running_witness = nova.clone(); nova_with_incorrect_running_witness.W_i = sampled_committed_witness; let incorrect_proof = - RandomizedIVCProof::new(&nova_with_incorrect_running_witness, &mut rng).unwrap(); + RandomizedIVCProof::new(&nova_with_incorrect_running_witness, &mut rng)?; let verify = RandomizedIVCProof::verify::< Pedersen, GVar2, @@ -361,5 +362,6 @@ pub mod tests { &incorrect_proof, ); assert!(verify.is_err()); + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/circuits.rs b/folding-schemes/src/folding/protogalaxy/circuits.rs index 363f0cd7..f51721b6 100644 --- a/folding-schemes/src/folding/protogalaxy/circuits.rs +++ b/folding-schemes/src/folding/protogalaxy/circuits.rs @@ -473,22 +473,22 @@ where #[cfg(test)] mod tests { - use std::error::Error; use super::*; use crate::{ arith::r1cs::tests::get_test_r1cs, folding::protogalaxy::folding::{tests::prepare_inputs, Folding}, transcript::poseidon::poseidon_canonical_config, + Error, }; use ark_bn254::{Fr, G1Projective as Projective}; use ark_relations::r1cs::ConstraintSystem; #[test] - fn test_folding_gadget() -> Result<(), Box> { + fn test_folding_gadget() -> Result<(), Error> { let k = 7; - let (witness, instance, witnesses, instances) = prepare_inputs(k); + let (witness, instance, witnesses, instances) = prepare_inputs(k)?; let r1cs = get_test_r1cs::(); // init Prover & Verifier's transcript @@ -526,7 +526,6 @@ mod tests { assert_eq!(folded_instance.e, folded_instance_var.e.value()?); assert_eq!(folded_instance.x, folded_instance_var.x.value()?); assert!(cs.is_satisfied()?); - Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/decider_eth.rs b/folding-schemes/src/folding/protogalaxy/decider_eth.rs index a2836b43..7259ad72 100644 --- a/folding-schemes/src/folding/protogalaxy/decider_eth.rs +++ b/folding-schemes/src/folding/protogalaxy/decider_eth.rs @@ -255,9 +255,10 @@ pub mod tests { use crate::folding::traits::CommittedInstanceOps; use crate::frontend::utils::CubicFCircuit; use crate::transcript::poseidon::poseidon_canonical_config; + use crate::Error; #[test] - fn test_decider() { + fn test_decider() -> Result<(), Error> { // use ProtoGalaxy as FoldingScheme type PG = ProtoGalaxy< Projective, @@ -283,25 +284,25 @@ pub mod tests { let mut rng = rand::rngs::OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let preprocessor_param = (poseidon_config, F_circuit); - let protogalaxy_params = PG::preprocess(&mut rng, &preprocessor_param).unwrap(); + let protogalaxy_params = PG::preprocess(&mut rng, &preprocessor_param)?; let start = Instant::now(); - let mut protogalaxy = PG::init(&protogalaxy_params, F_circuit, z_0.clone()).unwrap(); + let mut protogalaxy = PG::init(&protogalaxy_params, F_circuit, z_0.clone())?; println!("ProtoGalaxy initialized, {:?}", start.elapsed()); - protogalaxy.prove_step(&mut rng, vec![], None).unwrap(); - protogalaxy.prove_step(&mut rng, vec![], None).unwrap(); // do a 2nd step + protogalaxy.prove_step(&mut rng, vec![], None)?; + protogalaxy.prove_step(&mut rng, vec![], None)?; // do a 2nd step // prepare the Decider prover & verifier params let (decider_pp, decider_vp) = - D::preprocess(&mut rng, protogalaxy_params, protogalaxy.clone()).unwrap(); + D::preprocess(&mut rng, protogalaxy_params, protogalaxy.clone())?; // decider proof generation let start = Instant::now(); - let proof = D::prove(rng, decider_pp, protogalaxy.clone()).unwrap(); + let proof = D::prove(rng, decider_pp, protogalaxy.clone())?; println!("Decider prove, {:?}", start.elapsed()); // decider proof verification @@ -314,8 +315,7 @@ pub mod tests { &protogalaxy.U_i.get_commitments(), &protogalaxy.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); println!("Decider verify, {:?}", start.elapsed()); @@ -328,16 +328,16 @@ pub mod tests { &protogalaxy.U_i.get_commitments(), &protogalaxy.u_i.get_commitments(), &proof, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } // Test to check the serialization and deserialization of diverse Decider related parameters. // This test is the same test as `test_decider` but it serializes values and then uses the // deserialized values to continue the checks. #[test] - fn test_decider_serialization() { + fn test_decider_serialization() -> Result<(), Error> { // use ProtoGalaxy as FoldingScheme type PG = ProtoGalaxy< Projective, @@ -363,34 +363,32 @@ pub mod tests { let mut rng = rand::rngs::OsRng; let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; let preprocessor_param = (poseidon_config, F_circuit); - let protogalaxy_params = PG::preprocess(&mut rng, &preprocessor_param).unwrap(); + let protogalaxy_params = PG::preprocess(&mut rng, &preprocessor_param)?; let start = Instant::now(); - let mut protogalaxy = PG::init(&protogalaxy_params, F_circuit, z_0.clone()).unwrap(); + let mut protogalaxy = PG::init(&protogalaxy_params, F_circuit, z_0.clone())?; println!("ProtoGalaxy initialized, {:?}", start.elapsed()); - protogalaxy.prove_step(&mut rng, vec![], None).unwrap(); - protogalaxy.prove_step(&mut rng, vec![], None).unwrap(); // do a 2nd step + protogalaxy.prove_step(&mut rng, vec![], None)?; + protogalaxy.prove_step(&mut rng, vec![], None)?; // do a 2nd step // prepare the Decider prover & verifier params let (decider_pp, decider_vp) = - D::preprocess(&mut rng, protogalaxy_params.clone(), protogalaxy.clone()).unwrap(); + D::preprocess(&mut rng, protogalaxy_params.clone(), protogalaxy.clone())?; // serialize the Nova params. These params are the trusted setup of the commitment schemes used // (ie. KZG & Pedersen in this case) let mut protogalaxy_pp_serialized = vec![]; protogalaxy_params .0 - .serialize_compressed(&mut protogalaxy_pp_serialized) - .unwrap(); + .serialize_compressed(&mut protogalaxy_pp_serialized)?; let mut protogalaxy_vp_serialized = vec![]; protogalaxy_params .1 - .serialize_compressed(&mut protogalaxy_vp_serialized) - .unwrap(); + .serialize_compressed(&mut protogalaxy_vp_serialized)?; // deserialize the Nova params. This would be done by the client reading from a file let protogalaxy_pp_deserialized = ProverParams::< Projective, @@ -399,8 +397,7 @@ pub mod tests { Pedersen, >::deserialize_compressed( &mut protogalaxy_pp_serialized.as_slice() - ) - .unwrap(); + )?; let protogalaxy_vp_deserialized = as CommitmentScheme>::VerifierParams, as SNARK>::VerifyingKey, - >::deserialize_compressed(&mut decider_vp_serialized.as_slice()) - .unwrap(); + >::deserialize_compressed(&mut decider_vp_serialized.as_slice())?; let proof_deserialized = Proof::, Groth16>::deserialize_compressed( &mut proof_serialized.as_slice(), - ) - .unwrap(); + )?; // deserialize the public inputs from the single packet 'public_inputs_serialized' let mut reader = public_inputs_serialized.as_slice(); - let i_deserialized = Fr::deserialize_compressed(&mut reader).unwrap(); - let z_0_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); - let z_i_deserialized = Vec::::deserialize_compressed(&mut reader).unwrap(); + let i_deserialized = Fr::deserialize_compressed(&mut reader)?; + let z_0_deserialized = Vec::::deserialize_compressed(&mut reader)?; + let z_i_deserialized = Vec::::deserialize_compressed(&mut reader)?; // decider proof verification using the deserialized data let verified = D::verify( @@ -496,8 +484,8 @@ pub mod tests { &protogalaxy.U_i.get_commitments(), &protogalaxy.u_i.get_commitments(), &proof_deserialized, - ) - .unwrap(); + )?; assert!(verified); + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/decider_eth_circuit.rs b/folding-schemes/src/folding/protogalaxy/decider_eth_circuit.rs index cf00f94d..6c71c57b 100644 --- a/folding-schemes/src/folding/protogalaxy/decider_eth_circuit.rs +++ b/folding-schemes/src/folding/protogalaxy/decider_eth_circuit.rs @@ -212,11 +212,11 @@ pub mod tests { use crate::FoldingScheme; #[test] - fn test_decider_circuit() { + fn test_decider_circuit() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let z_0 = vec![Fr::from(3_u32)]; type PG = ProtoGalaxy< @@ -228,24 +228,25 @@ pub mod tests { Pedersen, Pedersen, >; - let pg_params = PG::preprocess(&mut rng, &(poseidon_config, F_circuit)).unwrap(); + let pg_params = PG::preprocess(&mut rng, &(poseidon_config, F_circuit))?; // generate a Nova instance and do a step of it - let mut protogalaxy = PG::init(&pg_params, F_circuit, z_0.clone()).unwrap(); - protogalaxy.prove_step(&mut rng, vec![], None).unwrap(); + let mut protogalaxy = PG::init(&pg_params, F_circuit, z_0.clone())?; + protogalaxy.prove_step(&mut rng, vec![], None)?; let ivc_proof = protogalaxy.ivc_proof(); - PG::verify(pg_params.1, ivc_proof).unwrap(); + PG::verify(pg_params.1, ivc_proof)?; // load the DeciderEthCircuit from the generated Nova instance let decider_circuit = - DeciderEthCircuit::::try_from(protogalaxy).unwrap(); + DeciderEthCircuit::::try_from(protogalaxy)?; let cs = ConstraintSystem::::new_ref(); // generate the constraints and check that are satisfied by the inputs - decider_circuit.generate_constraints(cs.clone()).unwrap(); - assert!(cs.is_satisfied().unwrap()); + decider_circuit.generate_constraints(cs.clone())?; + assert!(cs.is_satisfied()?); dbg!(cs.num_constraints()); + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/folding.rs b/folding-schemes/src/folding/protogalaxy/folding.rs index fcdbd832..93eac4ea 100644 --- a/folding-schemes/src/folding/protogalaxy/folding.rs +++ b/folding-schemes/src/folding/protogalaxy/folding.rs @@ -436,17 +436,20 @@ pub mod tests { #[allow(clippy::type_complexity)] pub fn prepare_inputs( k: usize, - ) -> ( - Witness, - CommittedInstance, - Vec>, - Vec>, - ) { + ) -> Result< + ( + Witness, + CommittedInstance, + Vec>, + Vec>, + ), + Error, + > { let mut rng = ark_std::test_rng(); let (_, x, w) = get_test_z_split::(rng.gen::() as usize); - let (pedersen_params, _) = Pedersen::::setup(&mut rng, w.len()).unwrap(); + let (pedersen_params, _) = Pedersen::::setup(&mut rng, w.len())?; let t = log2(get_test_r1cs::().A.n_rows) as usize; @@ -457,7 +460,7 @@ pub mod tests { w, r_w: C::ScalarField::zero(), }; - let phi = Pedersen::::commit(&pedersen_params, &witness.w, &witness.r_w).unwrap(); + let phi = Pedersen::::commit(&pedersen_params, &witness.w, &witness.r_w)?; let instance = CommittedInstance:: { phi, betas: betas.clone(), @@ -474,8 +477,7 @@ pub mod tests { w: w_i, r_w: C::ScalarField::zero(), }; - let phi_i = - Pedersen::::commit(&pedersen_params, &witness_i.w, &witness_i.r_w).unwrap(); + let phi_i = Pedersen::::commit(&pedersen_params, &witness_i.w, &witness_i.r_w)?; let instance_i = CommittedInstance:: { phi: phi_i, betas: vec![], @@ -486,13 +488,13 @@ pub mod tests { instances.push(instance_i); } - (witness, instance, witnesses, instances) + Ok((witness, instance, witnesses, instances)) } #[test] - fn test_fold() { + fn test_fold() -> Result<(), Error> { let k = 7; - let (witness, instance, witnesses, instances) = prepare_inputs(k); + let (witness, instance, witnesses, instances) = prepare_inputs(k)?; let r1cs = get_test_r1cs::(); // init Prover & Verifier's transcript @@ -507,12 +509,11 @@ pub mod tests { &witness, &instances, &witnesses, - ) - .unwrap(); + )?; // verifier let folded_instance_v = - Folding::::verify(&mut transcript_v, &instance, &instances, proof).unwrap(); + Folding::::verify(&mut transcript_v, &instance, &instances, proof)?; // check that prover & verifier folded instances are the same values assert_eq!(folded_instance.phi, folded_instance_v.phi); @@ -521,12 +522,12 @@ pub mod tests { assert!(!folded_instance.e.is_zero()); // check that the folded instance satisfies the relation - r1cs.check_relation(&folded_witness, &folded_instance) - .unwrap(); + r1cs.check_relation(&folded_witness, &folded_instance)?; + Ok(()) } #[test] - fn test_fold_various_iterations() { + fn test_fold_various_iterations() -> Result<(), Error> { let r1cs = get_test_r1cs::(); // init Prover & Verifier's transcript @@ -534,14 +535,14 @@ pub mod tests { let mut transcript_p = PoseidonSponge::::new(&poseidon_config); let mut transcript_v = PoseidonSponge::::new(&poseidon_config); - let (mut running_witness, mut running_instance, _, _) = prepare_inputs(0); + let (mut running_witness, mut running_instance, _, _) = prepare_inputs(0)?; // fold k instances on each of num_iters iterations let k = 7; let num_iters = 10; for _ in 0..num_iters { // generate the instances to be fold - let (_, _, witnesses, instances) = prepare_inputs(k); + let (_, _, witnesses, instances) = prepare_inputs(k)?; let (folded_instance, folded_witness, proof, _) = Folding::::prove( &mut transcript_p, @@ -550,8 +551,7 @@ pub mod tests { &running_witness, &instances, &witnesses, - ) - .unwrap(); + )?; // verifier let folded_instance_v = Folding::::verify( @@ -559,8 +559,7 @@ pub mod tests { &running_instance, &instances, proof, - ) - .unwrap(); + )?; // check that prover & verifier folded instances are the same values assert_eq!(folded_instance, folded_instance_v); @@ -568,11 +567,11 @@ pub mod tests { assert!(!folded_instance.e.is_zero()); // check that the folded instance satisfies the relation - r1cs.check_relation(&folded_witness, &folded_instance) - .unwrap(); + r1cs.check_relation(&folded_witness, &folded_instance)?; running_witness = folded_witness; running_instance = folded_instance; } + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/mod.rs b/folding-schemes/src/folding/protogalaxy/mod.rs index faaf6895..090a3672 100644 --- a/folding-schemes/src/folding/protogalaxy/mod.rs +++ b/folding-schemes/src/folding/protogalaxy/mod.rs @@ -1045,7 +1045,7 @@ where augmented_F_circuit.generate_constraints(cs.clone())?; #[cfg(test)] - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); let cs = cs.into_inner().ok_or(Error::NoInnerConstraintSystem)?; let (w_i1, x_i1) = extract_w_x::(&cs); @@ -1251,50 +1251,49 @@ mod tests { /// This test tests the ProtoGalaxy+CycleFold IVC, and by consequence it is /// also testing the AugmentedFCircuit #[test] - fn test_ivc() { + fn test_ivc() -> Result<(), Error> { let poseidon_config = poseidon_canonical_config::(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; // run the test using Pedersen commitments on both sides of the curve cycle - test_ivc_opt::, Pedersen>( + let _ = test_ivc_opt::, Pedersen>( poseidon_config.clone(), F_circuit, - ); + )?; // run the test using KZG for the commitments on the main curve, and Pedersen for the // commitments on the secondary curve - test_ivc_opt::, Pedersen>(poseidon_config, F_circuit); + let _ = test_ivc_opt::, Pedersen>(poseidon_config, F_circuit)?; + Ok(()) } // test_ivc allowing to choose the CommitmentSchemes fn test_ivc_opt, CS2: CommitmentScheme>( poseidon_config: PoseidonConfig, F_circuit: CubicFCircuit, - ) { + ) -> Result<(), Error> { type PG = ProtoGalaxy, CS1, CS2>; - let params = - PG::::preprocess(&mut test_rng(), &(poseidon_config, F_circuit)).unwrap(); + let params = PG::::preprocess(&mut test_rng(), &(poseidon_config, F_circuit))?; let z_0 = vec![Fr::from(3_u32)]; - let mut protogalaxy = PG::init(¶ms, F_circuit, z_0.clone()).unwrap(); + let mut protogalaxy = PG::init(¶ms, F_circuit, z_0.clone())?; let num_steps: usize = 3; for _ in 0..num_steps { - protogalaxy - .prove_step(&mut test_rng(), vec![], None) - .unwrap(); + protogalaxy.prove_step(&mut test_rng(), vec![], None)?; } assert_eq!(Fr::from(num_steps as u32), protogalaxy.i); let ivc_proof = protogalaxy.ivc_proof(); - PG::::verify(params.1, ivc_proof).unwrap(); + PG::::verify(params.1, ivc_proof)?; + Ok(()) } #[ignore] #[test] - fn test_t_bounds() { + fn test_t_bounds() -> Result<(), Error> { let d = 2; let k = 1; @@ -1302,7 +1301,7 @@ mod tests { for state_len in [1, 10, 100] { for external_inputs_len in [1, 10, 100] { let dummy_circuit: DummyCircuit = - FCircuit::::new((state_len, external_inputs_len)).unwrap(); + FCircuit::::new((state_len, external_inputs_len))?; let costs = (1..32) .into_par_iter() @@ -1329,5 +1328,6 @@ mod tests { } } } + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/traits.rs b/folding-schemes/src/folding/protogalaxy/traits.rs index 2144611b..a4c8ee87 100644 --- a/folding-schemes/src/folding/protogalaxy/traits.rs +++ b/folding-schemes/src/folding/protogalaxy/traits.rs @@ -154,7 +154,7 @@ pub mod tests { /// test that checks the native CommittedInstance.to_sponge_{bytes,field_elements} /// vs the R1CS constraints version #[test] - pub fn test_committed_instance_to_sponge_preimage() { + pub fn test_committed_instance_to_sponge_preimage() -> Result<(), Error> { let mut rng = ark_std::test_rng(); let t = rng.gen::() as usize; @@ -173,15 +173,15 @@ pub mod tests { let cs = ConstraintSystem::::new_ref(); let ciVar = - CommittedInstanceVar::::new_witness(cs.clone(), || Ok(ci.clone())) - .unwrap(); - let bytes_var = ciVar.to_sponge_bytes().unwrap(); - let field_elements_var = ciVar.to_sponge_field_elements().unwrap(); + CommittedInstanceVar::::new_witness(cs.clone(), || Ok(ci.clone()))?; + let bytes_var = ciVar.to_sponge_bytes()?; + let field_elements_var = ciVar.to_sponge_field_elements()?; - assert!(cs.is_satisfied().unwrap()); + assert!(cs.is_satisfied()?); // check that the natively computed and in-circuit computed hashes match - assert_eq!(bytes_var.value().unwrap(), bytes); - assert_eq!(field_elements_var.value().unwrap(), field_elements); + assert_eq!(bytes_var.value()?, bytes); + assert_eq!(field_elements_var.value()?, field_elements); + Ok(()) } } diff --git a/folding-schemes/src/folding/protogalaxy/utils.rs b/folding-schemes/src/folding/protogalaxy/utils.rs index 596235ce..998216fd 100644 --- a/folding-schemes/src/folding/protogalaxy/utils.rs +++ b/folding-schemes/src/folding/protogalaxy/utils.rs @@ -107,7 +107,6 @@ pub fn pow_i_var(mut i: usize, betas: &[FpVar]) -> FpVar { #[cfg(test)] mod tests { - use std::error::Error; use ark_bn254::Fr; use ark_r1cs_std::{alloc::AllocVar, R1CSVar}; @@ -116,9 +115,10 @@ mod tests { use rand::Rng; use super::*; + use crate::Error; #[test] - fn test_exponential_powers() -> Result<(), Box> { + fn test_exponential_powers() -> Result<(), Error> { let rng = &mut test_rng(); for t in 1..10 { @@ -138,7 +138,7 @@ mod tests { } #[test] - fn test_all_powers() -> Result<(), Box> { + fn test_all_powers() -> Result<(), Error> { let rng = &mut test_rng(); for n in 1..10 { @@ -158,7 +158,7 @@ mod tests { } #[test] - fn test_betas_star() -> Result<(), Box> { + fn test_betas_star() -> Result<(), Error> { let rng = &mut test_rng(); for t in 1..10 { @@ -182,7 +182,7 @@ mod tests { } #[test] - fn test_pow_i() -> Result<(), Box> { + fn test_pow_i() -> Result<(), Error> { let rng = &mut test_rng(); for t in 1..10 { diff --git a/folding-schemes/src/frontend/mod.rs b/folding-schemes/src/frontend/mod.rs index 8570c818..688abc26 100644 --- a/folding-schemes/src/frontend/mod.rs +++ b/folding-schemes/src/frontend/mod.rs @@ -56,31 +56,33 @@ pub mod tests { use utils::{CubicFCircuit, CustomFCircuit, WrapperCircuit}; #[test] - fn test_testfcircuit() { + fn test_testfcircuit() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); - let F_circuit = CubicFCircuit::::new(()).unwrap(); + let F_circuit = CubicFCircuit::::new(())?; let wrapper_circuit = WrapperCircuit::> { FC: F_circuit, z_i: Some(vec![Fr::from(3_u32)]), z_i1: Some(vec![Fr::from(35_u32)]), }; - wrapper_circuit.generate_constraints(cs.clone()).unwrap(); + wrapper_circuit.generate_constraints(cs.clone())?; assert_eq!(cs.num_constraints(), 3); + Ok(()) } #[test] - fn test_customtestfcircuit() { + fn test_customtestfcircuit() -> Result<(), Error> { let cs = ConstraintSystem::::new_ref(); let n_constraints = 1000; - let custom_circuit = CustomFCircuit::::new(n_constraints).unwrap(); + let custom_circuit = CustomFCircuit::::new(n_constraints)?; let z_i = vec![Fr::from(5_u32)]; let wrapper_circuit = WrapperCircuit::> { FC: custom_circuit, z_i: Some(z_i.clone()), - z_i1: Some(custom_circuit.step_native(0, z_i, vec![]).unwrap()), + z_i1: Some(custom_circuit.step_native(0, z_i, vec![])?), }; - wrapper_circuit.generate_constraints(cs.clone()).unwrap(); + wrapper_circuit.generate_constraints(cs.clone())?; assert_eq!(cs.num_constraints(), n_constraints); + Ok(()) } } diff --git a/folding-schemes/src/transcript/poseidon.rs b/folding-schemes/src/transcript/poseidon.rs index b77cf7d2..72694f05 100644 --- a/folding-schemes/src/transcript/poseidon.rs +++ b/folding-schemes/src/transcript/poseidon.rs @@ -111,9 +111,6 @@ pub fn poseidon_canonical_config() -> PoseidonConfig { #[cfg(test)] pub mod tests { - use crate::folding::circuits::nonnative::affine::NonNativeAffineVar; - - use super::*; use ark_bn254::{constraints::GVar, g1::Config, Fq, Fr, G1Projective as G1}; use ark_ec::PrimeGroup; use ark_ff::UniformRand; @@ -123,9 +120,13 @@ pub mod tests { use ark_relations::r1cs::ConstraintSystem; use ark_std::test_rng; + use super::*; + use crate::folding::circuits::nonnative::affine::NonNativeAffineVar; + use crate::Error; + // Test with value taken from https://github.com/iden3/circomlibjs/blob/43cc582b100fc3459cf78d903a6f538e5d7f38ee/test/poseidon.js#L32 #[test] - fn check_against_circom_poseidon() { + fn check_against_circom_poseidon() -> Result<(), Error> { use ark_bn254::Fr; use ark_crypto_primitives::sponge::{poseidon::PoseidonSponge, CryptographicSponge}; use std::str::FromStr; @@ -145,10 +146,11 @@ pub mod tests { ) .unwrap() ); + Ok(()) } #[test] - fn test_transcript_and_transcriptvar_absorb_native_point() { + fn test_transcript_and_transcriptvar_absorb_native_point() -> Result<(), Error> { // use 'native' transcript let config = poseidon_canonical_config::(); let mut tr = PoseidonSponge::::new(&config); @@ -164,17 +166,17 @@ pub mod tests { let p_var = ProjectiveVar::>::new_witness( ConstraintSystem::::new_ref(), || Ok(p), - ) - .unwrap(); - tr_var.absorb_point(&p_var).unwrap(); - let c_var = tr_var.get_challenge().unwrap(); + )?; + tr_var.absorb_point(&p_var)?; + let c_var = tr_var.get_challenge()?; // assert that native & gadget transcripts return the same challenge - assert_eq!(c, c_var.value().unwrap()); + assert_eq!(c, c_var.value()?); + Ok(()) } #[test] - fn test_transcript_and_transcriptvar_absorb_nonnative_point() { + fn test_transcript_and_transcriptvar_absorb_nonnative_point() -> Result<(), Error> { // use 'native' transcript let config = poseidon_canonical_config::(); let mut tr = PoseidonSponge::::new(&config); @@ -188,17 +190,17 @@ pub mod tests { let cs = ConstraintSystem::::new_ref(); let mut tr_var = PoseidonSpongeVar::::new(cs.clone(), &config); let p_var = - NonNativeAffineVar::::new_witness(ConstraintSystem::::new_ref(), || Ok(p)) - .unwrap(); - tr_var.absorb_nonnative(&p_var).unwrap(); - let c_var = tr_var.get_challenge().unwrap(); + NonNativeAffineVar::::new_witness(ConstraintSystem::::new_ref(), || Ok(p))?; + tr_var.absorb_nonnative(&p_var)?; + let c_var = tr_var.get_challenge()?; // assert that native & gadget transcripts return the same challenge - assert_eq!(c, c_var.value().unwrap()); + assert_eq!(c, c_var.value()?); + Ok(()) } #[test] - fn test_transcript_and_transcriptvar_get_challenge() { + fn test_transcript_and_transcriptvar_get_challenge() -> Result<(), Error> { // use 'native' transcript let config = poseidon_canonical_config::(); let mut tr = PoseidonSponge::::new(&config); @@ -208,16 +210,17 @@ pub mod tests { // use 'gadget' transcript let cs = ConstraintSystem::::new_ref(); let mut tr_var = PoseidonSpongeVar::::new(cs.clone(), &config); - let v = FpVar::::new_witness(cs.clone(), || Ok(Fr::from(42_u32))).unwrap(); - tr_var.absorb(&v).unwrap(); - let c_var = tr_var.get_challenge().unwrap(); + let v = FpVar::::new_witness(cs.clone(), || Ok(Fr::from(42_u32)))?; + tr_var.absorb(&v)?; + let c_var = tr_var.get_challenge()?; // assert that native & gadget transcripts return the same challenge - assert_eq!(c, c_var.value().unwrap()); + assert_eq!(c, c_var.value()?); + Ok(()) } #[test] - fn test_transcript_and_transcriptvar_nbits() { + fn test_transcript_and_transcriptvar_nbits() -> Result<(), Error> { let nbits = crate::constants::NOVA_N_BITS_RO; // use 'native' transcript @@ -231,36 +234,31 @@ pub mod tests { // use 'gadget' transcript let cs = ConstraintSystem::::new_ref(); let mut tr_var = PoseidonSpongeVar::::new(cs.clone(), &config); - let v = FpVar::::new_witness(cs.clone(), || Ok(Fq::from(42_u32))).unwrap(); - tr_var.absorb(&v).unwrap(); + let v = FpVar::::new_witness(cs.clone(), || Ok(Fq::from(42_u32)))?; + tr_var.absorb(&v)?; // get challenge from circuit transcript - let c_var = tr_var.get_challenge_nbits(nbits).unwrap(); + let c_var = tr_var.get_challenge_nbits(nbits)?; let P = G1::generator(); - let PVar = GVar::new_witness(cs.clone(), || Ok(P)).unwrap(); + let PVar = GVar::new_witness(cs.clone(), || Ok(P))?; // multiply point P by the challenge in different formats, to ensure that we get the same // result natively and in-circuit // native c*P - let c_Fr = Fr::from_bigint(BigInteger::from_bits_le(&c_bits)).unwrap(); + let c_Fr = Fr::from_bigint(BigInteger::from_bits_le(&c_bits)).ok_or(Error::OutOfBounds)?; let cP_native = P * c_Fr; // native c*P using mul_bits_be (notice the .rev to convert the LE to BE) let cP_native_bits = P.mul_bits_be(c_bits.into_iter().rev()); // in-circuit c*P using scalar_mul_le - let cPVar = PVar.scalar_mul_le(c_var.iter()).unwrap(); + let cPVar = PVar.scalar_mul_le(c_var.iter())?; // check that they are equal - assert_eq!( - cP_native.into_affine(), - cPVar.value().unwrap().into_affine() - ); - assert_eq!( - cP_native_bits.into_affine(), - cPVar.value().unwrap().into_affine() - ); + assert_eq!(cP_native.into_affine(), cPVar.value()?.into_affine()); + assert_eq!(cP_native_bits.into_affine(), cPVar.value()?.into_affine()); + Ok(()) } } diff --git a/folding-schemes/src/utils/vec.rs b/folding-schemes/src/utils/vec.rs index 5cf692ee..7bcbe92c 100644 --- a/folding-schemes/src/utils/vec.rs +++ b/folding-schemes/src/utils/vec.rs @@ -200,7 +200,7 @@ pub mod tests { // test mat_vec_mul & mat_vec_mul_sparse #[test] - fn test_mat_vec_mul() { + fn test_mat_vec_mul() -> Result<(), Error> { let A = to_F_matrix::(vec![ vec![0, 1, 0, 0, 0, 0], vec![0, 0, 0, 1, 0, 0], @@ -209,12 +209,9 @@ pub mod tests { ]) .to_dense(); let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]); + assert_eq!(mat_vec_mul_dense(&A, &z)?, to_F_vec(vec![3, 9, 30, 35])); assert_eq!( - mat_vec_mul_dense(&A, &z).unwrap(), - to_F_vec(vec![3, 9, 30, 35]) - ); - assert_eq!( - mat_vec_mul(&dense_matrix_to_sparse(A), &z).unwrap(), + mat_vec_mul(&dense_matrix_to_sparse(A), &z)?, to_F_vec(vec![3, 9, 30, 35]) ); @@ -222,29 +219,26 @@ pub mod tests { let v = to_F_vec(vec![19, 55, 50, 3]); assert_eq!( - mat_vec_mul_dense(&A.to_dense(), &v).unwrap(), + mat_vec_mul_dense(&A.to_dense(), &v)?, to_F_vec(vec![418, 1158, 979]) ); - assert_eq!(mat_vec_mul(&A, &v).unwrap(), to_F_vec(vec![418, 1158, 979])); + assert_eq!(mat_vec_mul(&A, &v)?, to_F_vec(vec![418, 1158, 979])); + Ok(()) } #[test] - fn test_hadamard_product() { + fn test_hadamard_product() -> Result<(), Error> { let a = to_F_vec::(vec![1, 2, 3, 4, 5, 6]); let b = to_F_vec(vec![7, 8, 9, 10, 11, 12]); - assert_eq!( - hadamard(&a, &b).unwrap(), - to_F_vec(vec![7, 16, 27, 40, 55, 72]) - ); + assert_eq!(hadamard(&a, &b)?, to_F_vec(vec![7, 16, 27, 40, 55, 72])); + Ok(()) } #[test] - fn test_vec_add() { + fn test_vec_add() -> Result<(), Error> { let a: Vec = to_F_vec::(vec![1, 2, 3, 4, 5, 6]); let b: Vec = to_F_vec(vec![7, 8, 9, 10, 11, 12]); - assert_eq!( - vec_add(&a, &b).unwrap(), - to_F_vec(vec![8, 10, 12, 14, 16, 18]) - ); + assert_eq!(vec_add(&a, &b)?, to_F_vec(vec![8, 10, 12, 14, 16, 18])); + Ok(()) } } diff --git a/solidity-verifiers/Cargo.toml b/solidity-verifiers/Cargo.toml index 2fff3162..2228d5cd 100644 --- a/solidity-verifiers/Cargo.toml +++ b/solidity-verifiers/Cargo.toml @@ -24,7 +24,7 @@ ark-relations = { version = "^0.5.0", default-features = false } ark-r1cs-std = { version = "^0.5.0", default-features = false, features = ["parallel"] } ark-grumpkin = { version = "^0.5.0", default-features = false } folding-schemes = { path = "../folding-schemes/", features=["light-test"]} -frontends = { path = "../frontends/"} +experimental-frontends = { path = "../experimental-frontends/"} noname = { git = "https://github.com/dmpierre/noname" } [features]