Skip to content

Commit

Permalink
Move the experimental frontends into a separate crate, so that when n…
Browse files Browse the repository at this point in the history
…ot using them they don't take several minutes to compile (and indirect dependencies).

This saves several minutes (and MBs of data) on compilation time both
when running tests in this repo, but also when using the sonobe lib as a
dependency in external repos.
  • Loading branch information
arnaucube committed Oct 14, 2024
1 parent cb1b8e3 commit 62286dc
Show file tree
Hide file tree
Showing 32 changed files with 121 additions and 86 deletions.
6 changes: 3 additions & 3 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: ./folding-schemes/src/frontend/circom/test_folder/compile.sh
run: ./frontends/src/circom/test_folder/compile.sh
- name: Execute compile.sh to generate .json from noir
run: ./folding-schemes/src/frontend/noir/test_folder/compile.sh
run: ./frontends/src/noir/test_folder/compile.sh
- name: Run tests
uses: actions-rs/cargo@v1
with:
Expand Down Expand Up @@ -127,7 +127,7 @@ 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: ./folding-schemes/src/frontend/circom/test_folder/compile.sh
run: ./frontends/src/circom/test_folder/compile.sh
- name: Execute compile.sh to generate .json from noir
run: ./folding-schemes/src/frontend/noir/test_folder/compile.sh
- name: Run examples tests
Expand Down
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Cargo.lock

# Circom generated files
folding-schemes/src/frontend/circom/test_folder/*_js/
frontends/src/circom/test_folder/*_js/
*.r1cs
*.sym

# Noir generated files
folding-schemes/src/frontend/noir/test_folder/*/target/*
frontends/src/noir/test_folder/*/target/*

# generated contracts at test time
# generated contracts data
solidity-verifiers/generated
examples/*.sol
examples/*.calldata
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
members = [
"folding-schemes",
"solidity-verifiers",
"cli"
"cli",
"frontends"
]
resolver = "2"

Expand Down
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ Work in progress:

- [ProtoGalaxy: Efficient ProtoStar-style folding of multiple instances](https://eprint.iacr.org/2023/1106.pdf), Liam Eagen, Ariel Gabizon. 2023

## Available frontends

Available frontends to define the folded circuit:

- [arkworks](https://github.com/arkworks-rs), arkworks contributors
- [Circom](https://github.com/iden3/circom), iden3, 0Kims Association
- [Noname](https://github.com/zksecurity/noname), zkSecurity

## Usage

### Build & test
Expand Down
3 changes: 2 additions & 1 deletion examples/circom_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ use folding_schemes::{
decider_eth::{prepare_calldata, Decider as DeciderEth},
Nova, PreprocessorParam,
},
frontend::{circom::CircomFCircuit, FCircuit},
frontend::FCircuit,
transcript::poseidon::poseidon_canonical_config,
Decider, FoldingScheme,
};
use frontends::circom::CircomFCircuit;
use solidity_verifiers::{
evm::{compile_solidity, Evm},
utils::get_function_selector_for_nova_cyclefold_verifier,
Expand Down
6 changes: 2 additions & 4 deletions examples/noir_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ use folding_schemes::{
decider_eth::{prepare_calldata, Decider as DeciderEth},
Nova, PreprocessorParam,
},
frontend::{
noir::{load_noir_circuit, NoirFCircuit},
FCircuit,
},
frontend::FCircuit,
transcript::poseidon::poseidon_canonical_config,
Decider, FoldingScheme,
};
use frontends::noir::{load_noir_circuit, NoirFCircuit};
use std::{env, time::Instant};

use solidity_verifiers::{
Expand Down
3 changes: 2 additions & 1 deletion examples/noname_full_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ use folding_schemes::{
decider_eth::{prepare_calldata, Decider as DeciderEth},
Nova, PreprocessorParam,
},
frontend::{noname::NonameFCircuit, FCircuit},
frontend::FCircuit,
transcript::poseidon::poseidon_canonical_config,
Decider, FoldingScheme,
};
use frontends::noname::NonameFCircuit;
use std::time::Instant;

use solidity_verifiers::{
Expand Down
16 changes: 4 additions & 12 deletions folding-schemes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,20 @@ ark-ff = { version = "^0.4.0", default-features = false, features = ["parallel",
ark-poly = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-std = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-crypto-primitives = { version = "^0.4.0", default-features = false, features = ["r1cs", "sponge", "crh", "parallel"] }
ark-grumpkin = { version = "0.4.0", default-features = false }
ark-poly-commit = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-relations = { version = "^0.4.0", default-features = false }
# this is patched at the workspace level
# ark-r1cs-std is patched at the workspace level
ark-r1cs-std = { version = "0.4.0", default-features = false, features = ["parallel"] }
ark-snark = { version = "^0.4.0", default-features = false }
ark-serialize = { version = "^0.4.0", default-features = false }
ark-circom = { git = "https://github.com/arnaucube/circom-compat", default-features = false }
ark-groth16 = { version = "^0.4.0", default-features = false, features = ["parallel"]}
ark-bn254 = { version = "^0.4.0", default-features = false }
ark-grumpkin = { version = "0.4.0", default-features = false }
thiserror = "1.0"
rayon = "1"
num-bigint = "0.4"
num-integer = "0.1"
color-eyre = "=0.6.2"
sha3 = "0.10"
ark-noname = { git = "https://github.com/dmpierre/ark-noname", branch = "feat/sonobe-integration" }
noname = { git = "https://github.com/dmpierre/noname" }
serde_json = "1.0.85" # to (de)serialize JSON
serde = "1.0.203"
acvm = { git = "https://github.com/noir-lang/noir", rev="2b4853e", default-features = false }
noir_arkworks_backend = { package="arkworks_backend", git = "https://github.com/dmpierre/arkworks_backend", branch = "feat/sonobe-integration" }
log = "0.4"

# tmp import for espresso's sumcheck
Expand All @@ -46,6 +38,7 @@ ark-grumpkin = {version="0.4.0", features=["r1cs"]}
ark-mnt4-298 = {version="0.4.0", features=["r1cs"]}
ark-mnt6-298 = {version="0.4.0", features=["r1cs"]}
rand = "0.8.5"
num-bigint = {version = "0.4", features = ["rand"]}
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
tracing-subscriber = { version = "0.2" }

Expand All @@ -55,9 +48,8 @@ tracing-subscriber = { version = "0.2" }
getrandom = { version = "0.2", features = ["js"] }

[features]
default = ["ark-circom/default", "parallel"]
default = ["parallel"]
parallel = []
wasm = ["ark-circom/wasm"]
light-test = []


Expand Down
4 changes: 0 additions & 4 deletions folding-schemes/src/frontend/circom/test_folder/compile.sh

This file was deleted.

3 changes: 0 additions & 3 deletions folding-schemes/src/frontend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use ark_r1cs_std::fields::fp::FpVar;
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
use ark_std::fmt::Debug;

pub mod circom;
pub mod noir;
pub mod noname;
pub mod utils;

/// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie.
Expand Down
4 changes: 2 additions & 2 deletions folding-schemes/src/frontend/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ impl<F: PrimeField> FCircuit<F> for CustomFCircuit<F> {
/// than the one done in the `AugmentedFCircuit`, but without adding all the extra constraints
/// of the AugmentedF circuit logic, in order to run lighter tests when we're not interested in
/// the the AugmentedF logic but in the wrapping of the circuits.
#[cfg(test)]
// #[cfg(test)]
pub struct WrapperCircuit<F: PrimeField, FC: FCircuit<F>> {
pub FC: FC, // F circuit
pub z_i: Option<Vec<F>>,
pub z_i1: Option<Vec<F>>,
}

#[cfg(test)]
// #[cfg(test)]
impl<F, FC> ark_relations::r1cs::ConstraintSynthesizer<F> for WrapperCircuit<F, FC>
where
F: PrimeField,
Expand Down
41 changes: 41 additions & 0 deletions frontends/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "frontends"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ark-ec = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-ff = { version = "^0.4.0", default-features = false, features = ["parallel", "asm"] }
ark-poly = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-std = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-relations = { version = "^0.4.0", default-features = false }
# this is patched at the workspace level
ark-r1cs-std = { version = "0.4.0", default-features = false, features = ["parallel"] }
ark-serialize = { version = "^0.4.0", default-features = false }
ark-circom = { git = "https://github.com/arnaucube/circom-compat", default-features = false }
num-bigint = "0.4"
color-eyre = "=0.6.2"
ark-noname = { git = "https://github.com/dmpierre/ark-noname", branch = "feat/sonobe-integration" }
noname = { git = "https://github.com/dmpierre/noname" }
serde_json = "1.0.85" # to (de)serialize JSON
acvm = { git = "https://github.com/noir-lang/noir", rev="2b4853e", default-features = false }
noir_arkworks_backend = { package="arkworks_backend", git = "https://github.com/dmpierre/arkworks_backend", branch = "feat/sonobe-integration" }
folding-schemes = { path = "../folding-schemes/"}

# tmp import for espresso's sumcheck
espresso_subroutines = {git="https://github.com/EspressoSystems/hyperplonk", package="subroutines"}

[dev-dependencies]
ark-bn254 = {version="0.4.0", features=["r1cs"]}

# This allows the crate to be built when targeting WASM.
# See more at: https://docs.rs/getrandom/#webassembly-support
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
getrandom = { version = "0.2", features = ["js"] }

[features]
default = ["ark-circom/default", "parallel"]
parallel = []
wasm = ["ark-circom/wasm"]
14 changes: 14 additions & 0 deletions frontends/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frontends

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).
- [Circom](https://github.com/iden3/circom), iden3, 0Kims Association (supported v2.1.9)
- [Noir](https://github.com/noir-lang/noir), Aztec
- [Noname](https://github.com/zksecurity/noname), zkSecurity


More details about frontends: https://privacy-scaling-explorations.github.io/sonobe-docs/usage/frontend.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use crate::frontend::FCircuit;
use crate::frontend::FpVar::Var;
use crate::utils::PathOrBin;
use crate::Error;
use ark_circom::circom::{CircomCircuit, R1CS as CircomR1CS};
use ark_ff::PrimeField;
use ark_r1cs_std::alloc::AllocVar;
use ark_r1cs_std::fields::fp::FpVar;
use ark_r1cs_std::fields::fp::FpVar::Var;
use ark_r1cs_std::R1CSVar;
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
use ark_std::fmt::Debug;
use folding_schemes::{frontend::FCircuit, utils::PathOrBin, Error};
use num_bigint::BigInt;
use std::rc::Rc;
use std::{fmt, usize};
Expand Down Expand Up @@ -187,10 +185,10 @@ impl<F: PrimeField> FCircuit<F> for CircomFCircuit<F> {
}

impl<F: PrimeField> CircomFCircuit<F> {
fn fpvars_to_bigints(&self, fpVars: &[FpVar<F>]) -> Result<Vec<BigInt>, SynthesisError> {
fn fpvars_to_bigints(&self, fpvars: &[FpVar<F>]) -> Result<Vec<BigInt>, SynthesisError> {
let mut input_values = Vec::new();
// converts each FpVar to PrimeField value, then to num_bigint::BigInt.
for fp_var in fpVars.iter() {
for fp_var in fpvars.iter() {
// extracts the PrimeField value from FpVar.
let primefield_value = fp_var.value()?;
// converts the PrimeField value to num_bigint::BigInt.
Expand All @@ -213,9 +211,9 @@ pub mod tests {
// Tests the step_native function of CircomFCircuit.
#[test]
fn test_circom_step_native() {
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs");
let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs");
let wasm_path =
PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");
PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");

let circom_fcircuit =
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
Expand All @@ -228,9 +226,9 @@ pub mod tests {
// Tests the generate_step_constraints function of CircomFCircuit.
#[test]
fn test_circom_step_constraints() {
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs");
let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs");
let wasm_path =
PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");
PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");

let circom_fcircuit =
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
Expand All @@ -249,16 +247,16 @@ pub mod tests {
// Tests the WrapperCircuit with CircomFCircuit.
#[test]
fn test_wrapper_circomtofcircuit() {
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs");
let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs");
let wasm_path =
PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");
PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");

let circom_fcircuit =
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // 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 = crate::frontend::utils::WrapperCircuit {
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()),
Expand All @@ -275,10 +273,9 @@ pub mod tests {

#[test]
fn test_circom_external_inputs() {
let r1cs_path =
PathBuf::from("./src/frontend/circom/test_folder/with_external_inputs.r1cs");
let r1cs_path = PathBuf::from("./src/circom/test_folder/with_external_inputs.r1cs");
let wasm_path = PathBuf::from(
"./src/frontend/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm",
"./src/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm",
);
let circom_fcircuit =
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 2)).unwrap(); // state_len:1, external_inputs_len:2
Expand Down Expand Up @@ -320,10 +317,9 @@ pub mod tests {

#[test]
fn test_circom_no_external_inputs() {
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/no_external_inputs.r1cs");
let wasm_path = PathBuf::from(
"./src/frontend/circom/test_folder/no_external_inputs_js/no_external_inputs.wasm",
);
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::<Fr>::new((r1cs_path.into(), wasm_path.into(), 3, 0)).unwrap();
let cs = ConstraintSystem::<Fr>::new_ref();
Expand Down Expand Up @@ -353,9 +349,9 @@ pub mod tests {

#[test]
fn test_custom_code() {
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs");
let r1cs_path = PathBuf::from("./src/circom/test_folder/cubic_circuit.r1cs");
let wasm_path =
PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");
PathBuf::from("./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");

let mut circom_fcircuit =
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
Expand All @@ -367,7 +363,7 @@ pub mod tests {

// Allocates z_i1 by using step_native function.
let z_i = vec![Fr::from(3_u32)];
let wrapper_circuit = crate::frontend::utils::WrapperCircuit {
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()),
Expand Down
4 changes: 4 additions & 0 deletions frontends/src/circom/test_folder/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
circom ./frontends/src/circom/test_folder/cubic_circuit.circom --r1cs --sym --wasm --prime bn128 --output ./frontends/src/circom/test_folder/
circom ./frontends/src/circom/test_folder/with_external_inputs.circom --r1cs --sym --wasm --prime bn128 --output ./frontends/src/circom/test_folder/
circom ./frontends/src/circom/test_folder/no_external_inputs.circom --r1cs --sym --wasm --prime bn128 --output ./frontends/src/circom/test_folder/
Loading

0 comments on commit 62286dc

Please sign in to comment.