diff --git a/ligthclient-circuits/src/lib.rs b/ligthclient-circuits/src/lib.rs index 09cd2967..f26ce09a 100644 --- a/ligthclient-circuits/src/lib.rs +++ b/ligthclient-circuits/src/lib.rs @@ -15,7 +15,6 @@ pub mod witness; mod sha256_circuit; mod sync_step_circuit; -mod state_circuit; mod committee_update_circuit; mod ssz_merkle; diff --git a/ligthclient-circuits/src/state_circuit.rs b/ligthclient-circuits/src/state_circuit.rs deleted file mode 100644 index 58a7d391..00000000 --- a/ligthclient-circuits/src/state_circuit.rs +++ /dev/null @@ -1,281 +0,0 @@ -use crate::sha256_circuit::Sha256Circuit; -use crate::table::sha256_table::Sha256TableAssignedRow; -use crate::witness::MerkleTraceStep; -use crate::{ - sha256_circuit::Sha256CircuitConfig, table::Sha256Table, util::ConstrainBuilderCommon, -}; - -use log::{debug, info}; - -use crate::gadget::{not, rlc}; -use crate::{ - table::LookupTable, - util::{Challenges, SubCircuit, SubCircuitConfig}, - witness::{self, MerkleTrace}, -}; -use eth_types::*; -use halo2_proofs::{ - circuit::{Layouter, Region, Value}, - plonk::{Advice, Column, ConstraintSystem, Error, Expression, Instance}, - poly::Rotation, -}; -use itertools::Itertools; -use poseidon_circuit::{hash, poseidon}; -use std::collections::HashMap; -use std::{ - marker::PhantomData, - ops::{Add, Mul}, - vec, -}; - -pub const TREE_LEVEL_AUX_COLUMNS: usize = 1; - -#[derive(Clone, Debug)] -pub struct StateCircuitConfig { - sha256_circuit: Sha256CircuitConfig, - pub state_root: [Column; 32], -} - -pub struct StateCircuitArgs { - pub sha256_circuit: Sha256CircuitConfig, - pub randomness: F, -} - -impl SubCircuitConfig for StateCircuitConfig { - type ConfigArgs = StateCircuitArgs; - - fn new(meta: &mut ConstraintSystem, args: Self::ConfigArgs) -> Self { - let state_root = array_init::array_init(|_| meta.instance_column()); - let sha256_circuit = args.sha256_circuit; - - debug!("state circuit degree={}", meta.degree()); - - StateCircuitConfig { - sha256_circuit, - state_root, - } - } - - fn annotate_columns_in_region(&self, region: &mut Region<'_, F>) { - self.sha256_circuit.annotate_columns_in_region(region); - } -} - -impl StateCircuitConfig { - fn assign( - &self, - layouter: &mut impl Layouter, - witness: &MerkleTrace, - challenge: Value, - ) -> Result<(), Error> { - let trace_steps = witness.sorted(); - - let mut sha256_witness = - Sha256Circuit::::generate_witness(&witness.sha256_inputs(), Default::default()); - let sha256_cells = self.sha256_circuit.assign(layouter, &sha256_witness)?; - - layouter.assign_region( - || "state circuit", - |mut region| { - self.annotate_columns_in_region(&mut region); - - let cells_map: HashMap<_, _> = sha256_cells - .iter() - .zip(trace_steps.iter()) - .map(|(r, s)| (s.index, r)) - .collect(); - - // Apply equality constraints - for (( - index, - Sha256TableAssignedRow { - is_enabled, - input_chunks, - input_rlc, - input_len, - hash_rlc, - hash_bytes, - }, - )) in cells_map.iter() - { - if *index == 1 { - continue; - } - - let parent_index = index / 2; - let right = parent_index % 2; - - if parent_index == 1 { - // parent is root node - // region.constrain_equal(parent_cell.cell(), cells[&1].2.cell())?; - continue; - } - - // if parent index is odd, that means its a sibling node - // TODO: Rename node to "left" and sibling to "right" - let parent_node_cell = if right == 0 { - // node cell (left) - &cells_map[&parent_index].input_chunks[0] - } else if right == 1 { - // sibling cell (right) - &cells_map[&(parent_index - 1)].input_chunks[1] - } else { - unreachable!() - }; - - region.constrain_equal(hash_rlc.cell(), parent_node_cell.cell())?; - } - - Ok(()) - }, - ) - } -} - -/// Circuit for verify Merkle-multi proof of the SSZ Merkelized `BeaconState` -#[derive(Clone, Debug)] -pub struct StateCircuit<'a, S: Spec, F: Field> { - trace: &'a MerkleTrace, - _f: PhantomData, - _spec: PhantomData, -} - -impl<'a, S: Spec, F: Field> StateCircuit<'a, S, F> { - pub fn new(trace: &'a MerkleTrace) -> Self { - Self { - trace, - _f: PhantomData, - _spec: PhantomData::, - } - } -} - -impl<'a, S: Spec, F: Field> SubCircuit<'a, F> for StateCircuit<'a, S, F> { - type Config = StateCircuitConfig; - type SynthesisArgs = (); - type Output = (); - - fn new_from_state(state: &'a witness::SyncState) -> Self { - Self::new(&state.merkle_trace) - } - - fn synthesize_sub( - &self, - config: &Self::Config, - challenges: &Challenges>, - layouter: &mut impl Layouter, - _: Self::SynthesisArgs, - ) -> Result<(), Error> { - config.assign(layouter, self.trace, challenges.sha256_input()) - } - - fn instances(&self) -> Vec> { - self.trace.root().map(|b| vec![F::from(b as u64)]).to_vec() - } - - fn unusable_rows() -> usize { - todo!() - } - - fn min_num_rows_state(_block: &witness::SyncState) -> (usize, usize) { - todo!() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - sha256_circuit::Sha256CircuitConfig, - util::{full_prover, full_verifier, gen_pkey}, - witness::{MerkleTrace, SyncState, SyncStateInput}, - }; - use ark_std::{end_timer, start_timer}; - use eth_types::Test as S; - use halo2_base::utils::fs::gen_srs; - use halo2_proofs::{ - circuit::SimpleFloorPlanner, dev::MockProver, halo2curves::bn256::Fr, plonk::Circuit, - }; - use std::{fs, marker::PhantomData}; - - #[derive(Debug, Clone)] - struct TestCircuit<'a, S: Spec, F: Field> { - inner: StateCircuit<'a, S, F>, - } - - impl<'a, S: Spec, F: Field> Circuit for TestCircuit<'a, S, F> { - type Config = (StateCircuitConfig, Challenges>); - type FloorPlanner = SimpleFloorPlanner; - - fn without_witnesses(&self) -> Self { - unimplemented!() - } - - fn configure(meta: &mut ConstraintSystem) -> Self::Config { - let sha256_table = Sha256Table::construct(meta); - let sha256_circuit = Sha256CircuitConfig::new::(meta, sha256_table); - - let config = { - StateCircuitConfig::new::( - meta, - StateCircuitArgs { - sha256_circuit, - randomness: Sha256CircuitConfig::fixed_challenge(), - }, - ) - }; - - ( - config, - Challenges::mock(Value::known(Sha256CircuitConfig::fixed_challenge())), - ) - } - - fn synthesize( - &self, - mut config: Self::Config, - mut layouter: impl Layouter, - ) -> Result<(), Error> { - self.inner - .synthesize_sub(&config.0, &config.1, &mut layouter, ())?; - Ok(()) - } - } - - #[test] - fn test_state_circuit() { - let k = 18; - let state_input: SyncStateInput = - serde_json::from_slice(&fs::read("../test_data/sync_state.json").unwrap()).unwrap(); - let state: SyncState = state_input.into(); - let circuit = TestCircuit:: { - inner: StateCircuit::new(&state.merkle_trace), - }; - - let instance = circuit.inner.instances(); - let timer = start_timer!(|| "state circuit mock prover"); - let prover = MockProver::::run(k as u32, &circuit, instance).unwrap(); - prover.assert_satisfied(); - end_timer!(timer); - } - - #[test] - fn test_state_proofgen() { - let k = 18; - let state_input: SyncStateInput = - serde_json::from_slice(&fs::read("../test_data/sync_state.json").unwrap()).unwrap(); - let state: SyncState = state_input.into(); - let circuit = TestCircuit:: { - inner: StateCircuit::new(&state.merkle_trace), - }; - - let params = gen_srs(k as u32); - - let pkey = gen_pkey(|| "state", ¶ms, None, circuit.clone()).unwrap(); - - let public_inputs = circuit.inner.instances(); - let proof = full_prover(¶ms, &pkey, circuit, public_inputs.clone()); - - assert!(full_verifier(¶ms, pkey.get_vk(), proof, public_inputs)) - } -}