From bce867188c9e837685cb69a98fcd55bba2562d76 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 18:18:26 -0800 Subject: [PATCH 01/10] simplify ripe md test --- evm/src/cpu/kernel/aggregator.rs | 1 - evm/src/cpu/kernel/asm/hash/ripemd/main.asm | 70 ++++++--- evm/src/cpu/kernel/asm/hash/ripemd/memory.asm | 137 ------------------ evm/src/cpu/kernel/asm/hash/ripemd/update.asm | 26 ++++ evm/src/cpu/kernel/interpreter.rs | 35 +++++ evm/src/cpu/kernel/tests/hash.rs | 93 +++++++----- evm/src/cpu/kernel/tests/mod.rs | 1 - evm/src/cpu/kernel/tests/ripemd.rs | 56 ------- evm/src/cpu/kernel/tests/test_utils.rs | 35 +++++ evm/src/memory/segments.rs | 2 +- 10 files changed, 200 insertions(+), 256 deletions(-) delete mode 100644 evm/src/cpu/kernel/asm/hash/ripemd/memory.asm delete mode 100644 evm/src/cpu/kernel/tests/ripemd.rs create mode 100644 evm/src/cpu/kernel/tests/test_utils.rs diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index a5eeaf32..6695c585 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -57,7 +57,6 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/hash/ripemd/constants.asm"), include_str!("asm/hash/ripemd/functions.asm"), include_str!("asm/hash/ripemd/main.asm"), - include_str!("asm/hash/ripemd/memory.asm"), include_str!("asm/hash/ripemd/update.asm"), include_str!("asm/hash/sha2/compression.asm"), include_str!("asm/hash/sha2/constants.asm"), diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm index bbcb4068..011ff906 100644 --- a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm +++ b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm @@ -7,40 +7,47 @@ /// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, 8, bytes = size(len(_input))) /// return process(STATE) /// -/// ripemd is called on a stack with ADDR and length -/// ripemd_stack is called on a stack with length, followed by the input bytes +/// ripemd is called on +/// // stack: length /// /// ripemd_update receives and return the stack in the form: /// stack: STATE, count, length, virt /// where virt is the virtual address of the bytes argument -global ripemd_stack: - // stack: length, INPUT - %stack (length) -> (64, length, 0x80, 63, length, length) - // stack: 64, length, 0x80, 63, length, length, INPUT - %jump(ripemd_storage) // stores the following into memory - // init _buffer at virt 0 [consumes 64] - // store _size at virt 64 [consumes length] - // store _padding at virt 72 [consumes 0x80, 63] - // store _input at virt 136 [consumes length] - global ripemd: - // stack: ADDR, length - %stack (ADDR: 3, length) -> (64, length, 0x80, 63, length, ADDR, length) - // stack: 64, length, 0x80, 63, length, ADDR, length - %jump(ripemd_storage) // stores the following into memory - // init _buffer at virt 0 [consumes 64] - // store _size at virt 64 [consumes length] - // store _padding at virt 72 [consumes 0x80, 63] - // store _input at virt 136 [consumes ADDR, length] + // stack: virt, length + %stack (virt, length) -> (length, 0x80, virt, length) + // stack: length, 0x80, virt, length -global ripemd_init: // stack: length - %stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process) - // stack: count = 0, length, virt = 136, ripemd_1, ripemd_2, process + %shl_const(3) + // stack: abcdefgh + %extract_and_store_byte(64) + // stack: abcdefg + %extract_and_store_byte(65) + // stack: abcdef + %extract_and_store_byte(66) + // stack: abcde + %extract_and_store_byte(67) + // stack: abcd + %extract_and_store_byte(68) + // stack: abc + %extract_and_store_byte(69) + // stack: ab + %extract_and_store_byte(70) + // stack: a + %mstore_kernel_general(71) + + // stack: 0x80 + %mstore_kernel_general(72) + + // stack: virt, length + %stack (virt, length) -> ( 0, length, virt, ripemd_1, ripemd_2, process) + // stack: count = 0, length, virt, ripemd_1, ripemd_2, process %stack () -> (0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0) // stack: 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, count, length, virt, LABELS %jump(ripemd_update) + ripemd_1: // stack: STATE, count, length , virt , LABELS DUP7 @@ -105,3 +112,20 @@ global process: // stack: 56 + 64*(t > 55), t SUB %endmacro + + +%macro extract_and_store_byte(offset) + // stack: xsy + PUSH 0x100 + DUP2 + MOD + // stack: y, xsy + %stack (y, xsy) -> (xsy, y, 0x100, y) + // stack: xsy, y, 0x100, y + SUB + DIV + SWAP1 + // stack: y, xs + %mstore_kernel_general($offset) + // stack: xs +%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/memory.asm b/evm/src/cpu/kernel/asm/hash/ripemd/memory.asm deleted file mode 100644 index e3b7cbe6..00000000 --- a/evm/src/cpu/kernel/asm/hash/ripemd/memory.asm +++ /dev/null @@ -1,137 +0,0 @@ -global ripemd_storage: // starts by initializing buffer - // stack: i [init: 64] - %store_zeros(64, ripemd_storage) - // stack: (empty) - %jump(store_size) - -store_size: - // stack: length - %shl_const(3) - // stack: abcdefgh - %extract_and_store_byte(64) - // stack: abcdefg - %extract_and_store_byte(65) - // stack: abcdef - %extract_and_store_byte(66) - // stack: abcde - %extract_and_store_byte(67) - // stack: abcd - %extract_and_store_byte(68) - // stack: abc - %extract_and_store_byte(69) - // stack: ab - %extract_and_store_byte(70) - // stack: a - %mstore_kernel_general(71) - // stack: 0x80 // padding has 0x80 in first position and zeros elsewhere - %mstore_kernel_general(72) // store first padding term here so as to avoid extra label - %jump(store_padding) - -store_padding: - // stack: i [init 63], length - %store_zeros(136, store_padding) - // stack: length - DUP1 - %jumpi(store_input_stack) - POP - %jump(ripemd_init) - -store_input_stack: - // stack: rem, length, REM_INP - %stack (rem, length, head) -> (length, rem, 136, head, rem, length) - SUB - ADD - // stack: offset, byte, rem, length, REM_INP - %mstore_kernel_general - // stack: rem, length, REM_INP - %decrement - DUP1 - // stack: rem - 1, rem - 1, length, REM_INP - %jumpi(store_input_stack) - // stack: 0, length - POP - %jump(ripemd_init) - -store_input: - // stack: rem , ADDR , length - DUP4 - DUP4 - DUP4 - MLOAD_GENERAL - // stack: byte, rem , ADDR , length - DUP2 - DUP7 - SUB - %add_const(136) - // stack: offset, byte, rem , ADDR , length - %mstore_kernel_general - // stack: rem , ADDR , length - %decrement - // stack: rem-1, ADDR , length - SWAP3 - %increment - SWAP3 - // stack: rem-1, ADDR+1, length - DUP1 - %jumpi(store_input) - // stack: 0 , ADDR , length - %pop4 - // stack: length - %jump(ripemd_init) - -/// def buffer_update(get, set, times): -/// for i in range(times): -/// buffer[set+i] = bytestring[get+i] - -global buffer_update: - // stack: get , set , times , retdest - DUP2 - DUP2 - // stack: get, set, get , set , times , retdest - %mupdate_kernel_general - // stack: get , set , times , retdest - %increment - SWAP1 - %increment - SWAP1 - SWAP2 - %decrement - SWAP2 - // stack: get+1, set+1, times-1, retdest - DUP3 - %jumpi(buffer_update) - // stack: get , set , 0 , retdest - %pop3 - JUMP - - -%macro store_zeros(N, label) - // stack: i - %stack (i) -> ($N, i, 0, i) - SUB - // stack: offset = N-i, 0, i - %mstore_kernel_general - // stack: i - %decrement - DUP1 - // stack: i-1, i-1 - %jumpi($label) - // stack: 0 - POP -%endmacro - -%macro extract_and_store_byte(offset) - // stack: xsy - PUSH 0x100 - DUP2 - MOD - // stack: y, xsy - %stack (y, xsy) -> (xsy, y, 0x100, y) - // stack: xsy, y, 0x100, y - SUB - DIV - SWAP1 - // stack: y, xs - %mstore_kernel_general($offset) - // stack: xs -%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/update.asm b/evm/src/cpu/kernel/asm/hash/ripemd/update.asm index a0c3ef68..63d3cff8 100644 --- a/evm/src/cpu/kernel/asm/hash/ripemd/update.asm +++ b/evm/src/cpu/kernel/asm/hash/ripemd/update.asm @@ -106,3 +106,29 @@ update_2: %stack (offset, STATE: 5) -> (STATE, offset, update_2) // stack: STATE, offset, update_2, shift, need, have, count, length, virt, retdest %jump(compress) + + +/// def buffer_update(get, set, times): +/// for i in range(times): +/// buffer[set+i] = bytestring[get+i] + +buffer_update: + // stack: get , set , times , retdest + DUP2 + DUP2 + // stack: get, set, get , set , times , retdest + %mupdate_kernel_general + // stack: get , set , times , retdest + %increment + SWAP1 + %increment + SWAP1 + SWAP2 + %decrement + SWAP2 + // stack: get+1, set+1, times-1, retdest + DUP3 + %jumpi(buffer_update) + // stack: get , set , 0 , retdest + %pop3 + JUMP diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 777c09e9..02ecd059 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -65,6 +65,32 @@ pub fn run_interpreter( ) } +pub struct InterpreterSetup { + pub label: String, + pub stack: Vec, + pub segment: Segment, + pub memory: Vec<(usize, Vec)>, +} + +impl InterpreterSetup { + pub fn run(self) -> anyhow::Result> { + let label = KERNEL.global_labels[&self.label]; + let mut stack = self.stack; + stack.reverse(); + let mut interpreter = Interpreter::new_with_kernel(label, stack); + for (pointer, data) in self.memory { + for (i, term) in data.iter().enumerate() { + interpreter + .generation_state + .memory + .set(MemoryAddress::new(0, self.segment, pointer + i), *term) + } + } + interpreter.run()?; + Ok(interpreter) + } +} + pub fn run<'a>( code: &'a [u8], initial_offset: usize, @@ -223,6 +249,15 @@ impl<'a> Interpreter<'a> { .content } + pub fn extract_kernel_memory(self, locs: Vec) -> Vec { + let mut output: Vec = vec![]; + for loc in locs { + let term = self.generation_state.memory.get(loc); + output.push(term); + } + output + } + pub(crate) fn push(&mut self, x: U256) { self.stack_mut().push(x); self.generation_state.registers.stack_len += 1; diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index b24317e0..979029b6 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use anyhow::Result; use blake2::Blake2b512; use ethereum_types::{U256, U512}; @@ -7,14 +5,14 @@ use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; use sha2::Sha256; -use crate::cpu::kernel::aggregator::KERNEL; -use crate::cpu::kernel::interpreter::run_interpreter; +use crate::cpu::kernel::interpreter::InterpreterSetup; +use crate::memory::segments::Segment::KernelGeneral; -/// Standard Sha2 implementation. -fn sha2(input: Vec) -> U256 { - let mut hasher = Sha256::new(); +/// Standard Blake2b implementation. +fn blake2b(input: Vec) -> U512 { + let mut hasher = Blake2b512::new(); hasher.update(input); - U256::from(&hasher.finalize()[..]) + U512::from(&hasher.finalize()[..]) } /// Standard RipeMD implementation. @@ -24,11 +22,11 @@ fn ripemd(input: Vec) -> U256 { U256::from(&hasher.finalize()[..]) } -/// Standard Blake2b implementation. -fn blake2b(input: Vec) -> U512 { - let mut hasher = Blake2b512::new(); +/// Standard Sha2 implementation. +fn sha2(input: Vec) -> U256 { + let mut hasher = Sha256::new(); hasher.update(input); - U512::from(&hasher.finalize()[..]) + U256::from(&hasher.finalize()[..]) } fn make_random_input() -> Vec { @@ -47,15 +45,6 @@ fn make_custom_input() -> Vec { ] } -fn make_input_stack(message: Vec) -> Vec { - let mut initial_stack = vec![U256::from(message.len())]; - let bytes: Vec = message.iter().map(|&x| U256::from(x as u32)).collect(); - initial_stack.extend(bytes); - initial_stack.push(U256::from_str("0xdeadbeef").unwrap()); - initial_stack.reverse(); - initial_stack -} - fn combine_u256s(hi: U256, lo: U256) -> U512 { let mut result = U512::from(hi); result <<= 256; @@ -75,16 +64,46 @@ fn prepare_test( let expected_random = standard_implementation(message_random.clone()); let expected_custom = standard_implementation(message_custom.clone()); - // Load the message onto the stack. - let initial_stack_random = make_input_stack(message_random); - let initial_stack_custom = make_input_stack(message_custom); + let inp: usize = 136; - // Make the kernel. - let kernel_function = KERNEL.global_labels[hash_fn_label]; + // Load the message into the kernel. + let interpreter_setup_random = InterpreterSetup { + label: hash_fn_label.to_string(), + stack: vec![ + U256::from(inp), + U256::from(message_random.len()), + U256::from(0xdeadbeefu32), + ], + segment: KernelGeneral, + memory: vec![( + inp, + message_random + .iter() + .map(|&x| U256::from(x as u32)) + .collect(), + )], + }; + + let interpreter_setup_custom = InterpreterSetup { + label: hash_fn_label.to_string(), + stack: vec![ + U256::from(inp), + U256::from(message_custom.len()), + U256::from(0xdeadbeefu32), + ], + segment: KernelGeneral, + memory: vec![( + inp, + message_custom + .iter() + .map(|&x| U256::from(x as u32)) + .collect(), + )], + }; // Run the kernel code. - let result_random = run_interpreter(kernel_function, initial_stack_random)?; - let result_custom = run_interpreter(kernel_function, initial_stack_custom)?; + let result_random = interpreter_setup_random.run().unwrap(); + let result_custom = interpreter_setup_custom.run().unwrap(); Ok(( expected_random, @@ -130,17 +149,17 @@ fn test_hash_512( Ok(()) } -#[test] -fn test_sha2() -> Result<()> { - test_hash_256("sha2", &sha2) -} +// #[test] +// fn test_blake2b() -> Result<()> { +// test_hash_512("blake2b", &blake2b) +// } #[test] fn test_ripemd() -> Result<()> { - test_hash_256("ripemd_stack", &ripemd) + test_hash_256("ripemd", &ripemd) } -#[test] -fn test_blake2b() -> Result<()> { - test_hash_512("blake2b", &blake2b) -} +// #[test] +// fn test_sha2() -> Result<()> { +// test_hash_256("sha2", &sha2) +// } diff --git a/evm/src/cpu/kernel/tests/mod.rs b/evm/src/cpu/kernel/tests/mod.rs index 1d522d5c..acf90230 100644 --- a/evm/src/cpu/kernel/tests/mod.rs +++ b/evm/src/cpu/kernel/tests/mod.rs @@ -7,7 +7,6 @@ mod fields; mod hash; mod mpt; mod packing; -mod ripemd; mod rlp; mod transaction_parsing; diff --git a/evm/src/cpu/kernel/tests/ripemd.rs b/evm/src/cpu/kernel/tests/ripemd.rs deleted file mode 100644 index 78b05cb8..00000000 --- a/evm/src/cpu/kernel/tests/ripemd.rs +++ /dev/null @@ -1,56 +0,0 @@ -use anyhow::Result; -use ethereum_types::U256; -use itertools::Itertools; - -use crate::cpu::kernel::aggregator::KERNEL; -use crate::cpu::kernel::interpreter::run_interpreter; - -fn make_input(word: &str) -> Vec { - let mut input: Vec = vec![word.len().try_into().unwrap()]; - input.append(&mut word.as_bytes().iter().map(|&x| x as u32).collect_vec()); - input.push(u32::from_str_radix("deadbeef", 16).unwrap()); - input -} - -#[test] -fn test_ripemd_reference() -> Result<()> { - let reference = vec![ - ("", "0x9c1185a5c5e9fc54612808977ee8f548b2258d31"), - ("a", "0x0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"), - ("abc", "0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), - ( - "message digest", - "0x5d0689ef49d2fae572b881b123a85ffa21595f36", - ), - ( - "abcdefghijklmnopqrstuvwxyz", - "0xf71c27109c692c1b56bbdceb5b9d2865b3708dbc", - ), - ( - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "0x12a053384a9c0c88e405a06c27dcf49ada62eb2b", - ), - ( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - "0xb0e20b6e3116640286ed3a87a5713079b21f5189", - ), - ( - "12345678901234567890123456789012345678901234567890123456789012345678901234567890", - "0x9b752e45573d4b39f4dbd3323cab82bf63326bfb", - ), - ]; - - for (x, y) in reference { - let input: Vec = make_input(x); - let expected = U256::from(y); - - let initial_offset = KERNEL.global_labels["ripemd_stack"]; - let initial_stack: Vec = input.iter().map(|&x| U256::from(x)).rev().collect(); - let final_stack: Vec = run_interpreter(initial_offset, initial_stack)? - .stack() - .to_vec(); - let actual = final_stack[0]; - assert_eq!(actual, expected); - } - Ok(()) -} diff --git a/evm/src/cpu/kernel/tests/test_utils.rs b/evm/src/cpu/kernel/tests/test_utils.rs new file mode 100644 index 00000000..0421ef4d --- /dev/null +++ b/evm/src/cpu/kernel/tests/test_utils.rs @@ -0,0 +1,35 @@ +use std::ops::Range; + +use anyhow::Result; +use ethereum_types::U256; + +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::Interpreter; +use crate::memory::segments::Segment; +use crate::witness::memory::MemoryAddress; + +pub struct InterpreterSetup { + pub label: String, + pub stack: Vec, + pub segment: Segment, + pub memory: Vec<(usize, Vec)>, +} + +impl InterpreterSetup { + pub fn run(self) -> Result> { + let label = KERNEL.global_labels[&self.label]; + let mut stack = self.stack; + stack.reverse(); + let mut interpreter = Interpreter::new_with_kernel(label, stack); + for (pointer, data) in self.memory { + for (i, term) in data.iter().enumerate() { + interpreter + .generation_state + .memory + .set(MemoryAddress::new(0, self.segment, pointer + i), *term) + } + } + interpreter.run()?; + Ok(interpreter) + } +} diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index 4ae1afa4..202901e2 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -1,6 +1,6 @@ #[allow(dead_code)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)] -pub(crate) enum Segment { +pub enum Segment { /// Contains EVM bytecode. Code = 0, /// The program stack. From c6cf1dc56a19bb1b206abd402160c06800874ad0 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 18:26:05 -0800 Subject: [PATCH 02/10] remove custom --- evm/src/cpu/kernel/tests/hash.rs | 63 +++++++------------------------- 1 file changed, 13 insertions(+), 50 deletions(-) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index 979029b6..e3b4587a 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -36,15 +36,6 @@ fn make_random_input() -> Vec { (0..num_bytes).map(|_| rng.gen()).collect() } -fn make_custom_input() -> Vec { - // Hardcode a custom message - vec![ - 86, 124, 206, 245, 74, 57, 250, 43, 60, 30, 254, 43, 143, 144, 242, 215, 13, 103, 237, 61, - 90, 105, 123, 250, 189, 181, 110, 192, 227, 57, 145, 46, 221, 238, 7, 181, 146, 111, 209, - 150, 31, 157, 229, 126, 206, 105, 37, 17, - ] -} - fn combine_u256s(hi: U256, lo: U256) -> U512 { let mut result = U512::from(hi); result <<= 256; @@ -54,29 +45,26 @@ fn combine_u256s(hi: U256, lo: U256) -> U512 { fn prepare_test( hash_fn_label: &str, + hash_input_virt: usize, standard_implementation: &dyn Fn(Vec) -> T, -) -> Result<(T, T, Vec, Vec)> { +) -> Result<(T, Vec)> { // Make the input. let message_random = make_random_input(); - let message_custom = make_custom_input(); // Hash the message using a standard implementation. let expected_random = standard_implementation(message_random.clone()); - let expected_custom = standard_implementation(message_custom.clone()); - - let inp: usize = 136; // Load the message into the kernel. let interpreter_setup_random = InterpreterSetup { label: hash_fn_label.to_string(), stack: vec![ - U256::from(inp), + U256::from(hash_input_virt), U256::from(message_random.len()), U256::from(0xdeadbeefu32), ], segment: KernelGeneral, memory: vec![( - inp, + hash_input_virt, message_random .iter() .map(|&x| U256::from(x as u32)) @@ -84,67 +72,42 @@ fn prepare_test( )], }; - let interpreter_setup_custom = InterpreterSetup { - label: hash_fn_label.to_string(), - stack: vec![ - U256::from(inp), - U256::from(message_custom.len()), - U256::from(0xdeadbeefu32), - ], - segment: KernelGeneral, - memory: vec![( - inp, - message_custom - .iter() - .map(|&x| U256::from(x as u32)) - .collect(), - )], - }; - - // Run the kernel code. + // Run the interpeter let result_random = interpreter_setup_random.run().unwrap(); - let result_custom = interpreter_setup_custom.run().unwrap(); - Ok(( - expected_random, - expected_custom, - result_random.stack().to_vec(), - result_custom.stack().to_vec(), - )) + Ok((expected_random, result_random.stack().to_vec())) } fn test_hash_256( hash_fn_label: &str, + hash_input_virt: usize, standard_implementation: &dyn Fn(Vec) -> U256, ) -> Result<()> { - let (expected_random, expected_custom, random_stack, custom_stack) = - prepare_test(hash_fn_label, standard_implementation).unwrap(); + let (expected_random, random_stack) = + prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); // Extract the final output. let actual_random = random_stack[0]; - let actual_custom = custom_stack[0]; // Check that the result is correct. assert_eq!(expected_random, actual_random); - assert_eq!(expected_custom, actual_custom); Ok(()) } fn test_hash_512( hash_fn_label: &str, + hash_input_virt: usize, standard_implementation: &dyn Fn(Vec) -> U512, ) -> Result<()> { - let (expected_random, expected_custom, random_stack, custom_stack) = - prepare_test(hash_fn_label, standard_implementation).unwrap(); + let (expected_random, random_stack) = + prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); // Extract the final output. let actual_random = combine_u256s(random_stack[0], random_stack[1]); - let actual_custom = combine_u256s(custom_stack[0], custom_stack[1]); // Check that the result is correct. assert_eq!(expected_random, actual_random); - assert_eq!(expected_custom, actual_custom); Ok(()) } @@ -156,7 +119,7 @@ fn test_hash_512( #[test] fn test_ripemd() -> Result<()> { - test_hash_256("ripemd", &ripemd) + test_hash_256("ripemd", 136, &ripemd) } // #[test] From 731c29c43b5d26b919a2ca779da76c701e7e8693 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 18:47:33 -0800 Subject: [PATCH 03/10] abstract --- evm/src/cpu/kernel/asm/hash/ripemd/main.asm | 2 +- evm/src/cpu/kernel/tests/hash.rs | 61 +++++++++++---------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm index 011ff906..1ea3ee1d 100644 --- a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm +++ b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm @@ -65,7 +65,7 @@ ripemd_2: %stack (STATE: 5, count, length, virt) -> (STATE, count, 8, 64) // stack: STATE, count, length = 8, virt = 64, LABELS %jump(ripemd_update) -global process: +process: // stack: a , b, c, d, e, count, length, virt %reverse_bytes_u32 %shl_const(128) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index e3b4587a..8565d779 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -36,6 +36,26 @@ fn make_random_input() -> Vec { (0..num_bytes).map(|_| rng.gen()).collect() } +fn make_interpreter_setup( + message: Vec, + hash_fn_label: &str, + hash_input_virt: usize, +) -> InterpreterSetup { + InterpreterSetup { + label: hash_fn_label.to_string(), + stack: vec![ + U256::from(hash_input_virt), + U256::from(message.len()), + U256::from(0xdeadbeefu32), + ], + segment: KernelGeneral, + memory: vec![( + hash_input_virt, + message.iter().map(|&x| U256::from(x as u32)).collect(), + )], + } +} + fn combine_u256s(hi: U256, lo: U256) -> U512 { let mut result = U512::from(hi); result <<= 256; @@ -49,33 +69,18 @@ fn prepare_test( standard_implementation: &dyn Fn(Vec) -> T, ) -> Result<(T, Vec)> { // Make the input. - let message_random = make_random_input(); + let message = make_random_input(); // Hash the message using a standard implementation. - let expected_random = standard_implementation(message_random.clone()); + let expected = standard_implementation(message.clone()); // Load the message into the kernel. - let interpreter_setup_random = InterpreterSetup { - label: hash_fn_label.to_string(), - stack: vec![ - U256::from(hash_input_virt), - U256::from(message_random.len()), - U256::from(0xdeadbeefu32), - ], - segment: KernelGeneral, - memory: vec![( - hash_input_virt, - message_random - .iter() - .map(|&x| U256::from(x as u32)) - .collect(), - )], - }; + let interpreter_setup = make_interpreter_setup(message, hash_fn_label, hash_input_virt); // Run the interpeter - let result_random = interpreter_setup_random.run().unwrap(); + let result = interpreter_setup.run().unwrap(); - Ok((expected_random, result_random.stack().to_vec())) + Ok((expected, result.stack().to_vec())) } fn test_hash_256( @@ -83,14 +88,14 @@ fn test_hash_256( hash_input_virt: usize, standard_implementation: &dyn Fn(Vec) -> U256, ) -> Result<()> { - let (expected_random, random_stack) = + let (expected, result_stack) = prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); // Extract the final output. - let actual_random = random_stack[0]; + let actual = result_stack[0]; // Check that the result is correct. - assert_eq!(expected_random, actual_random); + assert_eq!(expected, actual); Ok(()) } @@ -100,14 +105,14 @@ fn test_hash_512( hash_input_virt: usize, standard_implementation: &dyn Fn(Vec) -> U512, ) -> Result<()> { - let (expected_random, random_stack) = + let (expected, result_stack) = prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); // Extract the final output. - let actual_random = combine_u256s(random_stack[0], random_stack[1]); + let actual = combine_u256s(result_stack[0], result_stack[1]); // Check that the result is correct. - assert_eq!(expected_random, actual_random); + assert_eq!(expected, actual); Ok(()) } @@ -119,10 +124,10 @@ fn test_hash_512( #[test] fn test_ripemd() -> Result<()> { - test_hash_256("ripemd", 136, &ripemd) + test_hash_256("ripemd", 200, &ripemd) } // #[test] // fn test_sha2() -> Result<()> { -// test_hash_256("sha2", &sha2) +// test_hash_256("sha2", 1, &sha2) // } From abc762f7b4e37171fddb07cdb5fced545a4599f0 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 18:50:26 -0800 Subject: [PATCH 04/10] cleaner arithmetic --- evm/src/cpu/kernel/tests/hash.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index 8565d779..b57ce174 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -57,10 +57,7 @@ fn make_interpreter_setup( } fn combine_u256s(hi: U256, lo: U256) -> U512 { - let mut result = U512::from(hi); - result <<= 256; - result += U512::from(lo); - result + U512::from(lo) + (U512::from(hi) << 256) } fn prepare_test( From 77a7af76c224b00ca1086746a8c2ba08d0ec9d63 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 19:00:52 -0800 Subject: [PATCH 05/10] remove sha2 storage --- .../cpu/kernel/asm/hash/sha2/store_pad.asm | 39 ++----------------- evm/src/cpu/kernel/tests/hash.rs | 8 ++-- 2 files changed, 8 insertions(+), 39 deletions(-) diff --git a/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm b/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm index 7594eb81..e842d8be 100644 --- a/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm +++ b/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm @@ -1,39 +1,8 @@ global sha2: - %jump(sha2_store) - -global sha2_store: - // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - DUP1 - // stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - PUSH 0 - // stack: addr=0, num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - %mstore_kernel_general - // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - PUSH 1 - // stack: addr=1, counter=num_bytes, x[0], x[1], x[2], ... , x[num_bytes-1], retdest -store_loop: - // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - DUP2 - // stack: counter, addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - ISZERO - %jumpi(store_end) - // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - %stack (addr, counter, val) -> (addr, val, counter, addr) - // stack: addr, x[num_bytes-counter], counter, addr, ... , x[num_bytes-1], retdest - %mstore_kernel_general - // stack: counter, addr, ... , x[num_bytes-1], retdest - %decrement - // stack: counter-1, addr, ... , x[num_bytes-1], retdest - SWAP1 - // stack: addr, counter-1, ... , x[num_bytes-1], retdest - %increment - // stack: addr+1, counter-1, ... , x[num_bytes-1], retdest - %jump(store_loop) -store_end: - // stack: addr, counter, retdest - %pop2 - // stack: retdest - %jump(sha2_pad) + // stack: virt, length + POP + // stack: length + %mstore_kernel_general(0) // Precodition: input is in memory, starting at 0 of kernel general segment, of the form // num_bytes, x[0], x[1], ..., x[num_bytes - 1] diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index b57ce174..fce37c4d 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -124,7 +124,7 @@ fn test_ripemd() -> Result<()> { test_hash_256("ripemd", 200, &ripemd) } -// #[test] -// fn test_sha2() -> Result<()> { -// test_hash_256("sha2", 1, &sha2) -// } +#[test] +fn test_sha2() -> Result<()> { + test_hash_256("sha2", 1, &sha2) +} From 53ab0ada11676101fcbdd7b466a8fdc14defa758 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 15 Feb 2023 19:11:22 -0800 Subject: [PATCH 06/10] remove blake storage --- evm/src/cpu/kernel/aggregator.rs | 4 +- evm/src/cpu/kernel/asm/hash/blake2b/main.asm | 14 ++++++ evm/src/cpu/kernel/asm/hash/blake2b/store.asm | 45 ------------------- .../asm/hash/sha2/{store_pad.asm => main.asm} | 0 evm/src/cpu/kernel/interpreter.rs | 9 ---- evm/src/cpu/kernel/tests/hash.rs | 8 ++-- 6 files changed, 20 insertions(+), 60 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/hash/blake2b/main.asm delete mode 100644 evm/src/cpu/kernel/asm/hash/blake2b/store.asm rename evm/src/cpu/kernel/asm/hash/sha2/{store_pad.asm => main.asm} (100%) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 6695c585..a6436f5d 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -49,9 +49,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/hash/blake2b/g_functions.asm"), include_str!("asm/hash/blake2b/hash.asm"), include_str!("asm/hash/blake2b/iv.asm"), + include_str!("asm/hash/blake2b/main.asm"), include_str!("asm/hash/blake2b/ops.asm"), include_str!("asm/hash/blake2b/permutations.asm"), - include_str!("asm/hash/blake2b/store.asm"), include_str!("asm/hash/ripemd/box.asm"), include_str!("asm/hash/ripemd/compression.asm"), include_str!("asm/hash/ripemd/constants.asm"), @@ -60,9 +60,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/hash/ripemd/update.asm"), include_str!("asm/hash/sha2/compression.asm"), include_str!("asm/hash/sha2/constants.asm"), + include_str!("asm/hash/sha2/main.asm"), include_str!("asm/hash/sha2/message_schedule.asm"), include_str!("asm/hash/sha2/ops.asm"), - include_str!("asm/hash/sha2/store_pad.asm"), include_str!("asm/hash/sha2/temp_words.asm"), include_str!("asm/hash/sha2/write_length.asm"), include_str!("asm/main.asm"), diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/main.asm b/evm/src/cpu/kernel/asm/hash/blake2b/main.asm new file mode 100644 index 00000000..5e36ba72 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/main.asm @@ -0,0 +1,14 @@ +global blake2b: + // stack: virt, num_bytes, retdest + POP + // stack: num_bytes, retdest + DUP1 + // stack: num_bytes, num_bytes, retdest + %add_const(127) + %div_const(128) + // stack: num_blocks = ceil(num_bytes / 128), num_bytes, retdest + %mstore_kernel_general(0) + // stack: num_bytes, retdest + %mstore_kernel_general(1) + // stack: retdest + %jump(blake2b_compression) diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/store.asm b/evm/src/cpu/kernel/asm/hash/blake2b/store.asm deleted file mode 100644 index 0b2a9a7a..00000000 --- a/evm/src/cpu/kernel/asm/hash/blake2b/store.asm +++ /dev/null @@ -1,45 +0,0 @@ -global blake2b: - %jump(blake2b_store) - -global blake2b_store: - // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - DUP1 - // stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - %add_const(127) - %div_const(128) - // stack: num_blocks = ceil(num_bytes / 128), num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - PUSH 0 - // stack: addr=0, num_blocks, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - %mstore_kernel_general - // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - DUP1 - // stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - PUSH 1 - // stack: 1, num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - %mstore_kernel_general - // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest - PUSH 2 - // stack: addr=2, counter=num_bytes, x[0], x[1], x[2], ... , x[num_bytes-1], retdest -store_loop: - // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - DUP2 - // stack: counter, addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - ISZERO - %jumpi(store_end) - // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest - %stack (addr, counter, val) -> (addr, val, counter, addr) - // stack: addr, x[num_bytes-counter], counter, addr, ... , x[num_bytes-1], retdest - %mstore_kernel_general - // stack: counter, addr, ... , x[num_bytes-1], retdest - %decrement - // stack: counter-1, addr, ... , x[num_bytes-1], retdest - SWAP1 - // stack: addr, counter-1, ... , x[num_bytes-1], retdest - %increment - // stack: addr+1, counter-1, ... , x[num_bytes-1], retdest - %jump(store_loop) -store_end: - // stack: addr, counter, retdest - %pop2 - // stack: retdest - %jump(blake2b_compression) diff --git a/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm b/evm/src/cpu/kernel/asm/hash/sha2/main.asm similarity index 100% rename from evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm rename to evm/src/cpu/kernel/asm/hash/sha2/main.asm diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 02ecd059..2f1974b5 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -249,15 +249,6 @@ impl<'a> Interpreter<'a> { .content } - pub fn extract_kernel_memory(self, locs: Vec) -> Vec { - let mut output: Vec = vec![]; - for loc in locs { - let term = self.generation_state.memory.get(loc); - output.push(term); - } - output - } - pub(crate) fn push(&mut self, x: U256) { self.stack_mut().push(x); self.generation_state.registers.stack_len += 1; diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index fce37c4d..38fd7659 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -114,10 +114,10 @@ fn test_hash_512( Ok(()) } -// #[test] -// fn test_blake2b() -> Result<()> { -// test_hash_512("blake2b", &blake2b) -// } +#[test] +fn test_blake2b() -> Result<()> { + test_hash_512("blake2b", 2, &blake2b) +} #[test] fn test_ripemd() -> Result<()> { From 4e4cfb06b3aa3874bc811cb5862f04fa323a3cbd Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 16 Feb 2023 15:01:22 -0800 Subject: [PATCH 07/10] function API / remove redundancy --- evm/src/cpu/kernel/interpreter.rs | 32 +++++++++++------------ evm/src/cpu/kernel/tests/hash.rs | 10 +++++--- evm/src/cpu/kernel/tests/test_utils.rs | 35 -------------------------- 3 files changed, 22 insertions(+), 55 deletions(-) delete mode 100644 evm/src/cpu/kernel/tests/test_utils.rs diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 2f1974b5..843f0a0d 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -65,30 +65,30 @@ pub fn run_interpreter( ) } -pub struct InterpreterSetup { +pub struct InterpreterMemoryInitialization { pub label: String, pub stack: Vec, pub segment: Segment, pub memory: Vec<(usize, Vec)>, } -impl InterpreterSetup { - pub fn run(self) -> anyhow::Result> { - let label = KERNEL.global_labels[&self.label]; - let mut stack = self.stack; - stack.reverse(); - let mut interpreter = Interpreter::new_with_kernel(label, stack); - for (pointer, data) in self.memory { - for (i, term) in data.iter().enumerate() { - interpreter - .generation_state - .memory - .set(MemoryAddress::new(0, self.segment, pointer + i), *term) - } +pub fn run_interpreter_with_memory( + memory_init: InterpreterMemoryInitialization, +) -> anyhow::Result> { + let label = KERNEL.global_labels[&memory_init.label]; + let mut stack = memory_init.stack; + stack.reverse(); + let mut interpreter = Interpreter::new_with_kernel(label, stack); + for (pointer, data) in memory_init.memory { + for (i, term) in data.iter().enumerate() { + interpreter.generation_state.memory.set( + MemoryAddress::new(0, memory_init.segment, pointer + i), + *term, + ) } - interpreter.run()?; - Ok(interpreter) } + interpreter.run()?; + Ok(interpreter) } pub fn run<'a>( diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index 38fd7659..e6a3d2a0 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -5,7 +5,9 @@ use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; use sha2::Sha256; -use crate::cpu::kernel::interpreter::InterpreterSetup; +use crate::cpu::kernel::interpreter::{ + run_interpreter_with_memory, InterpreterMemoryInitialization, +}; use crate::memory::segments::Segment::KernelGeneral; /// Standard Blake2b implementation. @@ -40,8 +42,8 @@ fn make_interpreter_setup( message: Vec, hash_fn_label: &str, hash_input_virt: usize, -) -> InterpreterSetup { - InterpreterSetup { +) -> InterpreterMemoryInitialization { + InterpreterMemoryInitialization { label: hash_fn_label.to_string(), stack: vec![ U256::from(hash_input_virt), @@ -75,7 +77,7 @@ fn prepare_test( let interpreter_setup = make_interpreter_setup(message, hash_fn_label, hash_input_virt); // Run the interpeter - let result = interpreter_setup.run().unwrap(); + let result = run_interpreter_with_memory(interpreter_setup).unwrap(); Ok((expected, result.stack().to_vec())) } diff --git a/evm/src/cpu/kernel/tests/test_utils.rs b/evm/src/cpu/kernel/tests/test_utils.rs deleted file mode 100644 index 0421ef4d..00000000 --- a/evm/src/cpu/kernel/tests/test_utils.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::ops::Range; - -use anyhow::Result; -use ethereum_types::U256; - -use crate::cpu::kernel::aggregator::KERNEL; -use crate::cpu::kernel::interpreter::Interpreter; -use crate::memory::segments::Segment; -use crate::witness::memory::MemoryAddress; - -pub struct InterpreterSetup { - pub label: String, - pub stack: Vec, - pub segment: Segment, - pub memory: Vec<(usize, Vec)>, -} - -impl InterpreterSetup { - pub fn run(self) -> Result> { - let label = KERNEL.global_labels[&self.label]; - let mut stack = self.stack; - stack.reverse(); - let mut interpreter = Interpreter::new_with_kernel(label, stack); - for (pointer, data) in self.memory { - for (i, term) in data.iter().enumerate() { - interpreter - .generation_state - .memory - .set(MemoryAddress::new(0, self.segment, pointer + i), *term) - } - } - interpreter.run()?; - Ok(interpreter) - } -} From a6ffb4b3c3d7611cf47b1b98d668d544828bfea3 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 16 Feb 2023 16:30:50 -0800 Subject: [PATCH 08/10] simplify byte extraction --- evm/src/cpu/kernel/asm/hash/ripemd/main.asm | 57 ++++++++++---------- evm/src/cpu/kernel/asm/util/basic_macros.asm | 6 +-- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm index 1ea3ee1d..32d1994b 100644 --- a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm +++ b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm @@ -22,21 +22,28 @@ global ripemd: // stack: length %shl_const(3) // stack: abcdefgh - %extract_and_store_byte(64) - // stack: abcdefg - %extract_and_store_byte(65) - // stack: abcdef - %extract_and_store_byte(66) - // stack: abcde - %extract_and_store_byte(67) - // stack: abcd - %extract_and_store_byte(68) - // stack: abc - %extract_and_store_byte(69) - // stack: ab - %extract_and_store_byte(70) - // stack: a - %mstore_kernel_general(71) + DUP1 + %extract_and_store_byte(31, 64) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(30, 65) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(29, 66) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(28, 67) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(27, 68) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(26, 69) + // stack: abcdefgh + DUP1 + %extract_and_store_byte(25, 70) + // stack: abcdefgh + %extract_and_store_byte(24, 71) // stack: 0x80 %mstore_kernel_general(72) @@ -113,19 +120,11 @@ process: SUB %endmacro - -%macro extract_and_store_byte(offset) - // stack: xsy - PUSH 0x100 - DUP2 - MOD - // stack: y, xsy - %stack (y, xsy) -> (xsy, y, 0x100, y) - // stack: xsy, y, 0x100, y - SUB - DIV - SWAP1 - // stack: y, xs - %mstore_kernel_general($offset) +%macro extract_and_store_byte(byte, offset) // stack: xs + PUSH $byte + BYTE + // stack: xs[byte] + %mstore_kernel_general($offset) + // stack: %endmacro diff --git a/evm/src/cpu/kernel/asm/util/basic_macros.asm b/evm/src/cpu/kernel/asm/util/basic_macros.asm index 6640892f..a68d832d 100644 --- a/evm/src/cpu/kernel/asm/util/basic_macros.asm +++ b/evm/src/cpu/kernel/asm/util/basic_macros.asm @@ -289,7 +289,7 @@ // given u32 bytestring abcd return dcba %macro reverse_bytes_u32 - // stack: abcd + // stack: abcd DUP1 PUSH 28 BYTE @@ -308,11 +308,11 @@ PUSH 31 BYTE %shl_const(24) - // stack: d000, b0, a, c00 + // stack: d000, b0, a, c00 OR OR OR - // stack: dcba + // stack: dcba %endmacro %macro reverse_bytes_u64 From da7a8879c4a934d91b753e7585bfee5f5cf91dd5 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 16 Feb 2023 16:59:51 -0800 Subject: [PATCH 09/10] make hash functions take a location pointer --- evm/src/cpu/kernel/asm/hash/blake2b/main.asm | 17 +++++++++-------- evm/src/cpu/kernel/asm/hash/ripemd/main.asm | 9 +++++---- evm/src/cpu/kernel/asm/hash/sha2/main.asm | 17 ++++++++++------- evm/src/cpu/kernel/tests/hash.rs | 18 +++++++++--------- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/main.asm b/evm/src/cpu/kernel/asm/hash/blake2b/main.asm index 5e36ba72..933de505 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/main.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2b/main.asm @@ -1,14 +1,15 @@ global blake2b: // stack: virt, num_bytes, retdest - POP - // stack: num_bytes, retdest - DUP1 - // stack: num_bytes, num_bytes, retdest + DUP2 + // stack: num_bytes, virt, num_bytes, retdest %add_const(127) %div_const(128) - // stack: num_blocks = ceil(num_bytes / 128), num_bytes, retdest - %mstore_kernel_general(0) - // stack: num_bytes, retdest - %mstore_kernel_general(1) + // stack: num_blocks = ceil(num_bytes / 128), virt, num_bytes, retdest + DUP2 + // stack: virt, num_blocks, virt, num_bytes, retdest + %mstore_kernel_general + // stack: virt, num_bytes, retdest + %add_const(1) + %mstore_kernel_general // stack: retdest %jump(blake2b_compression) diff --git a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm index 32d1994b..4aa6a6ad 100644 --- a/evm/src/cpu/kernel/asm/hash/ripemd/main.asm +++ b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm @@ -6,13 +6,14 @@ /// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, padlength(len(input)), bytes = [0x80]+[0]*63) /// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, 8, bytes = size(len(_input))) /// return process(STATE) -/// -/// ripemd is called on -/// // stack: length +/// +/// The hardcoded memory structure, where each register is only a byte, is given as follows +/// { 0-63: buffer, 64-71: bytes(8*len(_input)), 72-135: [0x80]+[0]*63 } /// /// ripemd_update receives and return the stack in the form: /// stack: STATE, count, length, virt /// where virt is the virtual address of the bytes argument +/// global ripemd: // stack: virt, length @@ -52,7 +53,7 @@ global ripemd: %stack (virt, length) -> ( 0, length, virt, ripemd_1, ripemd_2, process) // stack: count = 0, length, virt, ripemd_1, ripemd_2, process %stack () -> (0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0) - // stack: 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, count, length, virt, LABELS + // stack: STATE, count, length, virt, LABELS %jump(ripemd_update) ripemd_1: diff --git a/evm/src/cpu/kernel/asm/hash/sha2/main.asm b/evm/src/cpu/kernel/asm/hash/sha2/main.asm index e842d8be..058224f6 100644 --- a/evm/src/cpu/kernel/asm/hash/sha2/main.asm +++ b/evm/src/cpu/kernel/asm/hash/sha2/main.asm @@ -1,16 +1,19 @@ global sha2: - // stack: virt, length - POP - // stack: length - %mstore_kernel_general(0) + // stack: virt, num_bytes, retdest + SWAP1 + // stack: num_bytes, virt, retdest + DUP2 + // stack: virt, num_bytes, virt, retdest + %mstore_kernel_general + // stack: virt, retdest + -// Precodition: input is in memory, starting at 0 of kernel general segment, of the form +// Precodition: input is in memory, starting at virt of kernel general segment, of the form // num_bytes, x[0], x[1], ..., x[num_bytes - 1] // Postcodition: output is in memory, starting at 0, of the form // num_blocks, block0[0], ..., block0[63], block1[0], ..., blocklast[63] global sha2_pad: - // stack: retdest - PUSH 0 + // stack: virt, retdest %mload_kernel_general // stack: num_bytes, retdest // STEP 1: append 1 diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index e6a3d2a0..2456c31d 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -41,18 +41,18 @@ fn make_random_input() -> Vec { fn make_interpreter_setup( message: Vec, hash_fn_label: &str, - hash_input_virt: usize, + hash_input_virt: (usize, usize), ) -> InterpreterMemoryInitialization { InterpreterMemoryInitialization { label: hash_fn_label.to_string(), stack: vec![ - U256::from(hash_input_virt), + U256::from(hash_input_virt.0), U256::from(message.len()), U256::from(0xdeadbeefu32), ], segment: KernelGeneral, memory: vec![( - hash_input_virt, + hash_input_virt.1, message.iter().map(|&x| U256::from(x as u32)).collect(), )], } @@ -64,7 +64,7 @@ fn combine_u256s(hi: U256, lo: U256) -> U512 { fn prepare_test( hash_fn_label: &str, - hash_input_virt: usize, + hash_input_virt: (usize, usize), standard_implementation: &dyn Fn(Vec) -> T, ) -> Result<(T, Vec)> { // Make the input. @@ -84,7 +84,7 @@ fn prepare_test( fn test_hash_256( hash_fn_label: &str, - hash_input_virt: usize, + hash_input_virt: (usize, usize), standard_implementation: &dyn Fn(Vec) -> U256, ) -> Result<()> { let (expected, result_stack) = @@ -101,7 +101,7 @@ fn test_hash_256( fn test_hash_512( hash_fn_label: &str, - hash_input_virt: usize, + hash_input_virt: (usize, usize), standard_implementation: &dyn Fn(Vec) -> U512, ) -> Result<()> { let (expected, result_stack) = @@ -118,15 +118,15 @@ fn test_hash_512( #[test] fn test_blake2b() -> Result<()> { - test_hash_512("blake2b", 2, &blake2b) + test_hash_512("blake2b", (0,2), &blake2b) } #[test] fn test_ripemd() -> Result<()> { - test_hash_256("ripemd", 200, &ripemd) + test_hash_256("ripemd", (200, 200), &ripemd) } #[test] fn test_sha2() -> Result<()> { - test_hash_256("sha2", 1, &sha2) + test_hash_256("sha2", (0, 1), &sha2) } From ea9846debff19aa39a92c50e8531d46779cb8ec1 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 16 Feb 2023 17:01:43 -0800 Subject: [PATCH 10/10] format --- evm/src/cpu/kernel/tests/hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index 2456c31d..bc73ecd5 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -118,7 +118,7 @@ fn test_hash_512( #[test] fn test_blake2b() -> Result<()> { - test_hash_512("blake2b", (0,2), &blake2b) + test_hash_512("blake2b", (0, 2), &blake2b) } #[test]