Skip to content

Commit

Permalink
Add Challenge API.
Browse files Browse the repository at this point in the history
  • Loading branch information
silathdiir committed Apr 26, 2023
1 parent 2cc63d2 commit 816767c
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 76 deletions.
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()
}
8 changes: 5 additions & 3 deletions src/gadgets/mpt_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::{
poseidon::PoseidonLookup,
};
use crate::{
challenges::Challenges,
constraint_builder::{AdviceColumn, ConstraintBuilder, Query, SelectorColumn},
serde::SMTTrace,
types::Proof,
Expand All @@ -13,7 +14,7 @@ use crate::{
use ethers_core::k256::elliptic_curve::PrimeField;
use ethers_core::types::Address;
use halo2_proofs::{
arithmetic::FieldExt, circuit::Region, halo2curves::bn256::Fr, plonk::ConstraintSystem,
arithmetic::FieldExt, circuit::{Region, Value}, halo2curves::bn256::Fr, plonk::{ConstraintSystem, Expression},
};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
Expand Down Expand Up @@ -104,6 +105,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 @@ -178,8 +180,8 @@ impl MptUpdateConfig {
config
}

fn assign(&self, region: &mut Region<'_, Fr>, updates: &[SMTTrace]) {
let randomness = Fr::from(123123u64); // TODOOOOOOO
fn assign(&self, region: &mut Region<'_, Fr>, updates: &[SMTTrace], challenges: &Challenges<Value<Fr>>) {
let randomness = challenges.mpt_word();

let mut offset = 0;
for update in updates {
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 @@ -25,7 +26,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 @@ -155,7 +158,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 @@ -186,20 +189,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 @@ -414,10 +421,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 @@ -444,14 +451,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 @@ -841,7 +848,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 @@ -856,7 +863,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 @@ -877,10 +884,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 @@ -892,19 +897,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 @@ -916,9 +926,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
76 changes: 41 additions & 35 deletions src/mpt_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ pub enum MPTProofType {
#[derive(Clone, Debug)]
pub(crate) struct MPTEntry<F: Field> {
proof_type: MPTProofType,
base: [Option<F>; 7],
base: [Option<Value<F>>; 7],
storage_key: KeyValue<F>,
new_value: KeyValue<F>,
old_value: KeyValue<F>,
Expand All @@ -262,7 +262,7 @@ pub(crate) struct MPTEntry<F: Field> {
impl<F: FieldExt> MPTEntry<F> {
// detect proof type from op data itself, just mocking,
// not always correct
pub fn mock_from_op(op: &AccountOp<F>, randomness: F) -> Self {
pub fn mock_from_op(op: &AccountOp<F>, randomness: Value<F>) -> Self {
if op.state_trie.is_some() {
return if op.store_after.is_none() && op.store_before.is_none() {
Self::from_op(MPTProofType::StorageDoesNotExist, op, randomness)
Expand Down Expand Up @@ -312,9 +312,9 @@ impl<F: FieldExt> MPTEntry<F> {
Self {
proof_type,
base: [
Some(op.address),
Some(Value::known(op.address)),
None,
Some(F::from(proof_type as u64)),
Some(Value::known(F::from(proof_type as u64))),
None,
None,
None,
Expand All @@ -326,45 +326,53 @@ impl<F: FieldExt> MPTEntry<F> {
}
}

pub fn from_op(proof_type: MPTProofType, op: &AccountOp<F>, randomness: F) -> Self {
pub fn from_op(proof_type: MPTProofType, op: &AccountOp<F>, randomness: Value<F>) -> Self {
let mut ret = Self::from_op_no_base(proof_type, op);

let (old_value_f, new_value_f) = match proof_type {
let (old_value, new_value) = match proof_type {
MPTProofType::NonceChanged => (
op.account_before
.as_ref()
.map(|acc| acc.nonce)
.unwrap_or_default(),
op.account_after
.as_ref()
.map(|acc| acc.nonce)
.unwrap_or_default(),
Value::known(
op.account_before
.as_ref()
.map(|acc| acc.nonce)
.unwrap_or_default(),
),
Value::known(
op.account_after
.as_ref()
.map(|acc| acc.nonce)
.unwrap_or_default(),
),
),
MPTProofType::BalanceChanged => (
op.account_before
.as_ref()
.map(|acc| acc.balance)
.unwrap_or_default(),
op.account_after
.as_ref()
.map(|acc| acc.balance)
.unwrap_or_default(),
Value::known(
op.account_before
.as_ref()
.map(|acc| acc.balance)
.unwrap_or_default(),
),
Value::known(
op.account_after
.as_ref()
.map(|acc| acc.balance)
.unwrap_or_default(),
),
),
MPTProofType::StorageChanged | MPTProofType::CodeHashExists => (
ret.old_value.u8_rlc(randomness),
ret.new_value.u8_rlc(randomness),
),
_ => (F::zero(), F::zero()),
_ => (Value::known(F::zero()), Value::known(F::zero())),
};

ret.base = [
ret.base[0],
Some(ret.storage_key.u8_rlc(randomness)),
ret.base[2],
Some(op.account_root()),
Some(op.account_root_before()),
Some(new_value_f),
Some(old_value_f),
Some(Value::known(op.account_root())),
Some(Value::known(op.account_root_before())),
Some(new_value),
Some(old_value),
];

ret
Expand All @@ -382,12 +390,12 @@ impl<F: FieldExt> MPTEntry<F> {

ret.base = [
ret.base[0],
store_key,
store_key.map(Value::known),
ret.base[1],
Some(op.account_root()),
Some(op.account_root_before()),
Some(new_value_f),
Some(old_value_f),
Some(Value::known(op.account_root())),
Some(Value::known(op.account_root_before())),
Some(Value::known(new_value_f)),
Some(Value::known(old_value_f)),
];

ret
Expand Down Expand Up @@ -535,9 +543,7 @@ impl<F: FieldExt> MPTTable<F> {
)?;
}

let base_entries = entry
.base
.map(|entry| entry.map(Value::known).unwrap_or_else(Value::unknown));
let base_entries = entry.base.map(|entry| entry.unwrap_or_else(Value::unknown));

for (val, col) in base_entries.into_iter().zip([
config.address,
Expand Down
Loading

0 comments on commit 816767c

Please sign in to comment.