Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: feat: support uniarg to reduce instruction number #299

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 0 additions & 3 deletions TODO.md

This file was deleted.

23 changes: 15 additions & 8 deletions crates/cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub(crate) struct Config {
}

impl Config {
#[cfg(debug_assertions)]
fn image_consistent_check(&self, wasm_image: &[u8]) -> anyhow::Result<()> {
if let Some(expected_wasm_image_md5) = &self.wasm_image_md5 {
let wasm_image_md5 = format!("{:x}", md5::compute(wasm_image));
Expand All @@ -94,6 +95,7 @@ impl Config {
Ok(())
}

#[cfg(debug_assertions)]
fn params_consistent_check(&self, params: &[u8]) -> anyhow::Result<()> {
let params_md5 = format!("{:x}", md5::compute(params));

Expand Down Expand Up @@ -146,6 +148,7 @@ impl Config {
let mut buf = Vec::new();
File::open(wasm_image)?.read_to_end(&mut buf)?;

#[cfg(debug_assertions)]
self.image_consistent_check(&buf)?;

ZkWasmLoader::parse_module(&buf)
Expand All @@ -157,6 +160,7 @@ impl Config {
let mut buf = Vec::new();
File::open(path)?.read_to_end(&mut buf)?;

#[cfg(debug_assertions)]
self.params_consistent_check(&buf)?;

let params = Params::<G1Affine>::read(&mut Cursor::new(&mut buf))?;
Expand All @@ -167,18 +171,21 @@ impl Config {
fn read_circuit_data(
&self,
path: &PathBuf,
expected_md5: &str,
_expected_md5: &str,
) -> anyhow::Result<CircuitData<G1Affine>> {
let mut buf = Vec::new();
File::open(path)?.read_to_end(&mut buf)?;
#[cfg(debug_assertions)]
{
let mut buf = Vec::new();
File::open(path)?.read_to_end(&mut buf)?;

let circuit_data_md5 = format!("{:x}", md5::compute(&buf));
let circuit_data_md5 = format!("{:x}", md5::compute(&buf));

if circuit_data_md5 != expected_md5 {
anyhow::bail!(
"Circuit data is inconsistent with the one used to build the circuit. \
if circuit_data_md5 != _expected_md5 {
anyhow::bail!(
"Circuit data is inconsistent with the one used to build the circuit. \
Maybe you have changed the circuit data after setup the circuit?",
);
);
}
}

let circuit_data = CircuitData::<G1Affine>::read(&mut File::open(path)?)?;
Expand Down
3 changes: 2 additions & 1 deletion crates/specs/src/configure_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use serde::Serialize;
// A wasm page size is 64KB
pub const WASM_BYTES_PER_PAGE: u64 = 64 * 1024_u64;

const WASM_32_MAXIMAL_PAGES_DEFAULT: u32 = 65536;
// Limit page size in u16 range
pub const WASM_32_MAXIMAL_PAGES_DEFAULT: u32 = 65535;

#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct ConfigureTable {
Expand Down
54 changes: 31 additions & 23 deletions crates/specs/src/encode/br_table.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
use num_bigint::BigUint;
use num_traits::One;
use static_assertions::const_assert;

use crate::brtable::BrTableEntry;
use crate::brtable::ElemEntry;
use crate::brtable::IndirectClass;
use crate::encode::COMMON_RANGE_OFFSET;
use crate::encode::instruction_table::FID_BITS;
use crate::encode::instruction_table::IID_BITS;
use crate::encode::U32_BITS;

use super::FromBn;

const INDIRECT_CLASS_SHIFT: u32 = 192;
lazy_static! {
static ref INDIRECT_CLASS_SHIFT: BigUint = BigUint::from(1u64) << 192;
static ref INDIRECT_CLASS_SHIFT_BN: BigUint = BigUint::one() << INDIRECT_CLASS_SHIFT;
}

pub(crate) const BR_TABLE_ENCODE_BOUNDARY: u32 = 224;
pub const BR_TABLE_ENCODE_BOUNDARY: u32 = 224;
// Tag only includes 1 bit(BrTable or Elem)
const_assert!(INDIRECT_CLASS_SHIFT < BR_TABLE_ENCODE_BOUNDARY);

pub fn encode_br_table_entry<T: FromBn>(
fid: T,
Expand All @@ -21,37 +28,38 @@ pub fn encode_br_table_entry<T: FromBn>(
keep: T,
dst_pc: T,
) -> T {
const FID_SHIFT: u32 = IID_SHIFT + COMMON_RANGE_OFFSET;
const IID_SHIFT: u32 = INDEX_SHIFT + COMMON_RANGE_OFFSET;
const INDEX_SHIFT: u32 = DROP_SHIFT + COMMON_RANGE_OFFSET;
const DROP_SHIFT: u32 = KEEP_SHIFT + COMMON_RANGE_OFFSET;
const KEEP_SHIFT: u32 = DST_PC_SHIFT + COMMON_RANGE_OFFSET;
const FID_SHIFT: u32 = IID_SHIFT + IID_BITS;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add assertion that IID_BITS, FID_BITS are one of (u8, u16, ucommon), so we know they are limited by range check in circuit.

const IID_SHIFT: u32 = INDEX_SHIFT + U32_BITS;
const INDEX_SHIFT: u32 = DROP_SHIFT + U32_BITS;
const DROP_SHIFT: u32 = KEEP_SHIFT + U32_BITS;
const KEEP_SHIFT: u32 = DST_PC_SHIFT + U32_BITS;
const DST_PC_SHIFT: u32 = 0;

assert!(FID_SHIFT + COMMON_RANGE_OFFSET <= BR_TABLE_ENCODE_BOUNDARY);
assert!(FID_SHIFT + FID_BITS <= INDIRECT_CLASS_SHIFT);

T::from_bn(&(BigUint::from(IndirectClass::BrTable as u64))) * T::from_bn(&INDIRECT_CLASS_SHIFT)
+ fid * T::from_bn(&(BigUint::from(1u64) << FID_SHIFT))
+ iid * T::from_bn(&(BigUint::from(1u64) << IID_SHIFT))
+ index * T::from_bn(&(BigUint::from(1u64) << INDEX_SHIFT))
+ drop * T::from_bn(&(BigUint::from(1u64) << DROP_SHIFT))
+ keep * T::from_bn(&(BigUint::from(1u64) << KEEP_SHIFT))
T::from_bn(&(BigUint::from(IndirectClass::BrTable as u64)))
* T::from_bn(&INDIRECT_CLASS_SHIFT_BN)
+ fid * T::from_bn(&(BigUint::one() << FID_SHIFT))
+ iid * T::from_bn(&(BigUint::one() << IID_SHIFT))
+ index * T::from_bn(&(BigUint::one() << INDEX_SHIFT))
+ drop * T::from_bn(&(BigUint::one() << DROP_SHIFT))
+ keep * T::from_bn(&(BigUint::one() << KEEP_SHIFT))
+ dst_pc
}

pub fn encode_elem_entry<T: FromBn>(table_idx: T, type_idx: T, offset: T, func_idx: T) -> T {
const TABLE_INDEX_SHIFT: u32 = TYPE_INDEX_SHIFT + COMMON_RANGE_OFFSET;
const TYPE_INDEX_SHIFT: u32 = OFFSET_SHIFT + COMMON_RANGE_OFFSET;
const OFFSET_SHIFT: u32 = FUNC_INDEX + COMMON_RANGE_OFFSET;
const TABLE_INDEX_SHIFT: u32 = TYPE_INDEX_SHIFT + U32_BITS;
const TYPE_INDEX_SHIFT: u32 = OFFSET_SHIFT + U32_BITS;
const OFFSET_SHIFT: u32 = FUNC_INDEX + FID_BITS;
const FUNC_INDEX: u32 = 0;

assert!(TABLE_INDEX_SHIFT + COMMON_RANGE_OFFSET <= BR_TABLE_ENCODE_BOUNDARY);
assert!(TABLE_INDEX_SHIFT + U32_BITS <= INDIRECT_CLASS_SHIFT);

T::from_bn(&(BigUint::from(IndirectClass::CallIndirect as u64)))
* T::from_bn(&INDIRECT_CLASS_SHIFT)
+ table_idx * T::from_bn(&(BigUint::from(1u64) << TABLE_INDEX_SHIFT))
+ type_idx * T::from_bn(&(BigUint::from(1u64) << TYPE_INDEX_SHIFT))
+ offset * T::from_bn(&(BigUint::from(1u64) << OFFSET_SHIFT))
* T::from_bn(&INDIRECT_CLASS_SHIFT_BN)
+ table_idx * T::from_bn(&(BigUint::one() << TABLE_INDEX_SHIFT))
+ type_idx * T::from_bn(&(BigUint::one() << TYPE_INDEX_SHIFT))
+ offset * T::from_bn(&(BigUint::one() << OFFSET_SHIFT))
+ func_idx
}

Expand Down
21 changes: 12 additions & 9 deletions crates/specs/src/encode/frame_table.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use num_bigint::BigUint;
use num_bigint::ToBigUint;
use num_traits::One;

use crate::encode::COMMON_RANGE_OFFSET;
use crate::encode::instruction_table::FID_BITS;
use crate::encode::instruction_table::IID_BITS;
use crate::encode::U32_BITS;
use crate::jtable::CalledFrameTableEntry;
use crate::jtable::FrameTableEntryInternal;
use crate::jtable::InheritedFrameTableEntry;
Expand All @@ -15,16 +18,16 @@ pub fn encode_frame_table_entry<T: FromBn>(
fid: T,
iid: T,
) -> T {
const FRAME_ID_SHIFT: u32 = LAST_JUMP_FRAME_ID_SHIFT + COMMON_RANGE_OFFSET;
const LAST_JUMP_FRAME_ID_SHIFT: u32 = CALLEE_FID + COMMON_RANGE_OFFSET;
const CALLEE_FID: u32 = FID_SHIFT + COMMON_RANGE_OFFSET;
const FID_SHIFT: u32 = IID_SHIFT + COMMON_RANGE_OFFSET;
const FRAME_ID_SHIFT: u32 = LAST_JUMP_FRAME_ID_SHIFT + U32_BITS;
const LAST_JUMP_FRAME_ID_SHIFT: u32 = CALLEE_FID + FID_BITS;
const CALLEE_FID: u32 = FID_SHIFT + FID_BITS;
const FID_SHIFT: u32 = IID_SHIFT + IID_BITS;
const IID_SHIFT: u32 = 0;

frame_id * T::from_bn(&(1u64.to_biguint().unwrap() << FRAME_ID_SHIFT))
+ last_frame_id * T::from_bn(&(1u64.to_biguint().unwrap() << LAST_JUMP_FRAME_ID_SHIFT))
+ callee_fid * T::from_bn(&(1u64.to_biguint().unwrap() << CALLEE_FID))
+ fid * T::from_bn(&(1u64.to_biguint().unwrap() << FID_SHIFT))
frame_id * T::from_bn(&(BigUint::one() << FRAME_ID_SHIFT))
+ last_frame_id * T::from_bn(&(BigUint::one() << LAST_JUMP_FRAME_ID_SHIFT))
+ callee_fid * T::from_bn(&(BigUint::one() << CALLEE_FID))
+ fid * T::from_bn(&(BigUint::one() << FID_SHIFT))
+ iid
}

Expand Down
4 changes: 2 additions & 2 deletions crates/specs/src/encode/image_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::encode::instruction_table::INSTRUCTION_ENCODE_BOUNDARY;

use super::FromBn;

const CLASS_SHIFT: u32 = 224;
const CLASS_SHIFT: u32 = 250;

#[derive(Clone, Copy)]
pub enum ImageTableEncoder {
Expand All @@ -22,7 +22,7 @@ const_assert!(BR_TABLE_ENCODE_BOUNDARY <= CLASS_SHIFT);
const_assert!(INIT_MEMORY_ENCODE_BOUNDARY <= CLASS_SHIFT);

lazy_static! {
static ref INSTRUCTION_TAG: BigUint = (ImageTableEncoder::Instruction as u64)
pub static ref INSTRUCTION_TAG: BigUint = (ImageTableEncoder::Instruction as u64)
.to_biguint()
.unwrap()
<< CLASS_SHIFT;
Expand Down
20 changes: 12 additions & 8 deletions crates/specs/src/encode/instruction_table.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
use num_bigint::BigUint;
use num_bigint::ToBigUint;
use num_traits::One;
use static_assertions::const_assert;

use crate::encode::COMMON_RANGE_OFFSET;
use crate::itable::InstructionTableEntry;
use crate::itable::Opcode;
use crate::itable::OPCODE_SHIFT;

use super::FromBn;

pub(crate) const INSTRUCTION_ENCODE_BOUNDARY: u32 = 224;
pub const INSTRUCTION_ENCODE_BOUNDARY: u32 = 250;
pub(crate) const IID_BITS: u32 = 16;
pub(crate) const FID_BITS: u32 = 16;
const_assert!(OPCODE_SHIFT + IID_BITS + FID_BITS <= INSTRUCTION_ENCODE_BOUNDARY);

pub fn encode_instruction_table_entry<T: FromBn>(fid: T, iid: T, opcode: T) -> T {
const FID_SHIFT: u32 = IID_SHIFT + COMMON_RANGE_OFFSET;
const FID_SHIFT: u32 = IID_SHIFT + IID_BITS;
const IID_SHIFT: u32 = OPCODE_SHIFT;

assert!(FID_SHIFT + COMMON_RANGE_OFFSET <= INSTRUCTION_ENCODE_BOUNDARY);

fid * T::from_bn(&(1u64.to_biguint().unwrap() << FID_SHIFT))
+ iid * T::from_bn(&(1u64.to_biguint().unwrap() << IID_SHIFT))
fid * T::from_bn(&(BigUint::one() << FID_SHIFT))
+ iid * T::from_bn(&(BigUint::one() << IID_SHIFT))
+ opcode
}

impl InstructionTableEntry {
pub(crate) fn encode(fid: u32, iid: u32, opcode: &Opcode) -> BigUint {
assert!(fid < 1 << FID_BITS);
assert!(iid < 1 << IID_BITS);

encode_instruction_table_entry(BigUint::from(fid), BigUint::from(iid), opcode.into())
}
}
6 changes: 3 additions & 3 deletions crates/specs/src/encode/memory_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use num_traits::One;
use static_assertions::const_assert;

use super::FromBn;
use crate::encode::COMMON_RANGE_OFFSET;
use crate::encode::U32_BITS;

const _END_SHIFT: u32 = OFFSET_SHIFT + COMMON_RANGE_OFFSET;
const OFFSET_SHIFT: u32 = LOCATION_TYPE_SHIFT + COMMON_RANGE_OFFSET;
const _END_SHIFT: u32 = OFFSET_SHIFT + U32_BITS;
const OFFSET_SHIFT: u32 = LOCATION_TYPE_SHIFT + U32_BITS;
const LOCATION_TYPE_SHIFT: u32 = IS_I32_SHIFT + 1;
const IS_I32_SHIFT: u32 = 0;

Expand Down
2 changes: 1 addition & 1 deletion crates/specs/src/encode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub mod instruction_table;
pub mod memory_table;
pub mod opcode;

pub(crate) const COMMON_RANGE_OFFSET: u32 = 32;
pub(crate) const U32_BITS: u32 = 32;

pub trait FromBn: Sized + Add<Self, Output = Self> + Mul<Self, Output = Self> {
fn zero() -> Self;
Expand Down
Loading
Loading