From fedb589255caf1bd62552fcc66daf7b263292f2c Mon Sep 17 00:00:00 2001 From: arnaucube Date: Tue, 11 Jun 2024 16:22:15 +0200 Subject: [PATCH] update README.md --- Cargo.toml | 4 ++++ README.md | 16 ++++++++++++++-- circuit/package.json | 4 ++-- src/lib.rs | 14 +++++++++----- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bb10d3..277581f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,10 @@ ark-crypto-primitives = { version = "^0.4.0", default-features = false, features 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" diff --git a/README.md b/README.md index 1aedf61..e7f2ab7 100644 --- a/README.md +++ b/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) diff --git a/circuit/package.json b/circuit/package.json index 2381217..968b6ae 100644 --- a/circuit/package.json +++ b/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", diff --git a/src/lib.rs b/src/lib.rs index 57ca511..66bc5cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -164,6 +164,9 @@ mod tests { #[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 = vec![0_u32; 32 * 8]; let z_0: Vec = z_0_aux.iter().map(|v| Fr::from(*v)).collect::>(); @@ -218,19 +221,20 @@ mod tests { // 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