Skip to content

Commit

Permalink
Merge branch 'v0.5' into zellic_kalos_39
Browse files Browse the repository at this point in the history
  • Loading branch information
z2trillion authored Aug 23, 2023
2 parents c930927 + 9bd1878 commit f929586
Show file tree
Hide file tree
Showing 85 changed files with 4,086 additions and 19,514 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
ethers-core = "0.17.0"
itertools = "0.10.5"
hash-circuit = { package = "poseidon-circuit", git = "https://github.com/scroll-tech/poseidon-circuit.git", branch = "scroll-dev-0619", features=['short']}
hash-circuit = { package = "poseidon-circuit", git = "https://github.com/scroll-tech/poseidon-circuit.git", branch = "scroll-dev-0723"}
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2022_09_10" }
rand = "0.8"
lazy_static = "1.4.0"
Expand All @@ -23,13 +23,15 @@ thiserror = "1.0"
log = "0.4"

[patch."https://github.com/privacy-scaling-explorations/halo2.git"]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "scroll-dev-0220" }
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }

[features]
# printout the layout of circuits for demo and some unittests
print_layout = ["halo2_proofs/dev-graph"]

[dev-dependencies]
mpt-zktrie = { git = "https://github.com/scroll-tech/zkevm-circuits.git" }
# mpt-zktrie = { path = "../scroll-circuits/zktrie" }
rand_chacha = "0.3.0"
plotters = "0.3"
bencher = "0.1"
Expand Down
4 changes: 4 additions & 0 deletions src/gadgets/is_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ impl IsZeroGadget {
"value is 0 or inverse_or_zero is inverse of value",
value.current() * (Query::one() - value.current() * inverse_or_zero.current()),
);
cb.assert_zero(
"inverse_or_zero is 0 or inverse_or_zero is inverse of value",
inverse_or_zero.current() * (Query::one() - value.current() * inverse_or_zero.current()),
);
Self {
value,
inverse_or_zero,
Expand Down
618 changes: 357 additions & 261 deletions src/gadgets/mpt_update.rs

Large diffs are not rendered by default.

28 changes: 5 additions & 23 deletions src/gadgets/mpt_update/nonexistence_proof.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{
constraint_builder::{AdviceColumn, ConstraintBuilder, Query, SecondPhaseAdviceColumn},
gadgets::{is_zero::IsZeroGadget, poseidon::PoseidonLookup},
types::HashDomain,
};
use halo2_proofs::{arithmetic::FieldExt, circuit::Region, halo2curves::bn256::Fr};
use halo2_proofs::arithmetic::FieldExt;

pub fn configure<F: FieldExt>(
cb: &mut ConstraintBuilder<F>,
Expand All @@ -12,7 +13,6 @@ pub fn configure<F: FieldExt>(
key_equals_other_key: IsZeroGadget,
hash: AdviceColumn,
hash_is_zero: IsZeroGadget,
other_key_hash: AdviceColumn,
other_leaf_data_hash: AdviceColumn,
poseidon: &impl PoseidonLookup,
) {
Expand All @@ -38,32 +38,14 @@ pub fn configure<F: FieldExt>(

cb.condition(is_type_1, |cb| {
cb.poseidon_lookup(
"other_key_hash == h(1, other_key)",
[Query::one(), other_key.current(), other_key_hash.current()],
poseidon,
);
cb.poseidon_lookup(
"hash == h(key_hash, other_leaf_data_hash)",
"hash == h(other_key, other_leaf_data_hash)",
[
other_key_hash.current(),
other_key.current(),
other_leaf_data_hash.current(),
Query::from(u64::from(HashDomain::Leaf)),
hash.current(),
],
poseidon,
);
});
}

pub fn assign(
region: &mut Region<'_, Fr>,
offset: usize,
(key_equals_other_key, key_minus_other_key): (IsZeroGadget, Fr),
(final_hash_is_zero, final_hash): (IsZeroGadget, Fr),
(other_key_hash_row, other_key_hash): (AdviceColumn, Fr),
(other_leaf_data_hash_row, other_leaf_data_hash): (AdviceColumn, Fr),
) {
key_equals_other_key.assign(region, offset, key_minus_other_key);
final_hash_is_zero.assign(region, offset, final_hash);
other_key_hash_row.assign(region, offset, other_key_hash);
other_leaf_data_hash_row.assign(region, offset, other_leaf_data_hash);
}
2 changes: 1 addition & 1 deletion src/gadgets/mpt_update/path.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use strum_macros::EnumIter;

#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Hash)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, EnumIter, Hash)]
pub enum PathType {
Start, // Used as boundary marker between updates
Common, // Hashes for both the old and new path are being updated.
Expand Down
20 changes: 19 additions & 1 deletion src/gadgets/mpt_update/segment.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::types::HashDomain;
use crate::MPTProofType;
use std::collections::HashMap;
use strum_macros::EnumIter;

#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Hash)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, EnumIter, Hash)]
pub enum SegmentType {
Start, // Boundary marker between updates
AccountTrie,
Expand Down Expand Up @@ -136,3 +137,20 @@ pub fn transitions(proof: MPTProofType) -> HashMap<SegmentType, Vec<SegmentType>
MPTProofType::AccountDestructed => [].into(),
}
}

pub fn domains(segment_type: SegmentType) -> Vec<HashDomain> {
match segment_type {
SegmentType::Start => vec![HashDomain::Pair],

SegmentType::AccountTrie | SegmentType::StorageTrie => vec![
HashDomain::Branch0,
HashDomain::Branch1,
HashDomain::Branch2,
HashDomain::Branch3,
],
SegmentType::AccountLeaf0 | SegmentType::StorageLeaf0 => vec![HashDomain::Leaf],
SegmentType::AccountLeaf1 | SegmentType::AccountLeaf2 | SegmentType::AccountLeaf3 => {
vec![HashDomain::AccountFields]
}
}
}
8 changes: 7 additions & 1 deletion src/gadgets/mpt_update/word_rlc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
byte_representation::{BytesLookup, RlcLookup},
poseidon::PoseidonLookup,
},
types::HashDomain,
util::{rlc, u256_hi_lo},
};
use ethers_core::types::U256;
Expand Down Expand Up @@ -34,7 +35,12 @@ pub fn configure<F: FieldExt>(
);
cb.poseidon_lookup(
"word_hash = poseidon(high, low)",
[high.current(), low.current(), word_hash.current()],
[
high.current(),
low.current(),
Query::from(u64::from(HashDomain::Pair)),
word_hash.current(),
],
poseidon,
);

Expand Down
12 changes: 6 additions & 6 deletions src/gadgets/one_hot.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use crate::constraint_builder::{BinaryColumn, BinaryQuery, ConstraintBuilder, Query};
use halo2_proofs::{arithmetic::FieldExt, circuit::Region, plonk::ConstraintSystem};
use std::{cmp::Eq, collections::HashMap, hash::Hash};
use std::{cmp::Eq, collections::BTreeMap, hash::Hash};
use strum::IntoEnumIterator;

// One hot encoding for an enum with T::COUNT variants with COUNT - 1 binary columns.
// It's useful to have 1 less column so that the default assigment for the gadget
// is valid (it will represent the first variant).
#[derive(Clone)]
pub struct OneHot<T: Hash> {
columns: HashMap<T, BinaryColumn>,
pub struct OneHot<T: Hash + PartialOrd + Ord> {
columns: BTreeMap<T, BinaryColumn>,
}

impl<T: IntoEnumIterator + Hash + Eq> OneHot<T> {
impl<T: IntoEnumIterator + Hash + Eq + PartialOrd + Ord> OneHot<T> {
pub fn configure<F: FieldExt>(
cs: &mut ConstraintSystem<F>,
cb: &mut ConstraintBuilder<F>,
) -> Self {
let mut columns = HashMap::new();
let mut columns = BTreeMap::new();
for variant in Self::nonfirst_variants() {
columns.insert(variant, cb.binary_columns::<1>(cs)[0]);
}
Expand Down Expand Up @@ -75,7 +75,7 @@ impl<T: IntoEnumIterator + Hash + Eq> OneHot<T> {
* self
.columns
.get(&t)
.map_or_else(|| !self.sum(-1), BinaryColumn::current)
.map_or_else(|| !self.sum(-1), BinaryColumn::previous)
})
}

Expand Down
40 changes: 24 additions & 16 deletions src/gadgets/poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use crate::constraint_builder::{AdviceColumn, ConstraintBuilder, FixedColumn, Query};
#[cfg(test)]
use crate::util::hash as poseidon_hash;
use halo2_proofs::{
arithmetic::FieldExt,
plonk::{Advice, Column, Fixed},
};
#[cfg(test)]
use halo2_proofs::{circuit::Region, halo2curves::bn256::Fr, plonk::ConstraintSystem};
#[cfg(test)]
use hash_circuit::hash::Hashable;

/// Lookup represent the poseidon table in zkevm circuit
pub trait PoseidonLookup {
fn lookup_columns(&self) -> (FixedColumn, [AdviceColumn; 5]) {
fn lookup_columns(&self) -> (FixedColumn, [AdviceColumn; 6]) {
let (fixed, adv) = self.lookup_columns_generic();
(FixedColumn(fixed), adv.map(AdviceColumn))
}
fn lookup_columns_generic(&self) -> (Column<Fixed>, [Column<Advice>; 5]) {
fn lookup_columns_generic(&self) -> (Column<Fixed>, [Column<Advice>; 6]) {
let (fixed, adv) = self.lookup_columns();
(fixed.0, adv.map(|col| col.0))
}
Expand All @@ -24,19 +24,21 @@ impl<F: FieldExt> ConstraintBuilder<F> {
pub fn poseidon_lookup(
&mut self,
name: &'static str,
queries: [Query<F>; 3],
[left, right, domain, hash]: [Query<F>; 4],
poseidon: &impl PoseidonLookup,
) {
let extended_queries = [
Query::one(),
queries[2].clone(),
queries[0].clone(),
queries[1].clone(),
hash,
left,
right,
Query::zero(),
domain,
Query::one(),
];

let (q_enable, [hash, left, right, control, head_mark]) = poseidon.lookup_columns();
let (q_enable, [hash, left, right, control, domain_spec, head_mark]) =
poseidon.lookup_columns();

self.add_lookup(
name,
Expand All @@ -47,6 +49,7 @@ impl<F: FieldExt> ConstraintBuilder<F> {
left.current(),
right.current(),
control.current(),
domain_spec.current(),
head_mark.current(),
],
)
Expand All @@ -61,36 +64,40 @@ pub struct PoseidonTable {
right: AdviceColumn,
hash: AdviceColumn,
control: AdviceColumn,
domain_spec: AdviceColumn,
head_mark: AdviceColumn,
}

#[cfg(test)]
impl PoseidonTable {
pub fn configure<F: FieldExt>(cs: &mut ConstraintSystem<F>) -> Self {
let [hash, left, right, control, head_mark] =
[0; 5].map(|_| AdviceColumn(cs.advice_column()));
let [hash, left, right, control, domain_spec, head_mark] =
[0; 6].map(|_| AdviceColumn(cs.advice_column()));
Self {
left,
right,
hash,
control,
head_mark,
domain_spec,
q_enable: FixedColumn(cs.fixed_column()),
}
}

pub fn load(&self, region: &mut Region<'_, Fr>, hash_traces: &[(Fr, Fr, Fr)]) {
pub fn load(&self, region: &mut Region<'_, Fr>, hash_traces: &[([Fr; 2], Fr, Fr)]) {
for (offset, hash_trace) in hash_traces.iter().enumerate() {
assert!(
poseidon_hash(hash_trace.0, hash_trace.1) == hash_trace.2,
Hashable::hash_with_domain([hash_trace.0[0], hash_trace.0[1]], hash_trace.1)
== hash_trace.2,
"{:?}",
(hash_trace.0, hash_trace.1, hash_trace.2)
);
for (column, value) in [
(self.left, hash_trace.0),
(self.right, hash_trace.1),
(self.left, hash_trace.0[0]),
(self.right, hash_trace.0[1]),
(self.hash, hash_trace.2),
(self.control, Fr::zero()),
(self.domain_spec, hash_trace.1),
(self.head_mark, Fr::one()),
] {
column.assign(region, offset, value);
Expand All @@ -102,14 +109,15 @@ impl PoseidonTable {

#[cfg(test)]
impl PoseidonLookup for PoseidonTable {
fn lookup_columns(&self) -> (FixedColumn, [AdviceColumn; 5]) {
fn lookup_columns(&self) -> (FixedColumn, [AdviceColumn; 6]) {
(
self.q_enable,
[
self.hash,
self.left,
self.right,
self.control,
self.domain_spec,
self.head_mark,
],
)
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
pub mod constraint_builder;
pub mod gadgets;
mod mpt_table;
#[cfg(test)]
mod tests;
pub mod types;
mod util;

Expand Down
Loading

0 comments on commit f929586

Please sign in to comment.