From a1ea7ff93056c7ac8cdf6c7e80c1e9deb6dec06f Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 9 Dec 2022 09:34:42 -0800 Subject: [PATCH] progress --- .../cpu/kernel/asm/hash/blake/compression.asm | 7 +- .../cpu/kernel/asm/hash/blake/g_functions.asm | 99 ++++++++++++++++++- evm/src/cpu/kernel/asm/hash/blake/ops.asm | 25 +++++ evm/src/cpu/kernel/constants/mod.rs | 22 +++-- 4 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/hash/blake/ops.asm diff --git a/evm/src/cpu/kernel/asm/hash/blake/compression.asm b/evm/src/cpu/kernel/asm/hash/blake/compression.asm index fceabeb1..74cdaff3 100644 --- a/evm/src/cpu/kernel/asm/hash/blake/compression.asm +++ b/evm/src/cpu/kernel/asm/hash/blake/compression.asm @@ -1,2 +1,7 @@ +%macro blake_compression_internal_state_addr + PUSH 0 +%endmacro + global blake_compression: - // stack: + // stack: h_0, ..., h_7, t_0, t_1, f_0, f_1, m_0, ..., m_15 + \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/hash/blake/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake/g_functions.asm index e8b1dab2..a4783648 100644 --- a/evm/src/cpu/kernel/asm/hash/blake/g_functions.asm +++ b/evm/src/cpu/kernel/asm/hash/blake/g_functions.asm @@ -1,3 +1,98 @@ global blake_g_function: - // stack: i, a, b, c, d - \ No newline at end of file + // Function to mix two input words, x and y, into the four words indexed by a, b, c, d (which + // are in the range 0..16) in the internal state. + // The internal state is stored in memory starting at the address start. + // stack: a, b, c, d, x, y, start + %stack (indices: 4) -> (indices, indices) + // stack: a, b, c, d, a, b, c, d, x, y, start + DUP11 + // stack: start, a, b, c, d, a, b, c, d, x, y, start + %stack (start, a, b, c, d) -> (d, start, c, start, b, start, a, start) + // stack: d, start, c, start, b, start, a, start, a, b, c, d, x, y, start + ADD + %mload_kernel_general + // stack: v[d], c, start, b, start, a, start, a, b, c, d, x, y, start + %stack (vd, remaining: 6) -> (remaining, vd) + // stack: c, start, b, start, a, start, v[d], a, b, c, d, x, y, start + ADD + %mload_kernel_general + %stack (vc, remaining: 4) -> (remaining, vc) + // stack: b, start, a, start, v[c], v[d], a, b, c, d, x, y, start + ADD + %mload_kernel_general + // stack: v[b], a, start, v[c], v[d], a, b, c, d, x, y, start + %stack (vb, remaining: 2) -> (remaining, vb) + // stack: a, start, v[b], v[c], v[d], a, b, c, d, x, y, start + ADD + %mload_kernel_general + // stack: v[a], v[b], v[c], v[d], a, b, c, d, x, y, start + DUP2 + // stack: v[b], v[a], v[b], v[c], v[d], a, b, c, d, x, y, start + DUP10 + // stack: x, v[b], v[a], v[b], v[c], v[d], a, b, c, d, x, y, start + ADD + ADD + %as_u64 + // stack: v[a]' = (v[a] + v[b] + x) % 2^64, v[b], v[c], v[d], a, b, c, d, x, y, start + %stack (a, b, c, d) -> (a, d, a, b, c, d) + // stack: v[a]', v[d], v[a]', v[b], v[c], v[d], a, b, c, d, x, y, start + XOR + %rotr_64(32) + // stack: v[d]' = (v[d] ^ v[a]') >>> 32, v[a]', v[b], v[c], v[d], a, b, c, d, x, y, start + %stack (top: 3, vd) -> (top) + // stack: v[d]', v[a]', v[b], v[c], a, b, c, d, x, y, start + %stack (d, a, b, c) -> (c, d, a, b, d) + // stack: v[c], v[d]', v[a]', v[b], v[d]', a, b, c, d, x, y, start + ADD + %as_u64 + // stack: v[c]' = (v[c] + v[d]') % 2^64, v[a]', v[b], v[d]', a, b, c, d, x, y, start + %stack (c, a, b, d) -> (b, c, a, c, d) + // stack: v[b], v[c]', v[a]', v[c]', v[d]', a, b, c, d, x, y, start + XOR + %rotr_64(24) + // stack: v[b]' = (v[b] ^ v[c]') >>> 24, v[a]', v[c]', v[d]', a, b, c, d, x, y, start + SWAP1 + // stack: v[a]', v[b]', v[c]', v[d]', a, b, c, d, x, y, start + DUP2 + // stack: v[b]', v[a]', v[b]', v[c]', v[d]', a, b, c, d, x, y, start + DUP11 + // stack: y, v[b]', v[a]', v[b]', v[c]', v[d]', a, b, c, d, x, y, start + ADD + ADD + %as_u64 + // stack: v[a]'' = (v[a]' + v[b]' + y) % 2^64, v[b]', v[c]', v[d]', a, b, c, d, x, y, start + SWAP3 + // stack: v[d]', v[b]', v[c]', v[a]'', a, b, c, d, x, y, start + DUP4 + // stack: v[a]'', v[d]', v[b]', v[c]', v[a]'', a, b, c, d, x, y, start + XOR + %rotr_64(16) + // stack: v[d]'' = (v[a]'' ^ v[d]') >>> 8, v[b]', v[c]', v[a]'', a, b, c, d, x, y, start + SWAP2 + // stack: v[c]', v[b]', v[d]'', v[a]'', a, b, c, d, x, y, start + DUP3 + // stack: v[d]'', v[c]', v[b]', v[d]'', v[a]'', a, b, c, d, x, y, start + ADD + %as_u64 + // stack: v[c]'' = (v[c]' + v[d]'') % 2^64, v[b]', v[d]'', v[a]'', a, b, c, d, x, y, start + DUP1 + // stack: v[c]'', v[c]'', v[b]', v[d]'', v[a]'', a, b, c, d, x, y, start + SWAP2 + // stack: v[b]', v[c]'', v[c]'', v[d]'', v[a]'', a, b, c, d, x, y, start + XOR + %rotr_64(63) + // stack: v[b]'' = (v[b]' ^ v[c]'') >>> 7, v[c]'', v[d]'', v[a]'', a, b, c, d, x, y, start + %stack (vb, vc, vd, va, a, b, c, d, x, y, start) -> (start, a, va, start, b, vb, start, c, vc, start, d, vd) + // stack: start, a, v[a]'', start, b, v[b]'', start, c, v[c]'', start, d, v[d]'' + ADD + %mstore_kernel_general + ADD + %mstore_kernel_general + ADD + %mstore_kernel_general + ADD + %mstore_kernel_general + + + + diff --git a/evm/src/cpu/kernel/asm/hash/blake/ops.asm b/evm/src/cpu/kernel/asm/hash/blake/ops.asm new file mode 100644 index 00000000..c83ace55 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake/ops.asm @@ -0,0 +1,25 @@ +%macro as_u64 + %and_const(0xffffffffffffffff) +%endmacro + +// 64-bit right rotation +%macro rotr_64(rot) + // stack: value + PUSH $rot + // stack: rot, value + DUP2 + DUP2 + // stack: rot, value, rot, value + SHR + // stack: value >> rot, rot, value + %stack (shifted, rot, value) -> (rot, value, shifted) + // stack: rot, value, value >> rot + PUSH 64 + SUB + // stack: 64 - rot, value, value >> rot + SHL + // stack: value << (64 - rot), value >> rot + %as_u64 + // stack: (value << (64 - rot)) % (1 << 64), value >> rot + ADD +%endmacro \ No newline at end of file diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index e762a643..723daac8 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -18,15 +18,16 @@ pub(crate) mod txn_fields; /// Constants that are accessible to our kernel assembly code. pub fn evm_constants() -> HashMap { let mut c = HashMap::new(); - for (name, value) in EC_CONSTANTS { - c.insert(name.into(), U256::from_big_endian(&value)); - } - for (name, value) in HASH_CONSTANTS { - c.insert(name.into(), U256::from_big_endian(&value)); + + let hex_constants = MISC_CONSTANTS.iter().chain(EC_CONSTANTS.iter()).chain(HASH_CONSTANTS.iter()); + for (name, value) in hex_constants { + c.insert(name.clone().into(), U256::from_big_endian(value)); } + for (name, value) in GAS_CONSTANTS { c.insert(name.into(), U256::from(value)); } + for segment in Segment::all() { c.insert(segment.var_name().into(), (segment as u32).into()); } @@ -49,12 +50,15 @@ pub fn evm_constants() -> HashMap { c } -const HASH_CONSTANTS: [(&str, [u8; 32]); 2] = [ - // Hash of an empty string: keccak(b'').hex() +const MISC_CONSTANTS: [(&str, [u8; 32]); 1] = [ + // 2^64 ( - "EMPTY_STRING_HASH", - hex!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), + "BLAKE_WORD_SIZE", + hex!("0000000000000000000000000000000000000000000000010000000000000000"), ), +]; + +const HASH_CONSTANTS: [(&str, [u8; 32]); 1] = [ // Hash of an empty node: keccak(rlp.encode(b'')).hex() ( "EMPTY_NODE_HASH",