Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/challenges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use halo2_proofs::{
arithmetic::FieldExt,
circuit::{Layouter, Value},
plonk::{Challenge, ConstraintSystem, Expression, FirstPhase, VirtualCells},
};

#[derive(Clone, Copy, Debug)]
pub struct Challenges<T = Challenge> {
mpt_word: T,
}

impl Challenges {
pub fn construct<F: FieldExt>(meta: &mut ConstraintSystem<F>) -> Self {
Self {
mpt_word: meta.challenge_usable_after(FirstPhase),
}
}

/// Return `Expression` of challenges from `ConstraintSystem`.
pub fn exprs<F: FieldExt>(&self, meta: &mut ConstraintSystem<F>) -> Challenges<Expression<F>> {
let [mpt_word] = query_expression(meta, |meta| {
[self.mpt_word].map(|challenge| meta.query_challenge(challenge))
});

Challenges { mpt_word }
}

/// Return `Value` of challenges from `Layouter`.
pub fn values<F: FieldExt>(&self, layouter: &impl Layouter<F>) -> Challenges<Value<F>> {
Challenges {
mpt_word: layouter.get_challenge(self.mpt_word),
}
}
}

impl<T: Clone> Challenges<T> {
pub fn mpt_word(&self) -> T {
self.mpt_word.clone()
}
}

fn query_expression<F: FieldExt, T>(
meta: &mut ConstraintSystem<F>,
mut f: impl FnMut(&mut VirtualCells<F>) -> T,
) -> T {
let mut expr = None;
meta.create_gate("Query expression", |meta| {
expr = Some(f(meta));
Some(Expression::Constant(F::from(0)))
});
expr.unwrap()
}
20 changes: 16 additions & 4 deletions src/gadgets/mpt_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use super::{
RANDOMNESS,
};
use crate::{
challenges::Challenges,
constraint_builder::{AdviceColumn, ConstraintBuilder, Query},
types::{
account_key, hash,
Expand All @@ -28,7 +29,7 @@ use ethers_core::{
};
use halo2_proofs::{
arithmetic::{Field, FieldExt},
circuit::Region,
circuit::{Region, Value},
halo2curves::bn256::Fr,
plonk::ConstraintSystem,
};
Expand Down Expand Up @@ -133,6 +134,7 @@ impl MptUpdateConfig {
fn configure<F: FieldExt>(
cs: &mut ConstraintSystem<F>,
cb: &mut ConstraintBuilder<F>,
challenges: &Challenges<Expression<F>>,
poseidon: &impl PoseidonLookup,
key_bit: &impl KeyBitLookup,
rlc: &impl RlcLookup,
Expand Down Expand Up @@ -299,8 +301,6 @@ impl MptUpdateConfig {
}

fn assign(&self, region: &mut Region<'_, Fr>, proofs: &[Proof]) {
let randomness = Fr::from(RANDOMNESS);

let mut offset = 0;
for proof in proofs {
let proof_type = MPTProofType::from(proof.claim);
Expand Down Expand Up @@ -1743,6 +1743,7 @@ mod test {
KeyBitConfig,
ByteBitGadget,
ByteRepresentationConfig,
Challenges,
);
type FloorPlanner = SimpleFloorPlanner;

Expand All @@ -1751,9 +1752,9 @@ mod test {
}

fn configure(cs: &mut ConstraintSystem<Fr>) -> Self::Config {
let challenges = Challenges::construct(cs);
let selector = SelectorColumn(cs.fixed_column());
let mut cb = ConstraintBuilder::new(selector);

let poseidon = PoseidonTable::configure(cs, &mut cb, 4096);
let byte_bit = ByteBitGadget::configure(cs, &mut cb);
let byte_representation = ByteRepresentationConfig::configure(cs, &mut cb, &byte_bit);
Expand All @@ -1768,9 +1769,13 @@ mod test {
&byte_bit,
);

let byte_representation = ByteRepresentationConfig::configure(cs, &mut cb, &byte_bit);

let challenges_exprs = challenges.exprs(cs);
let mpt_update = MptUpdateConfig::configure(
cs,
&mut cb,
&challenges_exprs,
&poseidon,
&key_bit,
&byte_representation,
Expand All @@ -1786,6 +1791,7 @@ mod test {
key_bit,
byte_bit,
byte_representation,
challenges,
)
}

Expand All @@ -1802,8 +1808,14 @@ mod test {
key_bit,
byte_bit,
byte_representation,
challenges,
) = config;

let challenges_value = challenges.values(&layouter);
layouter.assign_region(
|| "",
|mut region| {
mpt_update.assign(&mut region, &self.updates, &challenge_values);
let (u64s, u128s, frs) = self.byte_representations();

layouter.assign_region(
Expand Down
65 changes: 38 additions & 27 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

pub use crate::serde::{Hash, Row, RowDeError};

mod challenges;
mod constraint_builder;
mod eth;
mod gadgets;
Expand All @@ -23,7 +24,9 @@ mod util;
pub mod operation;
pub mod serde;

use challenges::Challenges;
use eth::StorageGadget;
use halo2_proofs::circuit::Value;
use hash_circuit::hash::PoseidonHashTable;
/// re-export required namespace from depened poseidon hash circuit
pub use hash_circuit::{hash, poseidon};
Expand Down Expand Up @@ -153,7 +156,7 @@ impl<Fp: FieldExt> SimpleTrie<Fp> {
}

impl<Fp: FieldExt> Circuit<Fp> for SimpleTrie<Fp> {
type Config = SimpleTrieConfig;
type Config = (SimpleTrieConfig, Challenges);
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
Expand Down Expand Up @@ -184,20 +187,24 @@ impl<Fp: FieldExt> Circuit<Fp> for SimpleTrie<Fp> {
layer.get_free_cols(),
Some(layer.get_root_indexs()),
);
let challenges = Challenges::construct(meta);

let cst = meta.fixed_column();
meta.enable_constant(cst);

SimpleTrieConfig {
layer,
padding,
mpt,
}
(
SimpleTrieConfig {
layer,
padding,
mpt,
},
challenges,
)
}

fn synthesize(
&self,
config: Self::Config,
(config, _challenges): Self::Config,
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
layouter.assign_region(
Expand Down Expand Up @@ -412,10 +419,10 @@ impl EthTrieConfig {
meta: &mut ConstraintSystem<Fp>,
mpt_tbl: [Column<Advice>; 7],
hash_tbl: [Column<Advice>; 5],
randomness: Expression<Fp>,
challenges: Challenges<Expression<Fp>>,
) -> Self {
let mut lite_cfg = Self::configure_base(meta, hash_tbl);
let mpt_tbl = MPTTable::configure(meta, mpt_tbl, randomness);
let mpt_tbl = MPTTable::configure(meta, mpt_tbl, challenges.mpt_word());
let layer = &lite_cfg.layer;
let layer_exported = layer.exported_cols(0);
let gadget_ind = layer.get_gadget_index();
Expand All @@ -442,14 +449,14 @@ impl EthTrieConfig {
pub fn load_mpt_table<'d, Fp: Hashable>(
&self,
layouter: &mut impl Layouter<Fp>,
randomness: Option<Fp>,
challenge: Option<Value<Fp>>,
ops: impl IntoIterator<Item = &'d AccountOp<Fp>>,
tbl_tips: impl IntoIterator<Item = MPTProofType>,
rows: usize,
) -> Result<(), Error> {
let mpt_entries = tbl_tips.into_iter().zip(ops).map(|(proof_type, op)| {
if let Some(rand) = randomness {
MPTEntry::from_op(proof_type, op, rand)
if let Some(challenge) = challenge {
MPTEntry::from_op(proof_type, op, challenge)
} else {
MPTEntry::from_op_no_base(proof_type, op)
}
Expand Down Expand Up @@ -839,7 +846,7 @@ impl CommitmentIndexs {
/// get commitment for lite circuit (no mpt)
pub fn new<Fp: Hashable>() -> Self {
let mut cs: ConstraintSystem<Fp> = Default::default();
let config = EthTrieCircuit::<_, true>::configure(&mut cs);
let config = EthTrieCircuit::<_, true>::configure(&mut cs).0;

let trie_circuit_indexs = config.hash_tbl.commitment_index();

Expand All @@ -854,7 +861,7 @@ impl CommitmentIndexs {
/// get commitment for full circuit
pub fn new_full_circuit<Fp: Hashable>() -> Self {
let mut cs: ConstraintSystem<Fp> = Default::default();
let config = EthTrieCircuit::<_, false>::configure(&mut cs);
let config = EthTrieCircuit::<_, false>::configure(&mut cs).0;

let trie_circuit_indexs = config.hash_tbl.commitment_index();
let mpt_table_start = config
Expand All @@ -875,10 +882,8 @@ impl CommitmentIndexs {
}
}

const TEMP_RANDOMNESS: u64 = 1;

impl<Fp: Hashable, const LITE: bool> Circuit<Fp> for EthTrieCircuit<Fp, LITE> {
type Config = EthTrieConfig;
type Config = (EthTrieConfig, Challenges);
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
Expand All @@ -890,19 +895,24 @@ impl<Fp: Hashable, const LITE: bool> Circuit<Fp> for EthTrieCircuit<Fp, LITE> {
}

fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
if LITE {
EthTrieConfig::configure_lite(meta)
} else {
let base = [0; 7].map(|_| meta.advice_column());
let hash_tbl = [0; 5].map(|_| meta.advice_column());
let randomness = Expression::Constant(Fp::from(get_rand_base()));
EthTrieConfig::configure_sub(meta, base, hash_tbl, randomness)
}
let challenges = Challenges::construct(meta);

(
if LITE {
EthTrieConfig::configure_lite(meta)
} else {
let base = [0; 7].map(|_| meta.advice_column());
let hash_tbl = [0; 5].map(|_| meta.advice_column());
let challenges = challenges.exprs(meta);
EthTrieConfig::configure_sub(meta, base, hash_tbl, challenges)
},
challenges,
)
}

fn synthesize(
&self,
config: Self::Config,
(config, challenges): Self::Config,
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
config.dev_load_hash_table(
Expand All @@ -914,9 +924,10 @@ impl<Fp: Hashable, const LITE: bool> Circuit<Fp> for EthTrieCircuit<Fp, LITE> {
if LITE {
Ok(())
} else {
let mpt_word = challenges.values(&layouter).mpt_word();
config.load_mpt_table(
&mut layouter,
Some(Fp::from(get_rand_base())),
Some(mpt_word),
self.ops.as_slice(),
self.mpt_table.iter().copied(),
self.calcs,
Expand Down
Loading