Skip to content

Commit

Permalink
fix ZELLIC-ZK1-4 Missing range checks in MulAdd chip (scroll-tech#685)
Browse files Browse the repository at this point in the history
* add range check

* fix unconstrained

* sort fields

* merge import

* unnecessary clone

* add range check

* add range table

* replace Range256Table of rlp_circuit_fsm

* replace u16_table of tx_circuit

* use TableColumn

* merge scroll-tech#694

* add type alias

* use type alias

* fix import

* merge scroll-tech#690 and reduce LtChip use

* missing q_enable

* annotate lookup column

* fix dev table load

* add RangeCheck

* minimal bug reproduce

* fix test

* clippy

* clippy

* remove print

* fix exp_circuit

* fix offset

* add u128 and cleanup

* revert to u8 table lookup

* use u8 table lookup for u8 cell

* fix dev_load

* constrain unused cell == 0

* add explain for padding

* update unusable_rows

* performance fix

* use Rotation::cur()

* fix incorrect constraint for unused_cells

* add comments describe row used

* add comments to clarify the ranges

Co-authored-by: Aurélien Nicolas <[email protected]>

* rename conflicted names

Co-authored-by: Aurélien Nicolas <[email protected]>

* remove incorrect comment

Co-authored-by: Aurélien Nicolas <[email protected]>

* explain why OFFSET_INCREMENT is 8usize

* use u16 for carry_lo/hi

* fix gadget test

* remove unused cell constrain

---------

Co-authored-by: DreamWuGit <[email protected]>
Co-authored-by: Aurélien Nicolas <[email protected]>
  • Loading branch information
3 people authored Aug 16, 2023
1 parent 4c0bbb7 commit b20bed2
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 149 deletions.
39 changes: 39 additions & 0 deletions eth-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ pub trait ToLittleEndian {
fn to_le_bytes(&self) -> [u8; 32];
}

/// Trait used to convert a scalar value to a 16x u16 array in little endian.
pub trait ToU16LittleEndian {
/// Convert the value to a 16x u16 array in little endian.
fn to_le_u16_array(&self) -> [u16; 16];
}

// We use our own declaration of another U256 in order to implement a custom
// deserializer that can parse U256 when returned by structLogs fields in geth
// debug_trace* methods, which don't contain the `0x` prefix.
Expand Down Expand Up @@ -159,6 +165,26 @@ impl ToLittleEndian for U256 {
}
}

impl ToU16LittleEndian for U256 {
/// Encode the value as 16x u16 array in little endian.
///
/// eg. 0xaabb_ccdd_eeff_0011_2233_4455_6677_8899_bbaa_ddcc_ffee_1100_3322_5544_7766_9988
/// -> [
/// 0x9988, 0x7766, 0x5544, 0x3322, 0x1100, 0xffee, 0xddcc, 0xbbaa,
/// 0x8899, 0x6677, 0x4455, 0x2233, 0x0011, 0xeeff, 0xccdd, 0xaabb,
/// ]
fn to_le_u16_array(&self) -> [u16; 16] {
let mut u16_array: [u16; 16] = [0; 16];
for (idx, u64_cell) in self.0.into_iter().enumerate() {
u16_array[idx * 4] = (u64_cell & 0xffff) as u16;
u16_array[idx * 4 + 1] = ((u64_cell >> 16) & 0xffff) as u16;
u16_array[idx * 4 + 2] = ((u64_cell >> 32) & 0xffff) as u16;
u16_array[idx * 4 + 3] = ((u64_cell >> 48) & 0xffff) as u16;
}
u16_array
}
}

impl<F: Field> ToScalar<F> for U256 {
fn to_scalar(&self) -> Option<F> {
let mut bytes = [0u8; 32];
Expand Down Expand Up @@ -488,6 +514,19 @@ mod tests {
use super::*;
use crate::evm_types::{memory::Memory, opcode_ids::OpcodeId, stack::Stack};

#[test]
fn test_to_u16_array() {
assert_eq!(
U256::from_str("0xaabbccddeeff00112233445566778899bbaaddccffee11003322554477669988")
.unwrap()
.to_le_u16_array(),
[
0x9988, 0x7766, 0x5544, 0x3322, 0x1100, 0xffee, 0xddcc, 0xbbaa, 0x8899, 0x6677,
0x4455, 0x2233, 0x0011, 0xeeff, 0xccdd, 0xaabb
]
);
}

#[test]
fn deserialize_geth_exec_trace2() {
let trace_json = r#"
Expand Down
1 change: 1 addition & 0 deletions gadgets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod is_zero;
pub mod less_than;
pub mod monotone;
pub mod mul_add;
pub mod range;
pub mod util;

use eth_types::Field;
Expand Down
Loading

0 comments on commit b20bed2

Please sign in to comment.