update README.md
arnaucube root@arnaucube.com
Tue, 11 Jun 2024 16:22:15 +0200
4 files changed,
29 insertions(+),
9 deletions(-)
M
Cargo.toml
→
Cargo.toml
@@ -24,6 +24,10 @@ ] }
ark-std = "0.4.0" color-eyre = "0.6.2" num-bigint = "0.4.3" +# Note: for testing purposes we use the 'light-test' feature when importing +# Sonobe's folding-schemes, but for a real-world usage it must be used without +# this feature (but then the DeciderETH circuit is bigger and takes more time +# to compute). folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes", features=["light-test"]} solidity-verifiers = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "solidity-verifiers"} serde = "1.0.198"
M
README.md
→
README.md
@@ -1,9 +1,21 @@
# keccak-chain-sonobe -Repo to test a more complex [Circom](https://github.com/iden3/circom) circuit with [Sonobe](https://github.com/privacy-scaling-explorations/sonobe). +Repo showcasing usage of [Sonobe](https://github.com/privacy-scaling-explorations/sonobe) with [Circom](https://github.com/iden3/circom) circuits. -Proves a chain of keccak256 hashes, using the [vocdoni/keccak256-circom](https://github.com/vocdoni/keccak256-circom) circuit. +Proves a chain of keccak256 hashes, using the [vocdoni/keccak256-circom](https://github.com/vocdoni/keccak256-circom) circuit, with [Nova](https://eprint.iacr.org/2021/370.pdf)+[CycleFold](https://eprint.iacr.org/2023/1192.pdf). + +The main idea is to prove $z_n = H(H(...~H(H(H(z_0)))))$, where $n$ is the number of Keccak256 hashes ($H$) that we compute. Proving this in a 'normal' R1CS circuit for a large $n$ would be too costly, but with folding we can manage to prove it in a reasonable time span. + +For more info about Sonobe, check out [Sonobe's docs](https://privacy-scaling-explorations.github.io/sonobe-docs). + +### Usage Assuming rust and circom have been installed: + - `./compile-circuit.sh` - `cargo test --release -- --nocapture` + +### Repo structure +- the Circom circuit to be folded is defined at [./circuit/keccak-chain.circom](https://github.com/arnaucube/keccak-chain-sonobe/blob/main/circuit/keccak-chain.circom) +- the logic to fold the circuit using Sonobe is defined at [src/lib.rs](https://github.com/arnaucube/keccak-chain-sonobe/blob/main/src/lib.rs) + - (it contains some extra sanity check that would not be needed in a real-world use case)
M
circuit/package.json
→
circuit/package.json
@@ -1,7 +1,7 @@
{ - "name": "fakeid-demo", + "name": "keccak-chain-circuit", "version": "0.0.1", - "description": "iden3 circuits", + "description": "Sonobe Circom circuit to prove a Keccak256 chain", "main": "index.js", "scripts": { "clean": "rm -fR dist",
M
src/lib.rs
→
src/lib.rs
@@ -164,6 +164,9 @@ }
#[test] fn full_flow() { + // set how many steps of folding we want to compute + let n_steps = 10; + // set the initial state let z_0_aux: Vec<u32> = vec![0_u32; 32 * 8]; let z_0: Vec<Fr> = z_0_aux.iter().map(|v| Fr::from(*v)).collect::<Vec<Fr>>();@@ -218,19 +221,20 @@
// initialize the folding scheme engine, in our case we use Nova let mut nova = NOVA::init(&fs_prover_params, f_circuit.clone(), z_0.clone()).unwrap(); // run n steps of the folding iteration - for _ in 0..3 { + for _ in 0..n_steps { let start = Instant::now(); nova.prove_step(vec![]).unwrap(); println!("Nova::prove_step {}: {:?}", nova.i, start.elapsed()); } // perform the hash chain natively in rust (which uses a rust Keccak256 library) - let z_1 = rust_native_step(0, z_0.clone(), vec![]).unwrap(); - let z_2 = rust_native_step(0, z_1, vec![]).unwrap(); - let z_3 = rust_native_step(0, z_2, vec![]).unwrap(); + let mut z_i_native = z_0.clone(); + for i in 0..n_steps { + z_i_native = rust_native_step(i, z_i_native.clone(), vec![]).unwrap(); + } // check that the value of the last folding state (nova.z_i) computed through folding, is // equal to the natively computed hash using the rust_native_step method - assert_eq!(nova.z_i, z_3); + assert_eq!(nova.z_i, z_i_native); // ---------------- // Sanity check