From 324e4c4d44a030b9e7fe85aa6e14e7fff3f25338 Mon Sep 17 00:00:00 2001 From: Timofey Luin Date: Mon, 28 Aug 2023 17:25:27 +0300 Subject: [PATCH] fix undeterministic hashing --- .../src/committee_update_circuit.rs | 4 +- .../src/gadget/crypto/cached_hash.rs | 55 ------------ ligthclient-circuits/src/gadget/crypto/mod.rs | 2 - .../src/gadget/crypto/sha256.rs | 2 - ligthclient-circuits/src/ssz_merkle.rs | 8 +- ligthclient-circuits/src/sync_step_circuit.rs | 83 ++++++++++++++++--- 6 files changed, 77 insertions(+), 77 deletions(-) delete mode 100644 ligthclient-circuits/src/gadget/crypto/cached_hash.rs diff --git a/ligthclient-circuits/src/committee_update_circuit.rs b/ligthclient-circuits/src/committee_update_circuit.rs index 4173c400..55d44e09 100644 --- a/ligthclient-circuits/src/committee_update_circuit.rs +++ b/ligthclient-circuits/src/committee_update_circuit.rs @@ -12,8 +12,8 @@ use std::{ use crate::{ gadget::crypto::{ - CachedHashChip, Fp2Point, FpPoint, G1Chip, G1Point, G2Chip, G2Point, HashChip, - HashToCurveCache, HashToCurveChip, Sha256Chip, SpreadConfig, + Fp2Point, FpPoint, G1Chip, G1Point, G2Chip, G2Point, HashChip, HashToCurveCache, + HashToCurveChip, Sha256Chip, SpreadConfig, }, poseidon::{g1_array_poseidon, poseidon_sponge}, sha256_circuit::{util::NUM_ROUNDS, Sha256CircuitConfig}, diff --git a/ligthclient-circuits/src/gadget/crypto/cached_hash.rs b/ligthclient-circuits/src/gadget/crypto/cached_hash.rs deleted file mode 100644 index aba86900..00000000 --- a/ligthclient-circuits/src/gadget/crypto/cached_hash.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::{cell::RefCell, collections::HashMap, hash::Hash}; - -use eth_types::Field; -use halo2_base::{safe_types::RangeChip, Context, QuantumCell}; -use halo2_proofs::{circuit::Region, plonk::Error}; - -use crate::witness::HashInput; - -use super::sha256::{AssignedHashResult, HashChip, Sha256Chip}; - -#[derive(Debug)] -pub struct CachedHashChip<'a, F: Field, HC: HashChip + 'a> { - pub inner: &'a HC, - cache: RefCell, AssignedHashResult>>, -} - -impl<'a, F: Field, HC: HashChip> HashChip for CachedHashChip<'a, F, HC> { - const BLOCK_SIZE: usize = HC::BLOCK_SIZE; - - const DIGEST_SIZE: usize = HC::DIGEST_SIZE; - - fn digest( - &self, - input: HashInput>, - ctx: &mut Context, - region: &mut Region<'_, F>, - ) -> Result, Error> { - let mut cache = self.cache.borrow_mut(); - let bytes: HashInput = input.clone().into(); - if let Some(result) = cache.get(&bytes) { - return Ok(result.clone()); - } - - let result = self.inner.digest::(input, ctx, region)?; - cache.insert(bytes, result.clone()); - Ok(result) - } - - fn take_extra_assignments(&self) -> halo2_base::gates::builder::KeygenAssignments { - self.inner.take_extra_assignments() - } - - fn range(&self) -> &RangeChip { - self.inner.range() - } -} - -impl<'a, F: Field, HC: HashChip> CachedHashChip<'a, F, HC> { - pub fn new(chip: &'a HC) -> Self { - Self { - inner: chip, - cache: Default::default(), - } - } -} diff --git a/ligthclient-circuits/src/gadget/crypto/mod.rs b/ligthclient-circuits/src/gadget/crypto/mod.rs index 1e395e93..bb966a63 100644 --- a/ligthclient-circuits/src/gadget/crypto/mod.rs +++ b/ligthclient-circuits/src/gadget/crypto/mod.rs @@ -1,10 +1,8 @@ -mod cached_hash; mod hash2curve; mod sha256; mod sha256_wide; mod util; -pub use cached_hash::CachedHashChip; use eth_types::{AppCurveExt, HashCurveExt}; use halo2_ecc::{ bigint::ProperCrtUint, diff --git a/ligthclient-circuits/src/gadget/crypto/sha256.rs b/ligthclient-circuits/src/gadget/crypto/sha256.rs index b380401a..3b0d749a 100644 --- a/ligthclient-circuits/src/gadget/crypto/sha256.rs +++ b/ligthclient-circuits/src/gadget/crypto/sha256.rs @@ -15,7 +15,6 @@ use std::collections::HashMap; use std::{cell::RefCell, char::MAX}; use crate::gadget::crypto::sha256::compression::{sha256_compression, INIT_STATE}; -use crate::gadget::rlc; use crate::util::AssignedValueCell; use crate::{ sha256_circuit::{util::Sha256AssignedRows, Sha256CircuitConfig}, @@ -75,7 +74,6 @@ impl<'a, F: Field> HashChip for Sha256Chip<'a, F> { ctx: &mut Context, region: &mut Region<'_, F>, ) -> Result, Error> { - let binary_input: HashInput = input.clone().into(); let assigned_input = input.into_assigned(ctx); // let mut extra_assignment = self.extra_assignments.borrow_mut(); diff --git a/ligthclient-circuits/src/ssz_merkle.rs b/ligthclient-circuits/src/ssz_merkle.rs index 5f2e19ec..7a17a6ea 100644 --- a/ligthclient-circuits/src/ssz_merkle.rs +++ b/ligthclient-circuits/src/ssz_merkle.rs @@ -5,6 +5,7 @@ use itertools::Itertools; use crate::{ gadget::crypto::HashChip, + util::{IntoConstant, IntoWitness}, witness::{HashInput, HashInputChunk}, }; @@ -34,16 +35,13 @@ where let len_even = chunks.len() + chunks.len() % 2; let padded_chunks = chunks .into_iter() - .pad_using(len_even, |_| { - HashInputChunk::from( - ZERO_HASHES[depth].map(|b| ctx.load_constant(F::from(b as u64))), - ) - }) + .pad_using(len_even, |_| ZERO_HASHES[depth].as_slice().into_constant()) .collect_vec(); chunks = padded_chunks .into_iter() .tuples() + .take(3) .map(|(left, right)| { hasher .digest::<128>(HashInput::TwoToOne(left, right), ctx, region) diff --git a/ligthclient-circuits/src/sync_step_circuit.rs b/ligthclient-circuits/src/sync_step_circuit.rs index 28b1b763..34721d68 100644 --- a/ligthclient-circuits/src/sync_step_circuit.rs +++ b/ligthclient-circuits/src/sync_step_circuit.rs @@ -12,8 +12,8 @@ use std::{ use crate::{ gadget::crypto::{ - CachedHashChip, Fp2Point, FpPoint, G1Chip, G1Point, G2Chip, G2Point, HashChip, - HashToCurveCache, HashToCurveChip, Sha256Chip, SpreadConfig, + Fp2Point, FpPoint, G1Chip, G1Point, G2Chip, G2Point, HashChip, HashToCurveCache, + HashToCurveChip, Sha256Chip, SpreadConfig, }, poseidon::{g1_array_poseidon, poseidon_sponge}, sha256_circuit::{util::NUM_ROUNDS, Sha256CircuitConfig}, @@ -248,7 +248,6 @@ impl Circuit for SyncStepCircuit { use ff::Field; fp12_chip.load_constant(ctx, Fq12::one()) }; - let hasher = CachedHashChip::new(&sha256_chip); let mut h2c_cache = HashToCurveCache::::default(); // Verify attestted header @@ -260,9 +259,9 @@ impl Circuit for SyncStepCircuit { self.attested_block.body_root.as_ref().into_witness(), ]; - let attested_header = ssz_merkleize_chunks(ctx, &mut region, &hasher, chunks)?; + let attested_header = ssz_merkleize_chunks(ctx, &mut region, &sha256_chip, chunks)?; - let signing_root = hasher + let signing_root = sha256_chip .digest::<128>( HashInput::TwoToOne( attested_header.into(), @@ -377,7 +376,7 @@ impl AppCircuitExt for SyncStepCircuit { std::env::set_var("LOOKUP_BITS", (k - 1).to_string()); let params: FlexGateConfigParams = serde_json::from_str(&var("FLEX_GATE_CONFIG_PARAMS").unwrap()).unwrap(); - println!("params: {:?}", params); + println!("config used: {:?}", params); params } @@ -425,6 +424,36 @@ impl Default for SyncStepCircuit { dry_run: false, _spec: PhantomData, } + // TODO: hard code default data + // let state_input: SyncStateInput = + // serde_json::from_slice(&fs::read("../test_data/sync_state.json").unwrap()).unwrap(); + // let state: SyncState = state_input.into(); + + // Self { + // builder, + // signature: state.sync_signature.clone(), + // domain: state.domain, + // attested_block: state.attested_block.clone(), + // pubkeys: state + // .sync_committee + // .iter() + // .cloned() + // .map(|v| { + // G1Affine::from_uncompressed_unchecked( + // &v.pubkey_uncompressed.as_slice().try_into().unwrap(), + // ) + // .unwrap() + // }) + // .collect_vec(), + // pariticipation_bits: state + // .sync_committee + // .iter() + // .cloned() + // .map(|v| v.is_attested) + // .collect_vec(), + // dry_run: false, + // _spec: PhantomData, + // } } } @@ -466,26 +495,38 @@ mod tests { use rayon::iter::ParallelIterator; use rayon::prelude::{IndexedParallelIterator, IntoParallelIterator}; use snark_verifier_sdk::{ + evm::{evm_verify, gen_evm_proof_shplonk}, halo2::{aggregation::AggregationCircuit, gen_proof_shplonk, gen_snark_shplonk}, CircuitExt, SHPLONK, }; - fn get_circuit_with_data(k: usize) -> SyncStepCircuit { + fn get_circuit_with_data(k: usize) -> (SyncStepCircuit, FlexGateConfigParams) { let builder = GateThreadBuilder::new(false); let state_input: SyncStateInput = serde_json::from_slice(&fs::read("../test_data/sync_state.json").unwrap()).unwrap(); let state = state_input.into(); - let _ = SyncStepCircuit::::parametrize(k); + let config = if let Ok(f) = fs::read("./config/sync_step.json") { + serde_json::from_slice(&f).expect("read config file") + } else { + SyncStepCircuit::::parametrize(k) + }; + + set_var( + "FLEX_GATE_CONFIG_PARAMS", + serde_json::to_string(&config).unwrap(), + ); + set_var("LOOKUP_BITS", (config.k - 1).to_string()); + println!("config used: {:?}", config); let builder = RefCell::from(builder); - SyncStepCircuit::new_from_state(builder, &state) + (SyncStepCircuit::new_from_state(builder, &state), config) } #[test] fn test_sync_circuit() { let k = 17; - let circuit = get_circuit_with_data(k); + let (circuit, _) = get_circuit_with_data(k); let timer = start_timer!(|| "sync circuit mock prover"); let prover = MockProver::::run(k as u32, &circuit, vec![]).unwrap(); @@ -496,7 +537,7 @@ mod tests { #[test] fn test_sync_proofgen() { let k = 20; - let circuit = get_circuit_with_data(k); + let (circuit, _) = get_circuit_with_data(k); let params = gen_srs(k as u32); @@ -507,4 +548,24 @@ mod tests { assert!(full_verifier(¶ms, pkey.get_vk(), proof, public_inputs)) } + + #[test] + fn test_sync_evm_verify() { + let k = 20; + let (circuit, config) = get_circuit_with_data(k); + + let (params, pk) = SyncStepCircuit::::setup(&config, None); + + let instances = circuit.instances(); + let num_instance = circuit.num_instance(); + let deployment_code = gen_evm_verifier_shplonk::>( + ¶ms, + pk.get_vk(), + num_instance, + None, + ); + let proof = gen_evm_proof_shplonk(¶ms, &pk, circuit, instances.clone()); + + evm_verify(deployment_code, instances, proof); + } }