Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
[word lo/hi] keccak circuit to word (#1434)
Browse files Browse the repository at this point in the history
### Description

Support word lo-hi in keccak circuit

### Issue Link

#1385 

### Type of change

- [x] Breaking change (fix or feature that would cause existing
functionality to not work as expected)

### Contents

- Change the keccak circuit hash output format from RLC to word lo-hi.
- Add convenient methods `map` for Word. This can easily map two limbs
to other types.
- Add a constructor for the zero known value word.


### Rationale

### Testss

The following tests can pass if we remove math_gadget tests below

```
cargo test -p zkevm-circuits packed_multi_keccak_simple --features test
```

```
zkevm-circuits/src/evm_circuit/util/math_gadget/add_words.rs
zkevm-circuits/src/evm_circuit/util/math_gadget/cmp_words.rs
zkevm-circuits/src/evm_circuit/util/math_gadget/lt_word.rs
zkevm-circuits/src/evm_circuit/util/math_gadget/min_max_word.rs
zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs
zkevm-circuits/src/evm_circuit/util/math_gadget/mul_add_words.rs
```
  • Loading branch information
ChihChengLiang committed Jun 8, 2023
1 parent e9ac9fd commit 40c9958
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 33 deletions.
20 changes: 12 additions & 8 deletions zkevm-circuits/src/keccak_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use crate::{
split, split_uniform, transform, transform_to, Part,
},
table::{KeccakTable, LookupTable},
util::{Challenges, SubCircuit, SubCircuitConfig},
util::{
word::{self, WordExpr},
Challenges, SubCircuit, SubCircuitConfig,
},
witness,
};
use eth_types::Field;
Expand Down Expand Up @@ -101,7 +104,7 @@ impl<F: Field> SubCircuitConfig<F> for KeccakCircuitConfig<F> {
let is_final = keccak_table.is_enabled;
let length = keccak_table.input_len;
let data_rlc = keccak_table.input_rlc;
let hash_rlc = keccak_table.output_rlc;
let hash_word = keccak_table.output;

let normalize_3 = array_init::array_init(|_| meta.lookup_table_column());
let normalize_4 = array_init::array_init(|_| meta.lookup_table_column());
Expand Down Expand Up @@ -565,12 +568,12 @@ impl<F: Field> SubCircuitConfig<F> for KeccakCircuitConfig<F> {
});
}
let hash_bytes_le = hash_bytes.into_iter().rev().collect::<Vec<_>>();
let rlc = compose_rlc::expr(&hash_bytes_le, challenges.evm_word());

cb.condition(start_new_hash, |cb| {
cb.require_equal(
"hash rlc check",
rlc,
meta.query_advice(hash_rlc, Rotation::cur()),
cb.require_equal_word(
"output check",
word::Word32::new(hash_bytes_le.try_into().expect("32 limbs")).to_word(),
hash_word.map(|col| meta.query_advice(col, Rotation::cur())),
);
});
cb.gate(meta.query_fixed(q_round_last, Rotation::cur()))
Expand Down Expand Up @@ -921,7 +924,8 @@ impl<F: Field> KeccakCircuitConfig<F> {
Value::known(F::from(row.is_final as u64)),
row.data_rlc,
Value::known(F::from(row.length as u64)),
row.hash_rlc,
row.hash.lo(),
row.hash.hi(),
],
)?;

Expand Down
23 changes: 13 additions & 10 deletions zkevm-circuits/src/keccak_circuit/keccak_packed_multi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{cell_manager::*, param::*, util::*};
use crate::{evm_circuit::util::rlc, util::Challenges};
use crate::util::{word::Word, Challenges};
use eth_types::Field;
use halo2_proofs::{
circuit::Value,
Expand Down Expand Up @@ -67,7 +67,7 @@ pub(crate) struct KeccakRow<F: Field> {
pub(crate) cell_values: Vec<F>,
pub(crate) length: usize,
pub(crate) data_rlc: Value<F>,
pub(crate) hash_rlc: Value<F>,
pub(crate) hash: Word<Value<F>>,
}

/// Part
Expand Down Expand Up @@ -528,7 +528,7 @@ pub(crate) fn keccak<F: Field>(
let mut cell_managers = Vec::new();
let mut regions = Vec::new();

let mut hash_rlc = Value::known(F::ZERO);
let mut hash = Word::default();
let mut round_lengths = Vec::new();
let mut round_data_rlcs = Vec::new();
for round in 0..NUM_ROUNDS + 1 {
Expand Down Expand Up @@ -747,18 +747,21 @@ pub(crate) fn keccak<F: Field>(

// The rlc of the hash
let is_final = is_final_block && round == NUM_ROUNDS;
hash_rlc = if is_final {
hash = if is_final {
let hash_bytes_le = s
.into_iter()
.take(4)
.flat_map(|a| to_bytes::value(&unpack(a[0])))
.rev()
.collect::<Vec<_>>();
challenges
.evm_word()
.map(|challenge_value| rlc::value(&hash_bytes_le, challenge_value))

let word: Word<Value<F>> = Word::from(eth_types::Word::from_little_endian(
hash_bytes_le.as_slice(),
))
.map(Value::known);
word
} else {
Value::known(F::ZERO)
Word::default().into_value()
};

// The words to squeeze out
Expand Down Expand Up @@ -800,7 +803,7 @@ pub(crate) fn keccak<F: Field>(
is_final: is_final_block && round == NUM_ROUNDS && row_idx == 0,
length: round_lengths[round],
data_rlc: round_data_rlcs[round][row_idx],
hash_rlc,
hash,
cell_values: regions[round].rows[row_idx].clone(),
});
}
Expand Down Expand Up @@ -845,7 +848,7 @@ pub(crate) fn multi_keccak<F: Field>(
is_final: false,
length: 0usize,
data_rlc: Value::known(F::ZERO),
hash_rlc: Value::known(F::ZERO),
hash: Word::default().into_value(),
cell_values: Vec::new(),
});
}
Expand Down
22 changes: 7 additions & 15 deletions zkevm-circuits/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::{
evm_circuit::util::rlc,
exp_circuit::param::{OFFSET_INCREMENT, ROWS_PER_STEP},
impl_expr,
util::{build_tx_log_address, word, Challenges},
util::{build_tx_log_address, keccak, word, Challenges},
witness::{
Block, BlockContext, Bytecode, MptUpdateRow, MptUpdates, Rw, RwMap, RwRow, Transaction,
},
};
use bus_mapping::circuit_input_builder::{CopyDataType, CopyEvent, CopyStep, ExpEvent};
use core::iter::once;
use eth_types::{Field, ToLittleEndian, ToScalar, Word, U256};
use eth_types::{Field, ToScalar, U256};
use gadgets::{
binary_number::{BinaryNumberChip, BinaryNumberConfig},
util::{split_u256, split_u256_limb64},
Expand All @@ -23,7 +23,6 @@ use halo2_proofs::{
poly::Rotation,
};
use itertools::Itertools;
use keccak256::plain::Keccak;
use std::array;
use strum_macros::{EnumCount, EnumIter};

Expand Down Expand Up @@ -959,26 +958,19 @@ impl KeccakTable {
pub fn assignments<F: Field>(
input: &[u8],
challenges: &Challenges<Value<F>>,
) -> Vec<[Value<F>; 4]> {
) -> Vec<[Value<F>; 5]> {
let input_rlc = challenges
.keccak_input()
.map(|challenge| rlc::value(input.iter().rev(), challenge));
let input_len = F::from(input.len() as u64);
let mut keccak = Keccak::default();
keccak.update(input);
let output = keccak.digest();
let output_rlc = challenges.evm_word().map(|challenge| {
rlc::value(
&Word::from_big_endian(output.as_slice()).to_le_bytes(),
challenge,
)
});
let output = word::Word::from(keccak(input));

vec![[
Value::known(F::ONE),
input_rlc,
Value::known(input_len),
output_rlc,
Value::known(output.lo()),
Value::known(output.hi()),
]]
}

Expand All @@ -987,7 +979,7 @@ impl KeccakTable {
&self,
region: &mut Region<F>,
offset: usize,
values: [Value<F>; 4],
values: [Value<F>; 5],
) -> Result<(), Error> {
for (&column, value) in <KeccakTable as LookupTable<F>>::advice_columns(self)
.iter()
Expand Down
5 changes: 5 additions & 0 deletions zkevm-circuits/src/util/word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ impl<T: Clone> Word<T> {
pub fn map<T2: Clone>(&self, mut func: impl FnMut(T) -> T2) -> Word<T2> {
Word(WordLimbs::<T2, 2>::new([func(self.lo()), func(self.hi())]))
}
/// Convert the word to Known Value
pub fn into_value(self) -> Word<Value<T>> {
let [lo, hi] = self.0.limbs;
Word::new([Value::known(lo), Value::known(hi)])
}
}

impl<T> std::ops::Deref for Word<T> {
Expand Down

0 comments on commit 40c9958

Please sign in to comment.