Browse Source

add rust-native hashing to compare final state

main
arnaucube 4 months ago
parent
commit
f038c9540b
3 changed files with 68 additions and 7 deletions
  1. +2
    -2
      Cargo.toml
  2. +1
    -1
      compile-circuit.sh
  3. +65
    -4
      src/lib.rs

+ 2
- 2
Cargo.toml

@ -24,11 +24,11 @@ ark-crypto-primitives = { version = "^0.4.0", default-features = false, features
ark-std = "0.4.0" ark-std = "0.4.0"
color-eyre = "0.6.2" color-eyre = "0.6.2"
num-bigint = "0.4.3" num-bigint = "0.4.3"
# folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes"}
folding-schemes = { path = "../folding/sonobe_FIX-CIRCOM/folding-schemes", package = "folding-schemes"}
folding-schemes = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "folding-schemes", branch="fix/circom-frontend", features=["light-test"]}
solidity-verifiers = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "solidity-verifiers"} solidity-verifiers = { git = "https://github.com/privacy-scaling-explorations/sonobe", package = "solidity-verifiers"}
serde = "1.0.198" serde = "1.0.198"
serde_json = "1.0.116" serde_json = "1.0.116"
tiny-keccak = { version = "2.0", features = ["keccak"] }
rand = "0.8.5" rand = "0.8.5"

+ 1
- 1
compile-circuit.sh

@ -9,4 +9,4 @@ cd circuit
npm install npm install
cd .. cd ..
circom ./circuit/keccak-chain.circom --O0 --r1cs --sym --wasm --prime bn128 --output ./circuit/
circom ./circuit/keccak-chain.circom --r1cs --sym --wasm --prime bn128 --output ./circuit/

+ 65
- 4
src/lib.rs

@ -19,6 +19,7 @@ mod tests {
use ark_groth16::{Groth16, ProvingKey, VerifyingKey as G16VerifierKey}; use ark_groth16::{Groth16, ProvingKey, VerifyingKey as G16VerifierKey};
use ark_poly_commit::kzg10::VerifierKey as KZGVerifierKey; use ark_poly_commit::kzg10::VerifierKey as KZGVerifierKey;
use ark_ff::{BigInteger, BigInteger256, PrimeField};
use ark_std::Zero; use ark_std::Zero;
use std::path::PathBuf; use std::path::PathBuf;
@ -118,6 +119,34 @@ mod tests {
(fs_prover_params, kzg_vk, g16_pk, g16_vk) (fs_prover_params, kzg_vk, g16_pk, g16_vk)
} }
fn f_vec_to_bits<F: PrimeField>(v: Vec<F>) -> Vec<bool> {
v.iter()
.map(|v_i| {
if v_i.is_one() {
return true;
}
return false;
})
.collect()
}
// returns the bytes representation of the given vector of finite field elements that represent
// bits
fn f_vec_to_bytes<F: PrimeField>(v: Vec<F>) -> Vec<u8> {
let b = f_vec_to_bits(v);
BigInteger256::from_bits_le(&b).to_bytes_le()
}
// function to compute the next state of the folding via rust-native code (not Circom). Used to
// check the Circom values.
use tiny_keccak::{Hasher, Keccak};
fn rust_native_step(z_i: [u8; 32]) -> [u8; 32] {
let mut h = Keccak::v256();
h.update(&z_i);
let mut z_i1 = [0u8; 32];
h.finalize(&mut z_i1);
z_i1
}
#[test] #[test]
fn full_flow() { fn full_flow() {
// set the initial state // set the initial state
@ -149,14 +178,46 @@ mod tests {
>; >;
// initialize the folding scheme engine, in our case we use Nova // initialize the folding scheme engine, in our case we use Nova
let mut nova = NOVA::init(&fs_prover_params, f_circuit.clone(), z_0).unwrap();
let mut nova = NOVA::init(&fs_prover_params, f_circuit.clone(), z_0.clone()).unwrap();
// run n steps of the folding iteration // run n steps of the folding iteration
for i in 0..10 {
for _ in 0..3 {
let start = Instant::now(); let start = Instant::now();
nova.prove_step(vec![]).unwrap(); nova.prove_step(vec![]).unwrap();
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
println!("Nova::prove_step {}: {:?}", nova.i, start.elapsed());
} }
// perform the hash chain natively in rust
let z_0_bytes: [u8; 32] = [0u8; 32];
let z_1_bytes = rust_native_step(z_0_bytes);
let z_2_bytes = rust_native_step(z_1_bytes);
let z_3_bytes = rust_native_step(z_2_bytes);
// 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
let nova_z_i = f_vec_to_bytes(nova.z_i.clone());
assert_eq!(nova_z_i, z_3_bytes);
/*
// The following lines contain a sanity check that checks the IVC proof (before going into
// the zkSNARK proof)
let verifier_params = VerifierParams::<G1, G2> {
poseidon_config: nova.poseidon_config.clone(),
r1cs: nova.clone().r1cs,
cf_r1cs: nova.clone().cf_r1cs,
};
let (running_instance, incoming_instance, cyclefold_instance) = nova.instances();
NOVA::verify(
verifier_params,
z_0,
nova.z_i.clone(),
nova.i,
running_instance,
incoming_instance,
cyclefold_instance,
)
.unwrap();
*/
let rng = rand::rngs::OsRng; let rng = rand::rngs::OsRng;
let start = Instant::now(); let start = Instant::now();
let proof = DECIDERETH_FCircuit::prove( let proof = DECIDERETH_FCircuit::prove(
@ -180,7 +241,7 @@ mod tests {
assert!(verified); assert!(verified);
println!("Decider proof verification: {}", verified); println!("Decider proof verification: {}", verified);
// Now, let's generate the Solidity code that verifies this Decider final proof
// generate the Solidity code that verifies this Decider final proof
let function_selector = let function_selector =
get_function_selector_for_nova_cyclefold_verifier(nova.z_0.len() * 2 + 1); get_function_selector_for_nova_cyclefold_verifier(nova.z_0.len() * 2 + 1);

Loading…
Cancel
Save