diff --git a/crates/mipsevm/Cargo.toml b/crates/mipsevm/Cargo.toml index ed1caa3..a126169 100644 --- a/crates/mipsevm/Cargo.toml +++ b/crates/mipsevm/Cargo.toml @@ -38,7 +38,7 @@ proptest = "1.4.0" [features] tracing = ["dep:tracing"] -#simd-keccak = ["dep:keccak256-aarch64-simd"] +simd-keccak = ["dep:keccak256-aarch64-simd"] [[bench]] name = "memory" diff --git a/crates/mipsevm/src/memory.rs b/crates/mipsevm/src/memory.rs index 4258c69..9159f32 100644 --- a/crates/mipsevm/src/memory.rs +++ b/crates/mipsevm/src/memory.rs @@ -64,7 +64,7 @@ impl Memory { } // Find the page and invalidate the address within it. - match self.page_lookup(address as u64 >> page::PAGE_ADDRESS_SIZE) { + match self.page_lookup(address >> page::PAGE_ADDRESS_SIZE) { Some(page) => { let mut page = page.borrow_mut(); let prev_valid = !page.valid[1]; @@ -85,7 +85,8 @@ impl Memory { } // Find the generalized index of the first page covering the address - let mut g_index = (1u64 << (64 - page::PAGE_ADDRESS_SIZE)) | (address >> page::PAGE_ADDRESS_SIZE); + let mut g_index = + (1u64 << (64 - page::PAGE_ADDRESS_SIZE)) | (address >> page::PAGE_ADDRESS_SIZE); // Invalidate all nodes in the branch while g_index > 0 { self.nodes.insert(g_index, None); @@ -277,7 +278,7 @@ impl Memory { anyhow::bail!("Unaligned memory access: {:x}", address); } - match self.page_lookup(address as u64 >> page::PAGE_ADDRESS_SIZE as u64) { + match self.page_lookup(address >> page::PAGE_ADDRESS_SIZE as u64) { Some(page) => { let page_address = address as usize & page::PAGE_ADDRESS_MASK; Ok(u32::from_be_bytes( @@ -344,7 +345,7 @@ impl Memory { anyhow::bail!("Unaligned memory access: {:x}", address); } - match self.page_lookup(address as u64 >> page::PAGE_ADDRESS_SIZE as u64) { + match self.page_lookup(address >> page::PAGE_ADDRESS_SIZE as u64) { Some(page) => { let page_address = address as usize & page::PAGE_ADDRESS_MASK; Ok(u64::from_be_bytes( @@ -452,8 +453,8 @@ impl Default for PageEntry { impl Serialize for Memory { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { let mut page_entries: Vec = self .pages @@ -471,8 +472,8 @@ impl Serialize for Memory { impl<'de> Deserialize<'de> for Memory { fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, + where + D: serde::Deserializer<'de>, { let page_entries: Vec = Vec::deserialize(deserializer)?; @@ -525,7 +526,7 @@ impl<'a> Read for MemoryReader<'a> { let start = self.address as usize & page::PAGE_ADDRESS_MASK; let mut end = page::PAGE_SIZE; - if page_index == (end_address as u64 >> page::PAGE_ADDRESS_SIZE as u64) { + if page_index == (end_address >> page::PAGE_ADDRESS_SIZE as u64) { end = end_address as usize & page::PAGE_ADDRESS_MASK; } let n = end - start; @@ -664,12 +665,12 @@ mod test { keccak_concat_hashes(z.into(), z.into()).into(), keccak_concat_hashes(z.into(), p3.into()).into(), ) - .into(), + .into(), keccak_concat_hashes( keccak_concat_hashes(z.into(), p5.into()).into(), keccak_concat_hashes(p6.into(), z.into()).into(), ) - .into(), + .into(), ); let r2 = memory .merkleize_subtree(1 << (page::PAGE_KEY_SIZE - 3)) diff --git a/crates/mipsevm/src/mips/instrumented.rs b/crates/mipsevm/src/mips/instrumented.rs index 6e9a901..e30ebc8 100644 --- a/crates/mipsevm/src/mips/instrumented.rs +++ b/crates/mipsevm/src/mips/instrumented.rs @@ -1,9 +1,9 @@ //! This module contains the [InstrumentedState] definition. +use crate::memory::PROOF_LEN; use crate::{traits::PreimageOracle, Address, State, StepWitness}; use anyhow::Result; use std::io::{BufWriter, Write}; -use crate::memory::PROOF_LEN; pub(crate) const MIPS_EBADF: u64 = 0x9; pub(crate) const MIPS_EINVAL: u64 = 0x16; @@ -39,10 +39,10 @@ pub struct InstrumentedState { } impl InstrumentedState - where - O: Write, - E: Write, - P: PreimageOracle, +where + O: Write, + E: Write, + P: PreimageOracle, { pub fn new(state: State, oracle: P, std_out: O, std_err: E) -> Self { Self { diff --git a/crates/mipsevm/src/mips/mips_vm.rs b/crates/mipsevm/src/mips/mips_vm.rs index 2940a70..62e948a 100644 --- a/crates/mipsevm/src/mips/mips_vm.rs +++ b/crates/mipsevm/src/mips/mips_vm.rs @@ -1,5 +1,6 @@ //! This module contains the MIPS VM implementation for the [InstrumentedState]. +use crate::utils::sign_extend; use crate::{ memory::MemoryReader, mips::instrumented::{MIPS_EBADF, MIPS_EINVAL}, @@ -9,13 +10,12 @@ use crate::{ }; use anyhow::Result; use std::io::{self, BufReader, Read, Write}; -use crate::utils::sign_extend; impl InstrumentedState - where - O: Write, - E: Write, - P: PreimageOracle, +where + O: Write, + E: Write, + P: PreimageOracle, { /// Read the preimage for the given key and offset from the [PreimageOracle] server. /// @@ -92,7 +92,8 @@ impl InstrumentedState let link_reg = if opcode == 3 { 31 } else { 0 }; // Take the top 4 bits of the next PC (its 256MB region), and concatenate with the // 26-bit offset - let target = self.state.next_pc & 0xFFFFFFFFF0000000 | (((instruction & 0x03FFFFFF) << 2) as u64); + let target = self.state.next_pc & 0xFFFFFFFFF0000000 + | (((instruction & 0x03FFFFFF) << 2) as u64); return self.handle_jump(link_reg, target); } @@ -322,7 +323,10 @@ impl InstrumentedState let effective_address = a1 & 0xFFFFFFFFFFFFFFFC; self.track_mem_access(effective_address as Address)?; - let memory = self.state.memory.get_memory_b4(effective_address as Address)?; + let memory = self + .state + .memory + .get_memory_b4(effective_address as Address)?; let mut key = self.state.preimage_key; let alignment = a1 & 0x3; let space = 4 - alignment; @@ -435,7 +439,8 @@ impl InstrumentedState self.state.pc = self.state.next_pc; if should_branch { - self.state.next_pc = prev_pc + 4 + (sign_extend((instruction & 0xFFFF) as u64, 16) << 2); + self.state.next_pc = + prev_pc + 4 + (sign_extend((instruction & 0xFFFF) as u64, 16) << 2); } else { // Branch not taken; proceed as normal. self.state.next_pc += 4; @@ -605,9 +610,15 @@ impl InstrumentedState match fun { // sll - 0 => Ok(sign_extend((rt & 0xFFFFFFFF) << ((instruction >> 6) & 0x1F), 32)), + 0 => Ok(sign_extend( + (rt & 0xFFFFFFFF) << ((instruction >> 6) & 0x1F), + 32, + )), // srl - 2 => Ok(sign_extend((rt & 0xFFFFFFFF) >> ((instruction >> 6) & 0x1F), 32)), + 2 => Ok(sign_extend( + (rt & 0xFFFFFFFF) >> ((instruction >> 6) & 0x1F), + 32, + )), // sra 3 => { let shamt = (instruction >> 6) & 0x1F; @@ -689,7 +700,10 @@ impl InstrumentedState Ok(sign_extend((rt & !mask) | val, 32)) } // lw / ll - 0x23 | 0x30 => Ok(sign_extend((mem >> (32 - ((rs & 0x4) << 3))) & 0xFFFFFFFF, 32)), + 0x23 | 0x30 => Ok(sign_extend( + (mem >> (32 - ((rs & 0x4) << 3))) & 0xFFFFFFFF, + 32, + )), // lbu 0x24 => Ok((mem >> (56 - ((rs & 0x7) << 3))) & 0xFF), // lhu diff --git a/crates/mipsevm/src/patch.rs b/crates/mipsevm/src/patch.rs index ecf1a8e..748e707 100644 --- a/crates/mipsevm/src/patch.rs +++ b/crates/mipsevm/src/patch.rs @@ -1,10 +1,10 @@ //! This module contains utilities for loading ELF files into [State] objects. +use crate::utils::sign_extend; use crate::{page, Address, State}; use anyhow::Result; use elf::{abi::PT_LOAD, endian::AnyEndian, ElfBytes}; use std::io::{self, Cursor, Read}; -use crate::utils::sign_extend; /// Symbols that indicate there is a patch to be made on an ELF file that was compiled from Go. pub(crate) const GO_SYMBOLS: [&str; 14] = [ @@ -38,7 +38,7 @@ pub fn load_elf(raw: &[u8]) -> Result { let mut state = State { pc: elf.ehdr.e_entry, next_pc: elf.ehdr.e_entry + 4, - heap: 2000000000000000u64, + heap: 0x20000000u64, ..Default::default() }; @@ -89,9 +89,7 @@ pub fn load_elf(raw: &[u8]) -> Result { ); } - state - .memory - .set_memory_range(header.p_vaddr, reader)?; + state.memory.set_memory_range(header.p_vaddr, reader)?; } Ok(state) @@ -163,7 +161,9 @@ pub fn patch_stack(state: &mut State) -> Result<()> { store_mem(state, sign_extend(ptr + 4 * 4, 63), 6)?; // auxv[0] = _AT_PAGESZ = 6 (key) store_mem(state, sign_extend(ptr + 4 * 5, 63), 4096)?; // auxv[1] = page size of 4 KiB (value) - (== minPhysPageSize) store_mem(state, sign_extend(ptr + 4 * 6, 63), 25)?; // auxv[2] = AT_RANDOM - state.memory.set_memory(sign_extend(ptr + 4 * 7, 63), sign_extend(ptr + 4 * 9, 63))?; // auxv[3] = random data + state + .memory + .set_memory(sign_extend(ptr + 4 * 7, 63), sign_extend(ptr + 4 * 9, 63))?; // auxv[3] = random data store_mem(state, sign_extend(ptr + 4 * 8, 63), 0)?; // auxv[term] = 0 // 16 bytes of "randomness" diff --git a/crates/mipsevm/src/utils.rs b/crates/mipsevm/src/utils.rs index cd6c123..5fb21a4 100644 --- a/crates/mipsevm/src/utils.rs +++ b/crates/mipsevm/src/utils.rs @@ -55,4 +55,4 @@ pub(crate) fn sign_extend(data: u64, index: u64) -> u64 { } else { data & mask } -} \ No newline at end of file +} diff --git a/crates/mipsevm/src/witness.rs b/crates/mipsevm/src/witness.rs index f9f057a..297aa5f 100644 --- a/crates/mipsevm/src/witness.rs +++ b/crates/mipsevm/src/witness.rs @@ -1,11 +1,11 @@ //! This module contains the various witness types. +use crate::memory::PROOF_LEN; use crate::{utils::keccak256, State, StateWitness, StateWitnessHasher}; use alloy_primitives::{B256, U256}; use alloy_sol_types::{sol, SolCall}; use preimage_oracle::KeyType; use revm::primitives::Bytes; -use crate::memory::PROOF_LEN; /// The size of an encoded [StateWitness] in bytes. pub const STATE_WITNESS_SIZE: usize = 378;