diff --git a/snark-verifier/src/loader/evm/code.rs b/snark-verifier/src/loader/evm/code.rs index d768d795..808e4c8f 100644 --- a/snark-verifier/src/loader/evm/code.rs +++ b/snark-verifier/src/loader/evm/code.rs @@ -27,7 +27,13 @@ pragma solidity ^0.8.0; contract Halo2Verifier {{ fallback(bytes calldata) external returns (bytes memory) {{ - assembly {{ + assembly (\"memory-safe\") {{ + // Enforce that Solidity memory layout is respected + let data := mload(0x40) + if iszero(eq(data, 0x80)) {{ + revert(0, 0) + }} + let success := true let f_p := {base_modulus} let f_q := {scalar_modulus} diff --git a/snark-verifier/src/loader/evm/loader.rs b/snark-verifier/src/loader/evm/loader.rs index c80d5892..e3d82cf2 100644 --- a/snark-verifier/src/loader/evm/loader.rs +++ b/snark-verifier/src/loader/evm/loader.rs @@ -22,6 +22,9 @@ use std::{ rc::Rc, }; +/// Memory pointer starts at 0x80, which is the end of the Solidity memory layout scratch space. +pub const MEM_PTR_START: usize = 0x80; + #[derive(Clone, Debug)] pub enum Value { Constant(T), @@ -77,7 +80,7 @@ impl EvmLoader { base_modulus, scalar_modulus, code: RefCell::new(code), - ptr: Default::default(), + ptr: RefCell::new(MEM_PTR_START), cache: Default::default(), }) } diff --git a/snark-verifier/src/system/halo2/transcript/evm.rs b/snark-verifier/src/system/halo2/transcript/evm.rs index 1ceeb020..026c4295 100644 --- a/snark-verifier/src/system/halo2/transcript/evm.rs +++ b/snark-verifier/src/system/halo2/transcript/evm.rs @@ -2,7 +2,12 @@ use crate::{ loader::{ - evm::{loader::Value, u256_to_fe, util::MemoryChunk, EcPoint, EvmLoader, Scalar, U256}, + evm::{ + loader::{Value, MEM_PTR_START}, + u256_to_fe, + util::MemoryChunk, + EcPoint, EvmLoader, Scalar, U256, + }, native::{self, NativeLoader}, Loader, }, @@ -40,7 +45,7 @@ where /// u256 for `transcript_initial_state`. pub fn new(loader: &Rc) -> Self { let ptr = loader.allocate(0x20); - assert_eq!(ptr, 0); + assert_eq!(ptr, MEM_PTR_START); let mut buf = MemoryChunk::new(ptr); buf.extend(0x20); Self { @@ -118,7 +123,7 @@ where fn common_scalar(&mut self, scalar: &Scalar) -> Result<(), Error> { match scalar.value() { - Value::Constant(_) if self.buf.ptr() == 0 => { + Value::Constant(_) if self.buf.ptr() == MEM_PTR_START => { self.loader.copy_scalar(scalar, self.buf.ptr()); } Value::Memory(ptr) => {