Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate tests to use ? instead of unwrap & experimental-frontends renaming #176

Merged
merged 5 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ jobs:
curl -sSfL https://github.com/ethereum/solidity/releases/download/v0.8.4/solc-static-linux -o /usr/local/bin/solc
chmod +x /usr/local/bin/solc
- name: Execute compile.sh to generate .r1cs and .wasm from .circom
run: ./frontends/src/circom/test_folder/compile.sh
run: ./experimental-frontends/src/circom/test_folder/compile.sh
- name: Execute compile.sh to generate .json from noir
run: ./frontends/src/noir/test_folder/compile.sh
run: ./experimental-frontends/src/noir/test_folder/compile.sh
- name: Run tests
uses: actions-rs/cargo@v1
with:
Expand Down Expand Up @@ -95,11 +95,11 @@ jobs:
default: true
- name: Add target
run: rustup target add ${{ matrix.target }}
- name: Wasm-compat frontends build
- name: Wasm-compat experimental-frontends build
uses: actions-rs/cargo@v1
with:
command: build
args: -p frontends --no-default-features --target ${{ matrix.target }} --features "wasm, parallel"
args: -p experimental-frontends --no-default-features --target ${{ matrix.target }} --features "wasm, parallel"
- name: Wasm-compat folding-schemes build
uses: actions-rs/cargo@v1
with:
Expand Down Expand Up @@ -132,9 +132,9 @@ jobs:
curl -sSfL https://github.com/ethereum/solidity/releases/download/v0.8.4/solc-static-linux -o /usr/local/bin/solc
chmod +x /usr/local/bin/solc
- name: Execute compile.sh to generate .r1cs and .wasm from .circom
run: ./frontends/src/circom/test_folder/compile.sh
run: ./experimental-frontends/src/circom/test_folder/compile.sh
- name: Execute compile.sh to generate .json from noir
run: ./frontends/src/noir/test_folder/compile.sh
run: ./experimental-frontends/src/noir/test_folder/compile.sh
- name: Run examples tests
run: cargo test --examples
- name: Run examples
Expand All @@ -154,7 +154,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: bench
args: --no-run
args: -p folding-schemes --no-run

fmt:
if: github.event.pull_request.draft == false
Expand All @@ -180,10 +180,10 @@ jobs:
feature_set: [basic, wasm]
include:
- feature_set: basic
features: --features default,light-test
# We only want to test `frontends` package with `wasm` feature.
features: --features default
# We only want to test `experimental-frontends` package with `wasm` feature.
- feature_set: wasm
features: -p frontends --features wasm,parallel --target wasm32-unknown-unknown
features: -p experimental-frontends --features wasm,parallel --target wasm32-unknown-unknown
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ members = [
"folding-schemes",
"solidity-verifiers",
"cli",
"frontends"
"experimental-frontends"
]
resolver = "2"
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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.

Expand All @@ -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.
Expand Down Expand Up @@ -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).

Expand Down
6 changes: 4 additions & 2 deletions benches/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ where
));
group.significance_level(0.1).sample_size(10);
group.bench_function("prove_step", |b| {
b.iter(|| black_box(fs.clone()).prove_step(rng, vec![], None).unwrap())
b.iter(|| -> Result<_, _> { black_box(fs.clone()).prove_step(rng, vec![], None) })
});

// verify the IVCProof
let ivc_proof = fs.ivc_proof();
group.bench_function("verify", |b| {
b.iter(|| FS::verify(black_box(fs_params.1.clone()), black_box(ivc_proof.clone())).unwrap())
b.iter(|| -> Result<_, _> {
FS::verify(black_box(fs_params.1.clone()), black_box(ivc_proof.clone()))
})
});
group.finish();
Ok(())
Expand Down
40 changes: 18 additions & 22 deletions examples/circom_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -28,17 +29,16 @@ 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,
verifiers::nova_cyclefold::get_decider_template_for_cyclefold_decider,
NovaCycleFoldVerifierKey,
};

fn main() {
fn main() -> Result<(), Error> {
// set the initial state
let z_0 = vec![Fr::from(3_u32)];

Expand All @@ -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::<Fr>::new(f_circuit_params).unwrap();
let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params)?;

pub type N =
Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>, false>;
Expand All @@ -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());
}

Expand All @@ -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(
Expand All @@ -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);

Expand All @@ -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()));
Expand All @@ -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(())
}
37 changes: 16 additions & 21 deletions examples/external_inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,32 +128,29 @@ pub mod tests {

// test to check that the ExternalInputsCircuit computes the same values inside and outside the circuit
#[test]
fn test_f_circuit() {
fn test_f_circuit() -> Result<(), Error> {
let poseidon_config = poseidon_canonical_config::<Fr>();

let cs = ConstraintSystem::<Fr>::new_ref();

let circuit = ExternalInputsCircuit::<Fr>::new(poseidon_config).unwrap();
let circuit = ExternalInputsCircuit::<Fr>::new(poseidon_config)?;
let z_i = vec![Fr::from(1_u32)];
let external_inputs = vec![Fr::from(3_u32)];

let z_i1 = circuit
.step_native(0, z_i.clone(), external_inputs.clone())
.unwrap();
let z_i1 = circuit.step_native(0, z_i.clone(), external_inputs.clone())?;

let z_iVar = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(z_i)).unwrap();
let external_inputsVar =
Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(external_inputs)).unwrap();
let z_iVar = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(z_i))?;
let external_inputsVar = Vec::<FpVar<Fr>>::new_witness(cs.clone(), || Ok(external_inputs))?;

let computed_z_i1Var = circuit
.generate_step_constraints(cs.clone(), 0, z_iVar, external_inputsVar)
.unwrap();
assert_eq!(computed_z_i1Var.value().unwrap(), z_i1);
let computed_z_i1Var =
circuit.generate_step_constraints(cs.clone(), 0, z_iVar, external_inputsVar)?;
assert_eq!(computed_z_i1Var.value()?, z_i1);
Ok(())
}
}

/// cargo run --release --example external_inputs
fn main() {
fn main() -> Result<(), Error> {
let num_steps = 5;
let initial_state = vec![Fr::from(1_u32)];

Expand All @@ -168,7 +165,7 @@ fn main() {
assert_eq!(external_inputs.len(), num_steps);

let poseidon_config = poseidon_canonical_config::<Fr>();
let F_circuit = ExternalInputsCircuit::<Fr>::new(poseidon_config.clone()).unwrap();
let F_circuit = ExternalInputsCircuit::<Fr>::new(poseidon_config.clone())?;

/// 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`
Expand All @@ -188,17 +185,15 @@ fn main() {

println!("Prepare Nova's ProverParams & VerifierParams");
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)?;

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, external_inputs_at_step) in external_inputs.iter().enumerate() {
let start = Instant::now();
folding_scheme
.prove_step(rng, external_inputs_at_step.clone(), None)
.unwrap();
folding_scheme.prove_step(rng, external_inputs_at_step.clone(), None)?;
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}
println!(
Expand All @@ -212,6 +207,6 @@ fn main() {
N::verify(
nova_params.1, // Nova's verifier params
ivc_proof,
)
.unwrap();
)?;
Ok(())
}
Loading
Loading