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). (#168)

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 authored Oct 19, 2024
1 parent cb1b8e3 commit 234600b
Show file tree
Hide file tree
Showing 34 changed files with 161 additions and 130 deletions.
5 changes: 3 additions & 2 deletions .github/scripts/wasm-target-test-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ cp "${GIT_ROOT}/rust-toolchain" .
rustup target add wasm32-unknown-unknown wasm32-wasi

# add dependencies
cargo add --path "${GIT_ROOT}/folding-schemes" --features wasm, parallel
cargo add --path "${GIT_ROOT}/frontends" --features wasm, parallel
cargo add --path "${GIT_ROOT}/folding-schemes" --features parallel
cargo add getrandom --features js --target wasm32-unknown-unknown

# test build for wasm32-* targets
Expand All @@ -26,4 +27,4 @@ cargo build --release --target wasm32-wasi

# delete test project
cd ../
rm -rf foobar
rm -rf foobar
21 changes: 13 additions & 8 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 @@ -95,11 +95,16 @@ jobs:
default: true
- name: Add target
run: rustup target add ${{ matrix.target }}
- name: Wasm-compat build
- name: Wasm-compat frontends build
uses: actions-rs/cargo@v1
with:
command: build
args: -p folding-schemes --no-default-features --target ${{ matrix.target }} --features "wasm, parallel"
args: -p frontends --no-default-features --target ${{ matrix.target }} --features "wasm, parallel"
- name: Wasm-compat folding-schemes build
uses: actions-rs/cargo@v1
with:
command: build
args: -p folding-schemes --no-default-features --target ${{ matrix.target }} --features "default,light-test"
- name: Run wasm-compat script
run: |
chmod +x .github/scripts/wasm-target-test-build.sh
Expand Down Expand Up @@ -127,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: ./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 examples tests
run: cargo test --examples
- name: Run examples
Expand Down Expand Up @@ -160,9 +165,9 @@ jobs:
include:
- feature_set: basic
features: --features default,light-test
# We only want to test `folding-schemes` package with `wasm` feature.
# We only want to test `frontends` package with `wasm` feature.
- feature_set: wasm
features: -p folding-schemes --features wasm,parallel --target wasm32-unknown-unknown
features: -p frontends --features wasm,parallel --target wasm32-unknown-unknown
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
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
61 changes: 26 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Sonobe is conceived as an exploratory effort with the aim to push forward the pr
<br>

> **Warning**: experimental code, do not use in production.<br>
> The code has not been audited. Several optimizations are also pending. Our focus so far has been on implementing the Nova and CycleFold schemes and achieving onchain (EVM) verification.
> The code has not been audited. Several optimizations are also pending. Our focus so far has been on implementing the Nova, HyperNova and ProtoGalaxy schemes, all with the CycleFold approach; and achieving the onchain (in EVM) verification of the folding proofs.

## Schemes implemented

Expand All @@ -27,52 +28,42 @@ 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:
## Frontends

- [arkworks](https://github.com/arkworks-rs), arkworks contributors
- [Circom](https://github.com/iden3/circom), iden3, 0Kims Association
- [Noname](https://github.com/zksecurity/noname), zkSecurity
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.

## Usage
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.

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.

### Build & test
You can test the library for both, WASM-targets and regular ones.
#### Regular targets
Tier-S targets allow the user to simply run `cargo test` or `cargo build` without needing to worry about anything.
**We strongly recommend to test using the `light-test` feature.** Which will omit the computationally intensive parts of the tests such as
generating a SNARK of 4~5M constraints to then verify it.

#### WASM targets
In order to build the lib for WASM-targets, use the following command:
`cargo build -p folding-schemes --no-default-features --target wasm32-unknown-unknown --features "wasm, parallel"`.
Where the target can be any WASM one and the `parallel` feature is optional.
## Usage
Import the library:
```toml
[dependencies]
folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes"}
```

**Trying to build for a WASM-target without the `wasm` feature or viceversa will end up in a compilation error.**
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.

### Docs
Available features:
- `parallel` enables some parallelization optimizations available in the crate. It is enabled by default.
- `light-test` disables part of the DeciderEthCircuit various circuits (which accounts for ~9M constraints) so that the tests involving those circuits can run faster. Do not use it outside tests. This feature is disabled by default.

Detailed usage and design documentation can be found at [Sonobe docs](https://privacy-scaling-explorations.github.io/sonobe-docs/).
Examples of usage can be found at the [examples](https://github.com/privacy-scaling-explorations/sonobe/tree/main/examples) directory.

### WASM-compatibility & features
For WASM (in browser usage), details can be found at [sonobe-docs/usage/wasm](https://privacy-scaling-explorations.github.io/sonobe-docs/usage/wasm.html).

The `sonobe/folding-schemes` crate is the only workspace member that supports WASM-target compilation. But, to have it working, `getrandom/js` needs
to be imported in the `Cargo.toml` of the crate that uses it as dependency.
```toml
[dependencies]
folding-schemes = { version = "0.1.0", default-features = false, features = ["parallel", "wasm"] }
getrandom = { version = "0.2", features = ["js"] }
```
See more details about `getrandom` here: https://docs.rs/getrandom/latest/getrandom/#webassembly-support.

Also, notice that:
- `wasm` feature **IS MANDATORY** if compilation to WASM targets is desired.
- `parallel` feature enables some parallelization optimizations available in the crate.
- `light-test` feature runs the computationally-intensive parts of the testing such as the full proof generation for the Eth-decider circuit
of Nova which is approximately 4-5M constraints. **This feature only matters when it comes to running Sonobe's tests.**
### Docs
Details on usage of the library, together with design documentation, can be found at the [Sonobe docs](https://privacy-scaling-explorations.github.io/sonobe-docs/).

### Folding Schemes introduction
## Folding Schemes introduction

Folding schemes efficiently achieve incrementally verifiable computation (IVC), where the prover recursively proves the correct execution of the incremental computations.
Once the IVC iterations are completed, the IVC proof is compressed into the Decider proof, a zkSNARK proof which proves that applying $n$ times the $F$ function (the circuit being folded) to the initial state ($z_0$) results in the final state ($z_n$).
Expand Down
9 changes: 4 additions & 5 deletions 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 Expand Up @@ -54,11 +55,9 @@ fn main() {
];

// initialize the Circom circuit
let r1cs_path = PathBuf::from(
"./folding-schemes/src/frontend/circom/test_folder/with_external_inputs.r1cs",
);
let r1cs_path = PathBuf::from("./frontends/src/circom/test_folder/with_external_inputs.r1cs");
let wasm_path = PathBuf::from(
"./folding-schemes/src/frontend/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm",
"./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);
Expand Down
8 changes: 3 additions & 5 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 All @@ -44,7 +42,7 @@ fn main() {
let cur_path = env::current_dir().unwrap();

let circuit_path = format!(
"{}/folding-schemes/src/frontend/noir/test_folder/test_mimc/target/test_mimc.json",
"{}/frontends/src/noir/test_folder/test_mimc/target/test_mimc.json",
cur_path.to_str().unwrap()
);

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
6 changes: 3 additions & 3 deletions folding-schemes/src/folding/nova/zk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
/// final proof generation to a server.
/// * Use-case-2: at the end of all the IVC folding steps (after n iterations of nova.prove_step),
/// to 'blind' the IVC proof so then it can be sent to a server that will generate the final
/// decider snark proof.
/// decider SNARK proof.
/// --> In this one, the user could externalize the Decider final proof generation to a
/// server.
/// * Use-case-3: the user does not care about the Decider (final compressed SNARK proof), and
/// wants to generate a zk-proof of the IVC state to an IVC verifier (without any SNARK proof
/// involved). Note that this proof will be much bigger and expensive to verify than a Decider
/// SNARK proof.
/// involved). In this use-case, the zk is only added at the last IVCProof. Note that this proof
/// will be much bigger and expensive to verify than a Decider SNARK proof.
///
/// The current implementation covers the Use-case-3.
/// Use-case-1 can be achieved directly by a simpler version of the zk IVC scheme skipping steps
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
2 changes: 0 additions & 2 deletions folding-schemes/src/frontend/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,12 @@ 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)]
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)]
impl<F, FC> ark_relations::r1cs::ConstraintSynthesizer<F> for WrapperCircuit<F, FC>
where
F: PrimeField,
Expand Down
33 changes: 33 additions & 0 deletions frontends/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "frontends"
version = "0.1.0"
edition = "2021"

[dependencies]
ark-ff = { version = "^0.4.0", default-features = false, features = ["parallel", "asm"] }
ark-std = { version = "^0.4.0", default-features = false, features = ["parallel"] }
ark-relations = { version = "^0.4.0", default-features = false }
# ark-r1cs-std 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"
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/"}

[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"]
Loading

0 comments on commit 234600b

Please sign in to comment.