mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-09 07:21:28 +01:00
Move the experimental frontends into a separate crate, so that when not 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.
This commit is contained in:
5
.github/scripts/wasm-target-test-build.sh
vendored
5
.github/scripts/wasm-target-test-build.sh
vendored
@@ -15,7 +15,8 @@ cp "${GIT_ROOT}/rust-toolchain" .
|
|||||||
rustup target add wasm32-unknown-unknown wasm32-wasi
|
rustup target add wasm32-unknown-unknown wasm32-wasi
|
||||||
|
|
||||||
# add dependencies
|
# 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
|
cargo add getrandom --features js --target wasm32-unknown-unknown
|
||||||
|
|
||||||
# test build for wasm32-* targets
|
# test build for wasm32-* targets
|
||||||
@@ -26,4 +27,4 @@ cargo build --release --target wasm32-wasi
|
|||||||
|
|
||||||
# delete test project
|
# delete test project
|
||||||
cd ../
|
cd ../
|
||||||
rm -rf foobar
|
rm -rf foobar
|
||||||
|
|||||||
21
.github/workflows/ci.yml
vendored
21
.github/workflows/ci.yml
vendored
@@ -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
|
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
|
chmod +x /usr/local/bin/solc
|
||||||
- name: Execute compile.sh to generate .r1cs and .wasm from .circom
|
- 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
|
- 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
|
- name: Run tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
@@ -95,11 +95,16 @@ jobs:
|
|||||||
default: true
|
default: true
|
||||||
- name: Add target
|
- name: Add target
|
||||||
run: rustup target add ${{ matrix.target }}
|
run: rustup target add ${{ matrix.target }}
|
||||||
- name: Wasm-compat build
|
- name: Wasm-compat frontends build
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
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
|
- name: Run wasm-compat script
|
||||||
run: |
|
run: |
|
||||||
chmod +x .github/scripts/wasm-target-test-build.sh
|
chmod +x .github/scripts/wasm-target-test-build.sh
|
||||||
@@ -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
|
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
|
chmod +x /usr/local/bin/solc
|
||||||
- name: Execute compile.sh to generate .r1cs and .wasm from .circom
|
- 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
|
- 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
|
- name: Run examples tests
|
||||||
run: cargo test --examples
|
run: cargo test --examples
|
||||||
- name: Run examples
|
- name: Run examples
|
||||||
@@ -160,9 +165,9 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- feature_set: basic
|
- feature_set: basic
|
||||||
features: --features default,light-test
|
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
|
- 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:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions-rs/toolchain@v1
|
- uses: actions-rs/toolchain@v1
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -2,14 +2,14 @@
|
|||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
# Circom generated files
|
# Circom generated files
|
||||||
folding-schemes/src/frontend/circom/test_folder/*_js/
|
frontends/src/circom/test_folder/*_js/
|
||||||
*.r1cs
|
*.r1cs
|
||||||
*.sym
|
*.sym
|
||||||
|
|
||||||
# Noir generated files
|
# 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
|
solidity-verifiers/generated
|
||||||
examples/*.sol
|
examples/*.sol
|
||||||
examples/*.calldata
|
examples/*.calldata
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
members = [
|
members = [
|
||||||
"folding-schemes",
|
"folding-schemes",
|
||||||
"solidity-verifiers",
|
"solidity-verifiers",
|
||||||
"cli"
|
"cli",
|
||||||
|
"frontends"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|||||||
67
README.md
67
README.md
@@ -13,7 +13,8 @@ Sonobe is conceived as an exploratory effort with the aim to push forward the pr
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
> **Warning**: experimental code, do not use in production.<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
|
## Schemes implemented
|
||||||
|
|
||||||
@@ -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
|
- [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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
- [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
|
## Usage
|
||||||
|
Import the library:
|
||||||
### 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.
|
|
||||||
|
|
||||||
**Trying to build for a WASM-target without the `wasm` feature or viceversa will end up in a compilation error.**
|
|
||||||
|
|
||||||
### Docs
|
|
||||||
|
|
||||||
Detailed usage and design documentation can be found at [Sonobe docs](https://privacy-scaling-explorations.github.io/sonobe-docs/).
|
|
||||||
|
|
||||||
### WASM-compatibility & features
|
|
||||||
|
|
||||||
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
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
folding-schemes = { version = "0.1.0", default-features = false, features = ["parallel", "wasm"] }
|
folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes"}
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
|
||||||
```
|
```
|
||||||
See more details about `getrandom` here: https://docs.rs/getrandom/latest/getrandom/#webassembly-support.
|
|
||||||
|
|
||||||
Also, notice that:
|
Available packages:
|
||||||
- `wasm` feature **IS MANDATORY** if compilation to WASM targets is desired.
|
- `folding-schemes`: main crate, contains the different scheme implementations, together with commitment schemes, frontend trait, arithmetization, transcript, etc.
|
||||||
- `parallel` feature enables some parallelization optimizations available in the crate.
|
- `solidity-verifiers`: contains the templating logic to output the verifier contracts for the DeciderEth proofs. Currently only supports Nova+CycleFold DeciderEth proofs.
|
||||||
- `light-test` feature runs the computationally-intensive parts of the testing such as the full proof generation for the Eth-decider circuit
|
- `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.
|
||||||
of Nova which is approximately 4-5M constraints. **This feature only matters when it comes to running Sonobe's tests.**
|
|
||||||
|
|
||||||
### Folding Schemes introduction
|
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.
|
||||||
|
|
||||||
|
Examples of usage can be found at the [examples](https://github.com/privacy-scaling-explorations/sonobe/tree/main/examples) directory.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
|
||||||
|
### 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 efficiently achieve incrementally verifiable computation (IVC), where the prover recursively proves the correct execution of the incremental computations.
|
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$).
|
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$).
|
||||||
|
|||||||
@@ -23,10 +23,11 @@ use folding_schemes::{
|
|||||||
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
||||||
Nova, PreprocessorParam,
|
Nova, PreprocessorParam,
|
||||||
},
|
},
|
||||||
frontend::{circom::CircomFCircuit, FCircuit},
|
frontend::FCircuit,
|
||||||
transcript::poseidon::poseidon_canonical_config,
|
transcript::poseidon::poseidon_canonical_config,
|
||||||
Decider, FoldingScheme,
|
Decider, FoldingScheme,
|
||||||
};
|
};
|
||||||
|
use frontends::circom::CircomFCircuit;
|
||||||
use solidity_verifiers::{
|
use solidity_verifiers::{
|
||||||
evm::{compile_solidity, Evm},
|
evm::{compile_solidity, Evm},
|
||||||
utils::get_function_selector_for_nova_cyclefold_verifier,
|
utils::get_function_selector_for_nova_cyclefold_verifier,
|
||||||
@@ -54,11 +55,9 @@ fn main() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// initialize the Circom circuit
|
// initialize the Circom circuit
|
||||||
let r1cs_path = PathBuf::from(
|
let r1cs_path = PathBuf::from("./frontends/src/circom/test_folder/with_external_inputs.r1cs");
|
||||||
"./folding-schemes/src/frontend/circom/test_folder/with_external_inputs.r1cs",
|
|
||||||
);
|
|
||||||
let wasm_path = PathBuf::from(
|
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);
|
let f_circuit_params = (r1cs_path.into(), wasm_path.into(), 1, 2);
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ use folding_schemes::{
|
|||||||
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
||||||
Nova, PreprocessorParam,
|
Nova, PreprocessorParam,
|
||||||
},
|
},
|
||||||
frontend::{
|
frontend::FCircuit,
|
||||||
noir::{load_noir_circuit, NoirFCircuit},
|
|
||||||
FCircuit,
|
|
||||||
},
|
|
||||||
transcript::poseidon::poseidon_canonical_config,
|
transcript::poseidon::poseidon_canonical_config,
|
||||||
Decider, FoldingScheme,
|
Decider, FoldingScheme,
|
||||||
};
|
};
|
||||||
|
use frontends::noir::{load_noir_circuit, NoirFCircuit};
|
||||||
use std::{env, time::Instant};
|
use std::{env, time::Instant};
|
||||||
|
|
||||||
use solidity_verifiers::{
|
use solidity_verifiers::{
|
||||||
@@ -44,7 +42,7 @@ fn main() {
|
|||||||
let cur_path = env::current_dir().unwrap();
|
let cur_path = env::current_dir().unwrap();
|
||||||
|
|
||||||
let circuit_path = format!(
|
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()
|
cur_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ use folding_schemes::{
|
|||||||
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
||||||
Nova, PreprocessorParam,
|
Nova, PreprocessorParam,
|
||||||
},
|
},
|
||||||
frontend::{noname::NonameFCircuit, FCircuit},
|
frontend::FCircuit,
|
||||||
transcript::poseidon::poseidon_canonical_config,
|
transcript::poseidon::poseidon_canonical_config,
|
||||||
Decider, FoldingScheme,
|
Decider, FoldingScheme,
|
||||||
};
|
};
|
||||||
|
use frontends::noname::NonameFCircuit;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use solidity_verifiers::{
|
use solidity_verifiers::{
|
||||||
|
|||||||
@@ -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-poly = { version = "^0.4.0", default-features = false, features = ["parallel"] }
|
||||||
ark-std = { 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-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-poly-commit = { version = "^0.4.0", default-features = false, features = ["parallel"] }
|
||||||
ark-relations = { version = "^0.4.0", default-features = false }
|
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-r1cs-std = { version = "0.4.0", default-features = false, features = ["parallel"] }
|
||||||
ark-snark = { version = "^0.4.0", default-features = false }
|
ark-snark = { version = "^0.4.0", default-features = false }
|
||||||
ark-serialize = { 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-groth16 = { version = "^0.4.0", default-features = false, features = ["parallel"]}
|
||||||
ark-bn254 = { version = "^0.4.0", default-features = false }
|
ark-bn254 = { version = "^0.4.0", default-features = false }
|
||||||
|
ark-grumpkin = { version = "0.4.0", default-features = false }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
rayon = "1"
|
rayon = "1"
|
||||||
num-bigint = "0.4"
|
num-bigint = "0.4"
|
||||||
num-integer = "0.1"
|
num-integer = "0.1"
|
||||||
color-eyre = "=0.6.2"
|
|
||||||
sha3 = "0.10"
|
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"
|
log = "0.4"
|
||||||
|
|
||||||
# tmp import for espresso's sumcheck
|
# tmp import for espresso's sumcheck
|
||||||
@@ -46,6 +38,7 @@ ark-grumpkin = {version="0.4.0", features=["r1cs"]}
|
|||||||
ark-mnt4-298 = {version="0.4.0", features=["r1cs"]}
|
ark-mnt4-298 = {version="0.4.0", features=["r1cs"]}
|
||||||
ark-mnt6-298 = {version="0.4.0", features=["r1cs"]}
|
ark-mnt6-298 = {version="0.4.0", features=["r1cs"]}
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
num-bigint = {version = "0.4", features = ["rand"]}
|
||||||
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
|
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
|
||||||
tracing-subscriber = { version = "0.2" }
|
tracing-subscriber = { version = "0.2" }
|
||||||
|
|
||||||
@@ -55,9 +48,8 @@ tracing-subscriber = { version = "0.2" }
|
|||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ark-circom/default", "parallel"]
|
default = ["parallel"]
|
||||||
parallel = []
|
parallel = []
|
||||||
wasm = ["ark-circom/wasm"]
|
|
||||||
light-test = []
|
light-test = []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
/// final proof generation to a server.
|
/// 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),
|
/// * 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
|
/// 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
|
/// --> In this one, the user could externalize the Decider final proof generation to a
|
||||||
/// server.
|
/// server.
|
||||||
/// * Use-case-3: the user does not care about the Decider (final compressed SNARK proof), and
|
/// * 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
|
/// 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
|
/// involved). In this use-case, the zk is only added at the last IVCProof. Note that this proof
|
||||||
/// SNARK proof.
|
/// will be much bigger and expensive to verify than a Decider SNARK proof.
|
||||||
///
|
///
|
||||||
/// The current implementation covers the Use-case-3.
|
/// 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
|
/// Use-case-1 can be achieved directly by a simpler version of the zk IVC scheme skipping steps
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
circom ./folding-schemes/src/frontend/circom/test_folder/cubic_circuit.circom --r1cs --sym --wasm --prime bn128 --output ./folding-schemes/src/frontend/circom/test_folder/
|
|
||||||
circom ./folding-schemes/src/frontend/circom/test_folder/with_external_inputs.circom --r1cs --sym --wasm --prime bn128 --output ./folding-schemes/src/frontend/circom/test_folder/
|
|
||||||
circom ./folding-schemes/src/frontend/circom/test_folder/no_external_inputs.circom --r1cs --sym --wasm --prime bn128 --output ./folding-schemes/src/frontend/circom/test_folder/
|
|
||||||
@@ -4,9 +4,6 @@ use ark_r1cs_std::fields::fp::FpVar;
|
|||||||
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
|
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
|
||||||
use ark_std::fmt::Debug;
|
use ark_std::fmt::Debug;
|
||||||
|
|
||||||
pub mod circom;
|
|
||||||
pub mod noir;
|
|
||||||
pub mod noname;
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
/// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie.
|
/// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie.
|
||||||
|
|||||||
@@ -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
|
/// 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
|
/// 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.
|
/// the the AugmentedF logic but in the wrapping of the circuits.
|
||||||
#[cfg(test)]
|
|
||||||
pub struct WrapperCircuit<F: PrimeField, FC: FCircuit<F>> {
|
pub struct WrapperCircuit<F: PrimeField, FC: FCircuit<F>> {
|
||||||
pub FC: FC, // F circuit
|
pub FC: FC, // F circuit
|
||||||
pub z_i: Option<Vec<F>>,
|
pub z_i: Option<Vec<F>>,
|
||||||
pub z_i1: Option<Vec<F>>,
|
pub z_i1: Option<Vec<F>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
impl<F, FC> ark_relations::r1cs::ConstraintSynthesizer<F> for WrapperCircuit<F, FC>
|
impl<F, FC> ark_relations::r1cs::ConstraintSynthesizer<F> for WrapperCircuit<F, FC>
|
||||||
where
|
where
|
||||||
F: PrimeField,
|
F: PrimeField,
|
||||||
|
|||||||
33
frontends/Cargo.toml
Normal file
33
frontends/Cargo.toml
Normal file
@@ -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"]
|
||||||
18
frontends/README.md
Normal file
18
frontends/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# 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:
|
||||||
|
- [Circom](https://github.com/iden3/circom), iden3, 0Kims Association. Supported version`<=v2.1.9`.
|
||||||
|
- [Noir](https://github.com/noir-lang/noir), Aztec.
|
||||||
|
- [Noname](https://github.com/zksecurity/noname), zkSecurity. Partially supported.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation about frontend interface and experimental frontends: https://privacy-scaling-explorations.github.io/sonobe-docs/usage/frontend.html
|
||||||
|
|
||||||
|
## Implementing new frontends
|
||||||
|
Support for new frontends can be added (even from outside this repo) by implementing the [`FCircuit` trait](https://github.com/privacy-scaling-explorations/sonobe/blob/main/folding-schemes/src/frontend/mod.rs).
|
||||||
@@ -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_circom::circom::{CircomCircuit, R1CS as CircomR1CS};
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_r1cs_std::alloc::AllocVar;
|
use ark_r1cs_std::alloc::AllocVar;
|
||||||
use ark_r1cs_std::fields::fp::FpVar;
|
use ark_r1cs_std::fields::fp::FpVar;
|
||||||
|
use ark_r1cs_std::fields::fp::FpVar::Var;
|
||||||
use ark_r1cs_std::R1CSVar;
|
use ark_r1cs_std::R1CSVar;
|
||||||
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
|
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
|
||||||
use ark_std::fmt::Debug;
|
use ark_std::fmt::Debug;
|
||||||
|
use folding_schemes::{frontend::FCircuit, utils::PathOrBin, Error};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{fmt, usize};
|
use std::{fmt, usize};
|
||||||
@@ -187,10 +185,10 @@ impl<F: PrimeField> FCircuit<F> for CircomFCircuit<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F: PrimeField> 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();
|
let mut input_values = Vec::new();
|
||||||
// converts each FpVar to PrimeField value, then to num_bigint::BigInt.
|
// 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.
|
// extracts the PrimeField value from FpVar.
|
||||||
let primefield_value = fp_var.value()?;
|
let primefield_value = fp_var.value()?;
|
||||||
// converts the PrimeField value to num_bigint::BigInt.
|
// converts the PrimeField value to num_bigint::BigInt.
|
||||||
@@ -213,9 +211,9 @@ pub mod tests {
|
|||||||
// Tests the step_native function of CircomFCircuit.
|
// Tests the step_native function of CircomFCircuit.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_circom_step_native() {
|
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 =
|
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 =
|
let circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
||||||
@@ -228,9 +226,9 @@ pub mod tests {
|
|||||||
// Tests the generate_step_constraints function of CircomFCircuit.
|
// Tests the generate_step_constraints function of CircomFCircuit.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_circom_step_constraints() {
|
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 =
|
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 =
|
let circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
||||||
@@ -249,16 +247,16 @@ pub mod tests {
|
|||||||
// Tests the WrapperCircuit with CircomFCircuit.
|
// Tests the WrapperCircuit with CircomFCircuit.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wrapper_circomtofcircuit() {
|
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 =
|
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 =
|
let circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
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.
|
// Allocates z_i1 by using step_native function.
|
||||||
let z_i = vec![Fr::from(3_u32)];
|
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(),
|
FC: circom_fcircuit.clone(),
|
||||||
z_i: Some(z_i.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![]).unwrap()),
|
||||||
@@ -275,10 +273,9 @@ pub mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_circom_external_inputs() {
|
fn test_circom_external_inputs() {
|
||||||
let r1cs_path =
|
let r1cs_path = PathBuf::from("./src/circom/test_folder/with_external_inputs.r1cs");
|
||||||
PathBuf::from("./src/frontend/circom/test_folder/with_external_inputs.r1cs");
|
|
||||||
let wasm_path = PathBuf::from(
|
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 =
|
let circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 2)).unwrap(); // state_len:1, external_inputs_len:2
|
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 2)).unwrap(); // state_len:1, external_inputs_len:2
|
||||||
@@ -320,10 +317,9 @@ pub mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_circom_no_external_inputs() {
|
fn test_circom_no_external_inputs() {
|
||||||
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/no_external_inputs.r1cs");
|
let r1cs_path = PathBuf::from("./src/circom/test_folder/no_external_inputs.r1cs");
|
||||||
let wasm_path = PathBuf::from(
|
let wasm_path =
|
||||||
"./src/frontend/circom/test_folder/no_external_inputs_js/no_external_inputs.wasm",
|
PathBuf::from("./src/circom/test_folder/no_external_inputs_js/no_external_inputs.wasm");
|
||||||
);
|
|
||||||
let circom_fcircuit =
|
let circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 3, 0)).unwrap();
|
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 3, 0)).unwrap();
|
||||||
let cs = ConstraintSystem::<Fr>::new_ref();
|
let cs = ConstraintSystem::<Fr>::new_ref();
|
||||||
@@ -353,9 +349,9 @@ pub mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_custom_code() {
|
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 =
|
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 =
|
let mut circom_fcircuit =
|
||||||
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
CircomFCircuit::<Fr>::new((r1cs_path.into(), wasm_path.into(), 1, 0)).unwrap(); // state_len:1, external_inputs_len:0
|
||||||
@@ -367,7 +363,7 @@ pub mod tests {
|
|||||||
|
|
||||||
// Allocates z_i1 by using step_native function.
|
// Allocates z_i1 by using step_native function.
|
||||||
let z_i = vec![Fr::from(3_u32)];
|
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(),
|
FC: circom_fcircuit.clone(),
|
||||||
z_i: Some(z_i.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![]).unwrap()),
|
||||||
4
frontends/src/circom/test_folder/compile.sh
Executable file
4
frontends/src/circom/test_folder/compile.sh
Executable file
@@ -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/
|
||||||
@@ -4,11 +4,10 @@ use ark_circom::{
|
|||||||
};
|
};
|
||||||
use ark_ff::{BigInteger, PrimeField};
|
use ark_ff::{BigInteger, PrimeField};
|
||||||
use ark_serialize::Read;
|
use ark_serialize::Read;
|
||||||
use color_eyre::Result;
|
|
||||||
use num_bigint::{BigInt, Sign};
|
use num_bigint::{BigInt, Sign};
|
||||||
use std::{fs::File, io::Cursor, marker::PhantomData, path::PathBuf};
|
use std::{fs::File, io::Cursor, marker::PhantomData, path::PathBuf};
|
||||||
|
|
||||||
use crate::{utils::PathOrBin, Error};
|
use folding_schemes::{utils::PathOrBin, Error};
|
||||||
|
|
||||||
// A struct that wraps Circom functionalities, allowing for extraction of R1CS and witnesses
|
// A struct that wraps Circom functionalities, allowing for extraction of R1CS and witnesses
|
||||||
// based on file paths to Circom's .r1cs and .wasm.
|
// based on file paths to Circom's .r1cs and .wasm.
|
||||||
@@ -134,14 +133,14 @@ mod tests {
|
|||||||
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
|
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
|
||||||
|
|
||||||
//To generate .r1cs and .wasm files, run the below command in the terminal.
|
//To generate .r1cs and .wasm files, run the below command in the terminal.
|
||||||
//bash ./folding-schemes/src/frontend/circom/test_folder/compile.sh
|
//bash ./frontends/src/circom/test_folder/compile.sh
|
||||||
|
|
||||||
// Test the satisfication by using the CircomBuilder of circom-compat
|
// Test the satisfication by using the CircomBuilder of circom-compat
|
||||||
#[test]
|
#[test]
|
||||||
fn test_circombuilder_satisfied() {
|
fn test_circombuilder_satisfied() {
|
||||||
let cfg = CircomConfig::<Fr>::new(
|
let cfg = CircomConfig::<Fr>::new(
|
||||||
"./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm",
|
"./src/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm",
|
||||||
"./src/frontend/circom/test_folder/cubic_circuit.r1cs",
|
"./src/circom/test_folder/cubic_circuit.r1cs",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut builder = CircomBuilder::new(cfg);
|
let mut builder = CircomBuilder::new(cfg);
|
||||||
@@ -156,9 +155,9 @@ mod tests {
|
|||||||
// Test the satisfication by using the CircomWrapper
|
// Test the satisfication by using the CircomWrapper
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extract_r1cs_and_witness() {
|
fn test_extract_r1cs_and_witness() {
|
||||||
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 =
|
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 inputs = vec![("ivc_input".to_string(), vec![BigInt::from(3)])];
|
let inputs = vec![("ivc_input".to_string(), vec![BigInt::from(3)])];
|
||||||
let wrapper = CircomWrapper::<Fr>::new(r1cs_path.into(), wasm_path.into()).unwrap();
|
let wrapper = CircomWrapper::<Fr>::new(r1cs_path.into(), wasm_path.into()).unwrap();
|
||||||
3
frontends/src/lib.rs
Normal file
3
frontends/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod circom;
|
||||||
|
pub mod noir;
|
||||||
|
pub mod noname;
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{utils::PathOrBin, Error};
|
|
||||||
|
|
||||||
use super::FCircuit;
|
|
||||||
use acvm::{
|
use acvm::{
|
||||||
acir::{
|
acir::{
|
||||||
acir_field::GenericFieldElement,
|
acir_field::GenericFieldElement,
|
||||||
@@ -16,6 +13,7 @@ use ark_ff::PrimeField;
|
|||||||
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar};
|
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar};
|
||||||
use ark_relations::r1cs::ConstraintSynthesizer;
|
use ark_relations::r1cs::ConstraintSynthesizer;
|
||||||
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
|
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
|
||||||
|
use folding_schemes::{frontend::FCircuit, utils::PathOrBin, Error};
|
||||||
use noir_arkworks_backend::{
|
use noir_arkworks_backend::{
|
||||||
read_program_from_binary, read_program_from_file, sonobe_bridge::AcirCircuitSonobe,
|
read_program_from_binary, read_program_from_file, sonobe_bridge::AcirCircuitSonobe,
|
||||||
};
|
};
|
||||||
@@ -30,7 +28,7 @@ pub struct NoirFCircuit<F: PrimeField> {
|
|||||||
impl<F: PrimeField> FCircuit<F> for NoirFCircuit<F> {
|
impl<F: PrimeField> FCircuit<F> for NoirFCircuit<F> {
|
||||||
type Params = (PathOrBin, usize, usize);
|
type Params = (PathOrBin, usize, usize);
|
||||||
|
|
||||||
fn new(params: Self::Params) -> Result<Self, crate::Error> {
|
fn new(params: Self::Params) -> Result<Self, Error> {
|
||||||
let (source, state_len, external_inputs_len) = params;
|
let (source, state_len, external_inputs_len) = params;
|
||||||
let program = match source {
|
let program = match source {
|
||||||
PathOrBin::Path(path) => read_program_from_file(path),
|
PathOrBin::Path(path) => read_program_from_file(path),
|
||||||
@@ -70,7 +68,7 @@ impl<F: PrimeField> FCircuit<F> for NoirFCircuit<F> {
|
|||||||
_i: usize,
|
_i: usize,
|
||||||
z_i: Vec<F>,
|
z_i: Vec<F>,
|
||||||
external_inputs: Vec<F>, // inputs that are not part of the state
|
external_inputs: Vec<F>, // inputs that are not part of the state
|
||||||
) -> Result<Vec<F>, crate::Error> {
|
) -> Result<Vec<F>, Error> {
|
||||||
let mut acvm = ACVM::new(
|
let mut acvm = ACVM::new(
|
||||||
&StubbedBlackBoxSolver,
|
&StubbedBlackBoxSolver,
|
||||||
&self.circuit.opcodes,
|
&self.circuit.opcodes,
|
||||||
@@ -226,20 +224,21 @@ pub fn load_noir_circuit<F: PrimeField>(path: String) -> Circuit<GenericFieldEle
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::frontend::{noir::load_noir_circuit, FCircuit};
|
use crate::noir::load_noir_circuit;
|
||||||
use ark_bn254::Fr;
|
use ark_bn254::Fr;
|
||||||
use ark_r1cs_std::R1CSVar;
|
use ark_r1cs_std::R1CSVar;
|
||||||
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar};
|
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar};
|
||||||
use ark_relations::r1cs::ConstraintSystem;
|
use ark_relations::r1cs::ConstraintSystem;
|
||||||
|
use folding_schemes::frontend::FCircuit;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use crate::frontend::noir::NoirFCircuit;
|
use crate::noir::NoirFCircuit;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_step_native() {
|
fn test_step_native() {
|
||||||
let cur_path = env::current_dir().unwrap();
|
let cur_path = env::current_dir().unwrap();
|
||||||
let circuit_path = format!(
|
let circuit_path = format!(
|
||||||
"{}/src/frontend/noir/test_folder/test_circuit/target/test_circuit.json",
|
"{}/src/noir/test_folder/test_circuit/target/test_circuit.json",
|
||||||
cur_path.to_str().unwrap()
|
cur_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
let circuit = load_noir_circuit(circuit_path);
|
let circuit = load_noir_circuit(circuit_path);
|
||||||
@@ -259,7 +258,7 @@ mod tests {
|
|||||||
let cs = ConstraintSystem::<Fr>::new_ref();
|
let cs = ConstraintSystem::<Fr>::new_ref();
|
||||||
let cur_path = env::current_dir().unwrap();
|
let cur_path = env::current_dir().unwrap();
|
||||||
let circuit_path = format!(
|
let circuit_path = format!(
|
||||||
"{}/src/frontend/noir/test_folder/test_circuit/target/test_circuit.json",
|
"{}/src/noir/test_folder/test_circuit/target/test_circuit.json",
|
||||||
cur_path.to_str().unwrap()
|
cur_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
let circuit = load_noir_circuit(circuit_path);
|
let circuit = load_noir_circuit(circuit_path);
|
||||||
@@ -283,7 +282,7 @@ mod tests {
|
|||||||
let cs = ConstraintSystem::<Fr>::new_ref();
|
let cs = ConstraintSystem::<Fr>::new_ref();
|
||||||
let cur_path = env::current_dir().unwrap();
|
let cur_path = env::current_dir().unwrap();
|
||||||
let circuit_path = format!(
|
let circuit_path = format!(
|
||||||
"{}/src/frontend/noir/test_folder/test_no_external_inputs/target/test_no_external_inputs.json",
|
"{}/src/noir/test_folder/test_no_external_inputs/target/test_no_external_inputs.json",
|
||||||
cur_path.to_str().unwrap()
|
cur_path.to_str().unwrap()
|
||||||
);
|
);
|
||||||
let circuit = load_noir_circuit(circuit_path);
|
let circuit = load_noir_circuit(circuit_path);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
CUR_DIR=$(pwd)
|
CUR_DIR=$(pwd)
|
||||||
TEST_PATH="${CUR_DIR}/folding-schemes/src/frontend/noir/test_folder/"
|
TEST_PATH="${CUR_DIR}/frontends/src/noir/test_folder/"
|
||||||
for test_path in test_circuit test_mimc test_no_external_inputs; do
|
for test_path in test_circuit test_mimc test_no_external_inputs; do
|
||||||
FOLDER="${TEST_PATH}${test_path}/"
|
FOLDER="${TEST_PATH}${test_path}/"
|
||||||
cd ${FOLDER} && nargo compile && cd ${TEST_PATH}
|
cd ${FOLDER} && nargo compile && cd ${TEST_PATH}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::Error;
|
|
||||||
use ark_noname::sonobe::NonameSonobeCircuit;
|
use ark_noname::sonobe::NonameSonobeCircuit;
|
||||||
use ark_r1cs_std::alloc::AllocVar;
|
use ark_r1cs_std::alloc::AllocVar;
|
||||||
use ark_r1cs_std::fields::fp::FpVar;
|
use ark_r1cs_std::fields::fp::FpVar;
|
||||||
@@ -8,9 +7,9 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use self::utils::NonameInputs;
|
use self::utils::NonameInputs;
|
||||||
|
|
||||||
use super::FCircuit;
|
|
||||||
use ark_ff::PrimeField;
|
use ark_ff::PrimeField;
|
||||||
use ark_noname::utils::compile_source_code;
|
use ark_noname::utils::compile_source_code;
|
||||||
|
use folding_schemes::{frontend::FCircuit, Error};
|
||||||
use noname::backends::{r1cs::R1CS as R1CSNoname, BackendField};
|
use noname::backends::{r1cs::R1CS as R1CSNoname, BackendField};
|
||||||
use noname::witness::CompiledCircuit;
|
use noname::witness::CompiledCircuit;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
@@ -25,7 +24,7 @@ pub struct NonameFCircuit<F: PrimeField, BF: BackendField> {
|
|||||||
impl<F: PrimeField, BF: BackendField> FCircuit<F> for NonameFCircuit<F, BF> {
|
impl<F: PrimeField, BF: BackendField> FCircuit<F> for NonameFCircuit<F, BF> {
|
||||||
type Params = (String, usize, usize);
|
type Params = (String, usize, usize);
|
||||||
|
|
||||||
fn new(params: Self::Params) -> Result<Self, crate::Error> {
|
fn new(params: Self::Params) -> Result<Self, Error> {
|
||||||
let (code, state_len, external_inputs_len) = params;
|
let (code, state_len, external_inputs_len) = params;
|
||||||
let compiled_circuit = compile_source_code::<BF>(&code).map_err(|_| {
|
let compiled_circuit = compile_source_code::<BF>(&code).map_err(|_| {
|
||||||
Error::Other("Encountered an error while compiling a noname circuit".to_owned())
|
Error::Other("Encountered an error while compiling a noname circuit".to_owned())
|
||||||
@@ -51,7 +50,7 @@ impl<F: PrimeField, BF: BackendField> FCircuit<F> for NonameFCircuit<F, BF> {
|
|||||||
_i: usize,
|
_i: usize,
|
||||||
z_i: Vec<F>,
|
z_i: Vec<F>,
|
||||||
external_inputs: Vec<F>,
|
external_inputs: Vec<F>,
|
||||||
) -> Result<Vec<F>, crate::Error> {
|
) -> Result<Vec<F>, Error> {
|
||||||
let wtns_external_inputs =
|
let wtns_external_inputs =
|
||||||
NonameInputs::from((&external_inputs, "external_inputs".to_string()));
|
NonameInputs::from((&external_inputs, "external_inputs".to_string()));
|
||||||
let wtns_ivc_inputs = NonameInputs::from((&z_i, "ivc_inputs".to_string()));
|
let wtns_ivc_inputs = NonameInputs::from((&z_i, "ivc_inputs".to_string()));
|
||||||
@@ -119,7 +118,7 @@ mod tests {
|
|||||||
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar};
|
use ark_r1cs_std::{alloc::AllocVar, fields::fp::FpVar, R1CSVar};
|
||||||
use noname::backends::r1cs::R1csBn254Field;
|
use noname::backends::r1cs::R1csBn254Field;
|
||||||
|
|
||||||
use crate::frontend::FCircuit;
|
use folding_schemes::frontend::FCircuit;
|
||||||
|
|
||||||
use super::NonameFCircuit;
|
use super::NonameFCircuit;
|
||||||
use ark_relations::r1cs::ConstraintSystem;
|
use ark_relations::r1cs::ConstraintSystem;
|
||||||
@@ -29,6 +29,7 @@ ark-bn254 = {version="0.4.0", features=["r1cs"]}
|
|||||||
ark-grumpkin = {version="0.4.0", features=["r1cs"]}
|
ark-grumpkin = {version="0.4.0", features=["r1cs"]}
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
folding-schemes = { path = "../folding-schemes/", features=["light-test"]}
|
folding-schemes = { path = "../folding-schemes/", features=["light-test"]}
|
||||||
|
frontends = { path = "../frontends/"}
|
||||||
noname = { git = "https://github.com/dmpierre/noname" }
|
noname = { git = "https://github.com/dmpierre/noname" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
Reference in New Issue
Block a user