Merge pull request #884 from mir-protocol/evm-kernel-tests

This commit is contained in:
Dima V 2023-02-17 03:20:04 +01:00 committed by GitHub
commit 6f2d99c7bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 187 additions and 378 deletions

View File

@ -49,21 +49,20 @@ pub(crate) fn combined_kernel() -> Kernel {
include_str!("asm/hash/blake2b/g_functions.asm"), include_str!("asm/hash/blake2b/g_functions.asm"),
include_str!("asm/hash/blake2b/hash.asm"), include_str!("asm/hash/blake2b/hash.asm"),
include_str!("asm/hash/blake2b/iv.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/ops.asm"),
include_str!("asm/hash/blake2b/permutations.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/box.asm"),
include_str!("asm/hash/ripemd/compression.asm"), include_str!("asm/hash/ripemd/compression.asm"),
include_str!("asm/hash/ripemd/constants.asm"), include_str!("asm/hash/ripemd/constants.asm"),
include_str!("asm/hash/ripemd/functions.asm"), include_str!("asm/hash/ripemd/functions.asm"),
include_str!("asm/hash/ripemd/main.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/ripemd/update.asm"),
include_str!("asm/hash/sha2/compression.asm"), include_str!("asm/hash/sha2/compression.asm"),
include_str!("asm/hash/sha2/constants.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/message_schedule.asm"),
include_str!("asm/hash/sha2/ops.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/temp_words.asm"),
include_str!("asm/hash/sha2/write_length.asm"), include_str!("asm/hash/sha2/write_length.asm"),
include_str!("asm/main.asm"), include_str!("asm/main.asm"),

View File

@ -0,0 +1,15 @@
global blake2b:
// stack: virt, num_bytes, retdest
DUP2
// stack: num_bytes, virt, num_bytes, retdest
%add_const(127)
%div_const(128)
// 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)

View File

@ -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)

View File

@ -6,41 +6,56 @@
/// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, padlength(len(input)), bytes = [0x80]+[0]*63) /// 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))) /// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, 8, bytes = size(len(_input)))
/// return process(STATE) /// return process(STATE)
/// ///
/// ripemd is called on a stack with ADDR and length /// The hardcoded memory structure, where each register is only a byte, is given as follows
/// ripemd_stack is called on a stack with length, followed by the input bytes /// { 0-63: buffer, 64-71: bytes(8*len(_input)), 72-135: [0x80]+[0]*63 }
/// ///
/// ripemd_update receives and return the stack in the form: /// ripemd_update receives and return the stack in the form:
/// stack: STATE, count, length, virt /// stack: STATE, count, length, virt
/// where virt is the virtual address of the bytes argument /// 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: global ripemd:
// stack: ADDR, length // stack: virt, length
%stack (ADDR: 3, length) -> (64, length, 0x80, 63, length, ADDR, length) %stack (virt, length) -> (length, 0x80, virt, length)
// stack: 64, length, 0x80, 63, length, ADDR, length // stack: length, 0x80, virt, 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]
global ripemd_init:
// stack: length // stack: length
%stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process) %shl_const(3)
// stack: count = 0, length, virt = 136, ripemd_1, ripemd_2, process // stack: abcdefgh
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)
// 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)
// stack: 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, count, length, virt, LABELS // stack: STATE, count, length, virt, LABELS
%jump(ripemd_update) %jump(ripemd_update)
ripemd_1: ripemd_1:
// stack: STATE, count, length , virt , LABELS // stack: STATE, count, length , virt , LABELS
DUP7 DUP7
@ -58,7 +73,7 @@ ripemd_2:
%stack (STATE: 5, count, length, virt) -> (STATE, count, 8, 64) %stack (STATE: 5, count, length, virt) -> (STATE, count, 8, 64)
// stack: STATE, count, length = 8, virt = 64, LABELS // stack: STATE, count, length = 8, virt = 64, LABELS
%jump(ripemd_update) %jump(ripemd_update)
global process: process:
// stack: a , b, c, d, e, count, length, virt // stack: a , b, c, d, e, count, length, virt
%reverse_bytes_u32 %reverse_bytes_u32
%shl_const(128) %shl_const(128)
@ -105,3 +120,12 @@ global process:
// stack: 56 + 64*(t > 55), t // stack: 56 + 64*(t > 55), t
SUB SUB
%endmacro %endmacro
%macro extract_and_store_byte(byte, offset)
// stack: xs
PUSH $byte
BYTE
// stack: xs[byte]
%mstore_kernel_general($offset)
// stack:
%endmacro

View File

@ -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

View File

@ -106,3 +106,29 @@ update_2:
%stack (offset, STATE: 5) -> (STATE, offset, update_2) %stack (offset, STATE: 5) -> (STATE, offset, update_2)
// stack: STATE, offset, update_2, shift, need, have, count, length, virt, retdest // stack: STATE, offset, update_2, shift, need, have, count, length, virt, retdest
%jump(compress) %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

View File

@ -1,47 +1,19 @@
global sha2: global sha2:
%jump(sha2_store) // stack: virt, num_bytes, retdest
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 SWAP1
// stack: addr, counter-1, ... , x[num_bytes-1], retdest // stack: num_bytes, virt, retdest
%increment DUP2
// stack: addr+1, counter-1, ... , x[num_bytes-1], retdest // stack: virt, num_bytes, virt, retdest
%jump(store_loop) %mstore_kernel_general
store_end: // stack: virt, retdest
// stack: addr, counter, retdest
%pop2
// stack: retdest
%jump(sha2_pad)
// 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] // num_bytes, x[0], x[1], ..., x[num_bytes - 1]
// Postcodition: output is in memory, starting at 0, of the form // Postcodition: output is in memory, starting at 0, of the form
// num_blocks, block0[0], ..., block0[63], block1[0], ..., blocklast[63] // num_blocks, block0[0], ..., block0[63], block1[0], ..., blocklast[63]
global sha2_pad: global sha2_pad:
// stack: retdest // stack: virt, retdest
PUSH 0
%mload_kernel_general %mload_kernel_general
// stack: num_bytes, retdest // stack: num_bytes, retdest
// STEP 1: append 1 // STEP 1: append 1

View File

@ -289,7 +289,7 @@
// given u32 bytestring abcd return dcba // given u32 bytestring abcd return dcba
%macro reverse_bytes_u32 %macro reverse_bytes_u32
// stack: abcd // stack: abcd
DUP1 DUP1
PUSH 28 PUSH 28
BYTE BYTE
@ -308,11 +308,11 @@
PUSH 31 PUSH 31
BYTE BYTE
%shl_const(24) %shl_const(24)
// stack: d000, b0, a, c00 // stack: d000, b0, a, c00
OR OR
OR OR
OR OR
// stack: dcba // stack: dcba
%endmacro %endmacro
%macro reverse_bytes_u64 %macro reverse_bytes_u64

View File

@ -65,6 +65,32 @@ pub fn run_interpreter(
) )
} }
pub struct InterpreterMemoryInitialization {
pub label: String,
pub stack: Vec<U256>,
pub segment: Segment,
pub memory: Vec<(usize, Vec<U256>)>,
}
pub fn run_interpreter_with_memory(
memory_init: InterpreterMemoryInitialization,
) -> anyhow::Result<Interpreter<'static>> {
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)
}
pub fn run<'a>( pub fn run<'a>(
code: &'a [u8], code: &'a [u8],
initial_offset: usize, initial_offset: usize,

View File

@ -1,5 +1,3 @@
use std::str::FromStr;
use anyhow::Result; use anyhow::Result;
use blake2::Blake2b512; use blake2::Blake2b512;
use ethereum_types::{U256, U512}; use ethereum_types::{U256, U512};
@ -7,14 +5,16 @@ use rand::{thread_rng, Rng};
use ripemd::{Digest, Ripemd160}; use ripemd::{Digest, Ripemd160};
use sha2::Sha256; use sha2::Sha256;
use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::interpreter::{
use crate::cpu::kernel::interpreter::run_interpreter; run_interpreter_with_memory, InterpreterMemoryInitialization,
};
use crate::memory::segments::Segment::KernelGeneral;
/// Standard Sha2 implementation. /// Standard Blake2b implementation.
fn sha2(input: Vec<u8>) -> U256 { fn blake2b(input: Vec<u8>) -> U512 {
let mut hasher = Sha256::new(); let mut hasher = Blake2b512::new();
hasher.update(input); hasher.update(input);
U256::from(&hasher.finalize()[..]) U512::from(&hasher.finalize()[..])
} }
/// Standard RipeMD implementation. /// Standard RipeMD implementation.
@ -24,11 +24,11 @@ fn ripemd(input: Vec<u8>) -> U256 {
U256::from(&hasher.finalize()[..]) U256::from(&hasher.finalize()[..])
} }
/// Standard Blake2b implementation. /// Standard Sha2 implementation.
fn blake2b(input: Vec<u8>) -> U512 { fn sha2(input: Vec<u8>) -> U256 {
let mut hasher = Blake2b512::new(); let mut hasher = Sha256::new();
hasher.update(input); hasher.update(input);
U512::from(&hasher.finalize()[..]) U256::from(&hasher.finalize()[..])
} }
fn make_random_input() -> Vec<u8> { fn make_random_input() -> Vec<u8> {
@ -38,109 +38,95 @@ fn make_random_input() -> Vec<u8> {
(0..num_bytes).map(|_| rng.gen()).collect() (0..num_bytes).map(|_| rng.gen()).collect()
} }
fn make_custom_input() -> Vec<u8> { fn make_interpreter_setup(
// Hardcode a custom message message: Vec<u8>,
vec![ hash_fn_label: &str,
86, 124, 206, 245, 74, 57, 250, 43, 60, 30, 254, 43, 143, 144, 242, 215, 13, 103, 237, 61, hash_input_virt: (usize, usize),
90, 105, 123, 250, 189, 181, 110, 192, 227, 57, 145, 46, 221, 238, 7, 181, 146, 111, 209, ) -> InterpreterMemoryInitialization {
150, 31, 157, 229, 126, 206, 105, 37, 17, InterpreterMemoryInitialization {
] label: hash_fn_label.to_string(),
} stack: vec![
U256::from(hash_input_virt.0),
fn make_input_stack(message: Vec<u8>) -> Vec<U256> { U256::from(message.len()),
let mut initial_stack = vec![U256::from(message.len())]; U256::from(0xdeadbeefu32),
let bytes: Vec<U256> = message.iter().map(|&x| U256::from(x as u32)).collect(); ],
initial_stack.extend(bytes); segment: KernelGeneral,
initial_stack.push(U256::from_str("0xdeadbeef").unwrap()); memory: vec![(
initial_stack.reverse(); hash_input_virt.1,
initial_stack message.iter().map(|&x| U256::from(x as u32)).collect(),
)],
}
} }
fn combine_u256s(hi: U256, lo: U256) -> U512 { fn combine_u256s(hi: U256, lo: U256) -> U512 {
let mut result = U512::from(hi); U512::from(lo) + (U512::from(hi) << 256)
result <<= 256;
result += U512::from(lo);
result
} }
fn prepare_test<T>( fn prepare_test<T>(
hash_fn_label: &str, hash_fn_label: &str,
hash_input_virt: (usize, usize),
standard_implementation: &dyn Fn(Vec<u8>) -> T, standard_implementation: &dyn Fn(Vec<u8>) -> T,
) -> Result<(T, T, Vec<U256>, Vec<U256>)> { ) -> Result<(T, Vec<U256>)> {
// Make the input. // Make the input.
let message_random = make_random_input(); let message = make_random_input();
let message_custom = make_custom_input();
// Hash the message using a standard implementation. // Hash the message using a standard implementation.
let expected_random = standard_implementation(message_random.clone()); let expected = standard_implementation(message.clone());
let expected_custom = standard_implementation(message_custom.clone());
// Load the message onto the stack. // Load the message into the kernel.
let initial_stack_random = make_input_stack(message_random); let interpreter_setup = make_interpreter_setup(message, hash_fn_label, hash_input_virt);
let initial_stack_custom = make_input_stack(message_custom);
// Make the kernel. // Run the interpeter
let kernel_function = KERNEL.global_labels[hash_fn_label]; let result = run_interpreter_with_memory(interpreter_setup).unwrap();
// Run the kernel code. Ok((expected, result.stack().to_vec()))
let result_random = run_interpreter(kernel_function, initial_stack_random)?;
let result_custom = run_interpreter(kernel_function, initial_stack_custom)?;
Ok((
expected_random,
expected_custom,
result_random.stack().to_vec(),
result_custom.stack().to_vec(),
))
} }
fn test_hash_256( fn test_hash_256(
hash_fn_label: &str, hash_fn_label: &str,
hash_input_virt: (usize, usize),
standard_implementation: &dyn Fn(Vec<u8>) -> U256, standard_implementation: &dyn Fn(Vec<u8>) -> U256,
) -> Result<()> { ) -> Result<()> {
let (expected_random, expected_custom, random_stack, custom_stack) = let (expected, result_stack) =
prepare_test(hash_fn_label, standard_implementation).unwrap(); prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap();
// Extract the final output. // Extract the final output.
let actual_random = random_stack[0]; let actual = result_stack[0];
let actual_custom = custom_stack[0];
// Check that the result is correct. // Check that the result is correct.
assert_eq!(expected_random, actual_random); assert_eq!(expected, actual);
assert_eq!(expected_custom, actual_custom);
Ok(()) Ok(())
} }
fn test_hash_512( fn test_hash_512(
hash_fn_label: &str, hash_fn_label: &str,
hash_input_virt: (usize, usize),
standard_implementation: &dyn Fn(Vec<u8>) -> U512, standard_implementation: &dyn Fn(Vec<u8>) -> U512,
) -> Result<()> { ) -> Result<()> {
let (expected_random, expected_custom, random_stack, custom_stack) = let (expected, result_stack) =
prepare_test(hash_fn_label, standard_implementation).unwrap(); prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap();
// Extract the final output. // 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]);
let actual_custom = combine_u256s(custom_stack[0], custom_stack[1]);
// Check that the result is correct. // Check that the result is correct.
assert_eq!(expected_random, actual_random); assert_eq!(expected, actual);
assert_eq!(expected_custom, actual_custom);
Ok(()) Ok(())
} }
#[test] #[test]
fn test_sha2() -> Result<()> { fn test_blake2b() -> Result<()> {
test_hash_256("sha2", &sha2) test_hash_512("blake2b", (0, 2), &blake2b)
} }
#[test] #[test]
fn test_ripemd() -> Result<()> { fn test_ripemd() -> Result<()> {
test_hash_256("ripemd_stack", &ripemd) test_hash_256("ripemd", (200, 200), &ripemd)
} }
#[test] #[test]
fn test_blake2b() -> Result<()> { fn test_sha2() -> Result<()> {
test_hash_512("blake2b", &blake2b) test_hash_256("sha2", (0, 1), &sha2)
} }

View File

@ -7,7 +7,6 @@ mod fields;
mod hash; mod hash;
mod mpt; mod mpt;
mod packing; mod packing;
mod ripemd;
mod rlp; mod rlp;
mod transaction_parsing; mod transaction_parsing;

View File

@ -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<u32> {
let mut input: Vec<u32> = 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<u32> = make_input(x);
let expected = U256::from(y);
let initial_offset = KERNEL.global_labels["ripemd_stack"];
let initial_stack: Vec<U256> = input.iter().map(|&x| U256::from(x)).rev().collect();
let final_stack: Vec<U256> = run_interpreter(initial_offset, initial_stack)?
.stack()
.to_vec();
let actual = final_stack[0];
assert_eq!(actual, expected);
}
Ok(())
}

View File

@ -1,6 +1,6 @@
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub(crate) enum Segment { pub enum Segment {
/// Contains EVM bytecode. /// Contains EVM bytecode.
Code = 0, Code = 0,
/// The program stack. /// The program stack.