From 5f564b67828b8161090222d00eddae55b3a0f38e Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Thu, 20 Apr 2023 15:11:19 -0700 Subject: [PATCH 01/16] initial work on blake precompile --- .../kernel/asm/core/precompiles/blake2_f.asm | 56 ++++++- .../kernel/asm/core/precompiles/sha256.asm | 1 + .../cpu/kernel/asm/hash/blake2b/blake2_f.asm | 145 ++++++++++++++++++ .../kernel/asm/hash/blake2b/compression.asm | 5 +- .../kernel/asm/hash/blake2b/g_functions.asm | 22 +-- evm/src/cpu/kernel/asm/hash/blake2b/hash.asm | 1 + evm/src/cpu/kernel/constants/mod.rs | 2 +- 7 files changed, 217 insertions(+), 15 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index a10c9ba2..74c65610 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -1,3 +1,55 @@ global precompile_blake2_f: - // TODO - PANIC + // stack: address, retdest, new_ctx, kexit_info, ret_offset, ret_size + %pop2 + // stack: new_ctx, kexit_info, ret_offset, ret_size + DUP1 + SET_CONTEXT + // stack: (empty) + PUSH 0x100000000 // = 2^32 (is_kernel = true) + // stack: kexit_info + + // get various inputs out of SEGMENT_CALLDATA + + // charge gas (based on rounds) + + // Copy the call data to the kernel general segment (blake2b expects it there) and call blake2b. + %calldatasize + GET_CONTEXT + // stack: ctx, size + + // TODO: change + // The next block of code is equivalent to the following %stack macro call + // (unfortunately the macro call takes too long to expand dynamically). + // + // %stack (ctx, size) -> + // ( + // 0, @SEGMENT_KERNEL_GENERAL, 1, // DST + // ctx, @SEGMENT_CALLDATA, 0, // SRC + // size, blake2_f, // count, retdest + // 0, size, blake2_f_contd // blake2b input: virt, num_bytes, retdest + // ) + // + PUSH 0 + PUSH blake2_f + DUP4 + PUSH 0 + PUSH @SEGMENT_CALLDATA + PUSH blake2_f_contd + SWAP7 + SWAP6 + PUSH 1 + PUSH @SEGMENT_KERNEL_GENERAL + PUSH 0 + + %jump(memcpy) + +blake2_f_contd: + // stack: hash, kexit_info + // Store the result hash to the parent's return data using `mstore_unpacking`. + + + + %mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32) + %mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT) + %stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, 0, hash, 32, pop_and_return_success) + %jump(mstore_unpacking) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/sha256.asm b/evm/src/cpu/kernel/asm/core/precompiles/sha256.asm index 86461a59..804c8a7e 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/sha256.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/sha256.asm @@ -23,6 +23,7 @@ global precompile_sha256: // Copy the call data to the kernel general segment (sha2 expects it there) and call sha2. %calldatasize GET_CONTEXT + // stack: ctx, size // The next block of code is equivalent to the following %stack macro call // (unfortunately the macro call takes too long to expand dynamically). diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm b/evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm new file mode 100644 index 00000000..6a433e23 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm @@ -0,0 +1,145 @@ +global blake2_f: + // stack: rounds, h0...h7, m0...m15, t0, t1, flag, retdest + + // Store the hash values. + %blake2b_hash_value_addr + // stack: addr, rounds, h0...h7, m0...m15, t0, t1, flag, retdest + %rep 8 + // stack: addr, rounds, h_i, ... + %stack (addr, rounds, h_i) -> (addr, h_i, addr, rounds) + // stack: addr, h_i, addr, rounds, ... + %mstore_kernel_general + %increment + %endrep + + // stack: addr, rounds, m0...m15, t0, t1, flag, retdest + POP + // stack: rounds, m0...m15, t0, t1, flag, retdest + + // Save the message to the message working space. + %blake2b_message_addr + // stack: message_addr, rounds, m0...m15, t0, t1, flag, retdest + %rep 16 + // stack: message_addr, rounds, m_i, ... + %stack (message_addr, rounds, m_i) -> (message_addr, m_i, message_addr, rounds) + // stack: message_addr, m_i, message_addr, rounds, ... + %mstore_kernel_general + %increment + %endrep + + // stack: message_addr, rounds, t0, t1, flag, retdest + POP + // stack: rounds, t0, t1, flag, retdest + + + + + %blake2b_hash_value_addr + %add_const(7) + %rep 8 + // stack: addr, ... + DUP1 + // stack: addr, addr, ... + %mload_kernel_general + // stack: val, addr, ... + SWAP1 + // stack: addr, val, ... + %decrement + %endrep + // stack: addr, h_0, ..., h_7, rounds, t0, t1, flag, retdest + POP + // stack: h_0, ..., h_7, rounds, t0, t1, flag, retdest + + // Store the initial 16 values of the internal state. + %blake2b_internal_state_addr + // stack: start, h_0, ..., h_7, rounds, t0, t1, flag, retdest + + // First eight words of the internal state: current hash value h_0, ..., h_7. + %rep 8 + SWAP1 + DUP2 + %mstore_kernel_general + %increment + %endrep + // stack: start + 8, rounds, t0, t1, flag, retdest + + // Next four values of the internal state: first four IV values. + PUSH 0 + // stack: 0, start + 8, rounds, t0, t1, flag, retdest + %rep 4 + // stack: i, loc, ... + DUP1 + // stack: i, i, loc, ... + %blake2b_iv + // stack: IV_i, i, loc, ... + DUP3 + // stack: loc, IV_i, i, loc, ... + %mstore_kernel_general + // stack: i, loc, ... + %increment + SWAP1 + %increment + SWAP1 + // stack: i + 1, loc + 1,... + %endrep + // stack: 4, start + 12, rounds, t0, t1, flag, retdest + POP + // stack: start + 12, rounds, t0, t1, flag, retdest + SWAP4 + // stack: flag, rounds, t0, t1, start + 12, retdest + %mul_const(0xFFFFFFFFFFFFFFFF) + // stack: invert_if_flag, rounds, t0, t1, start + 12, retdest + %stack (inv, r, t0, t1, s) -> (4, s, t0, t1, inv, 0, r) + // stack: 4, start + 12, t0, t1, invert_if_flag, 0, rounds, retdest + + + // Last four values of the internal state: last four IV values, XOR'd with + // the values (t0, t1, invert_if_flag, 0). + %rep 4 + // stack: i, loc, val, next_val,... + DUP1 + // stack: i, i, loc, val, next_val,... + %blake2b_iv + // stack: IV_i, i, loc, val, next_val,... + DUP4 + // stack: val, IV_i, i, loc, val, next_val,... + XOR + // stack: val ^ IV_i, i, loc, val, next_val,... + DUP3 + // stack: loc, val ^ IV_i, i, loc, val, next_val,... + %mstore_kernel_general + // stack: i, loc, val, next_val,... + %increment + // stack: i + 1, loc, val, next_val,... + SWAP2 + // stack: val, loc, i + 1, next_val,... + POP + // stack: loc, i + 1, next_val,... + %increment + // stack: loc + 1, i + 1, next_val,... + SWAP1 + // stack: i + 1, loc + 1, next_val,... + %endrep + // stack: 8, start + 16, rounds, retdest + %pop2 + // stack: rounds, retdest + + // Run rounds of G functions. + PUSH g_functions_return + // stack: g_functions_return, rounds, retdest + SWAP1 + // stack: rounds, g_functions_return, retdest + %blake2b_internal_state_addr + // stack: start, rounds, g_functions_return, retdest + %jump(run_rounds_g_function) +g_functions_return: + // Finalize hash value. + // stack: retdest + PUSH hash_generate_return + // stack: hash_generate_return, retdest + %jump(blake2b_generate_all_hash_values) +hash_generate_return: + // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', retdest + %stack (h: 8, retdest) -> (retdest, h) + // stack: retdest, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7' + JUMP diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm b/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm index 6e8cdb0a..9ad6bba9 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm @@ -187,9 +187,10 @@ compression_loop: // Run 12 rounds of G functions. PUSH g_functions_return // stack: g_functions_return, cur_block, retdest + PUSH 12 %blake2b_internal_state_addr - // stack: start, g_functions_return, cur_block, retdest - %jump(run_12_rounds_g_function) + // stack: start, 12, g_functions_return, cur_block, retdest + %jump(run_rounds_g_function) g_functions_return: // Finalize hash value. // stack: cur_block, retdest diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm index f2d3b1d2..0544fe98 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm @@ -149,27 +149,29 @@ run_g_function_round: // stack: retdest, round, start JUMP -global run_12_rounds_g_function: - // stack: start, retdest +global run_rounds_g_function: + // stack: start, rounds, retdest PUSH 0 - // stack: round=0, start, retdest + // stack: round=0, start, rounds, retdest run_next_round_g_function: - // stack: round, start, retdest + // stack: round, start, rounds, retdest PUSH run_next_round_g_function_return - // stack: run_next_round_g_function_return, round, start, retdest + // stack: run_next_round_g_function_return, round, start, rounds, retdest SWAP2 // stack: start, round, run_next_round_g_function_return, retdest SWAP1 // stack: round, start, run_next_round_g_function_return, retdest %jump(run_g_function_round) run_next_round_g_function_return: - // stack: round, start, retdest + // stack: round, start, rounds, retdest %increment - // stack: round+1, start, retdest + // stack: round+1, start, rounds, retdest DUP1 - // stack: round+1, round+1, start, retdest - %lt_const(12) - // stack: round+1 < 12, round+1, start, retdest + // stack: round+1, round+1, start, rounds, retdest + DUP4 + // stack: rounds, round+1, round+1, start, rounds, retdest + GT + // stack: round+1 < rounds, round+1, start, rounds, retdest %jumpi(run_next_round_g_function) // stack: round+1, start, retdest %pop2 diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm b/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm index 654b51b3..afaaa548 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm @@ -1,3 +1,4 @@ +// Generate a new hash value from the previous hash value and two elements of the internal state. blake2b_generate_new_hash_value: // stack: i, retdest %blake2b_hash_value_addr diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index 75a96403..24f62fdf 100644 --- a/evm/src/cpu/kernel/constants/mod.rs +++ b/evm/src/cpu/kernel/constants/mod.rs @@ -225,5 +225,5 @@ const PRECOMPILES_GAS: [(&str, u16); 13] = [ ("BN_MUL_GAS", 6_000), ("SNARKV_STATIC_GAS", 45_000), ("SNARKV_DYNAMIC_GAS", 34_000), - ("BLAKE2_F_DYNAMIC_GAS", 1), + ("BLAKE2_F__GAS", 1), ]; From 9f0c2f472b0bcaa778650e626c230cc298ec1754 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 21 Apr 2023 12:21:08 -0700 Subject: [PATCH 02/16] blake precompile progress --- .../kernel/asm/core/precompiles/blake2_f.asm | 38 +++++++++++++++++++ evm/src/cpu/kernel/asm/memory/packing.asm | 6 +++ 2 files changed, 44 insertions(+) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index 74c65610..5915ffe7 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -16,6 +16,44 @@ global precompile_blake2_f: %calldatasize GET_CONTEXT // stack: ctx, size + %stack (ctx) -> (ctx, @SEGMENT_CALLDATA, 0, 4, blake2_f_contd) + %jump(mload_packing) +blake2_f_contd: + // stack: rounds, size + PUSH 4 + %rep 8 + // stack: 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + DUP1 + // stack: 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + GET_CONTEXT + // stack: ctx, 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + %stack (ctx, offset) -> (ctx, @SEGMENT_KERNEL_GENERAL, offset, 8) + %mload_packing + // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + SWAP1 + // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, rounds, size + %endrep + + + // stack: ctx, rounds, size + %stack (ctx) -> + // stack: rounds, size + PUSH 4 + // stack: 4, rounds, size + %rep 8 + // stack: 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + DUP1 + // stack: 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + %mload_current_u64(@SEGMENT_CALLDATA) + // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + SWAP1 + // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, rounds, size + %add_const(8) + // stack: 4 + 8 * (i + 1), h_i, h_(i-1), ..., h_0, rounds, size + %endrep + // stack: h_7, ..., h_0, rounds, size + + // TODO: change // The next block of code is equivalent to the following %stack macro call diff --git a/evm/src/cpu/kernel/asm/memory/packing.asm b/evm/src/cpu/kernel/asm/memory/packing.asm index f12c7b17..75b8fc7c 100644 --- a/evm/src/cpu/kernel/asm/memory/packing.asm +++ b/evm/src/cpu/kernel/asm/memory/packing.asm @@ -43,6 +43,12 @@ mload_packing_return: %stack (packed_value, addr: 3, len, retdest) -> (retdest, packed_value) JUMP +%macro mload_packing + %stack (addr: 3, len) -> (addr, len, %%after) + %jump(extcodehash) +%%after: +%endmacro + // Pre stack: context, segment, offset, value, len, retdest // Post stack: offset' global mstore_unpacking: From 86acc15f12b353997fc3e211ae57afa4e01dcd9d Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 21 Apr 2023 18:13:53 -0700 Subject: [PATCH 03/16] blake precompile progress --- .../kernel/asm/core/precompiles/blake2_f.asm | 90 +++++++++++++------ 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index 5915ffe7..e0ffa765 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -14,48 +14,84 @@ global precompile_blake2_f: // Copy the call data to the kernel general segment (blake2b expects it there) and call blake2b. %calldatasize + + // stack: size + %stack () -> (@SEGMENT_CALLDATA, 0, 4) GET_CONTEXT - // stack: ctx, size - %stack (ctx) -> (ctx, @SEGMENT_CALLDATA, 0, 4, blake2_f_contd) - %jump(mload_packing) -blake2_f_contd: + // stack: ctx, @SEGMENT_CALLDATA, 0, 4, size + %mload_packing // stack: rounds, size + PUSH 4 %rep 8 // stack: 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - DUP1 - // stack: 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + PUSH 8 + // stack: 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + DUP2 + // stack: 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size + PUSH @SEGMENT_CALLDATA + // stack: @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size GET_CONTEXT - // stack: ctx, 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - %stack (ctx, offset) -> (ctx, @SEGMENT_KERNEL_GENERAL, offset, 8) + // stack: ctx, @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size %mload_packing // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size SWAP1 // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, rounds, size - %endrep - - - // stack: ctx, rounds, size - %stack (ctx) -> - // stack: rounds, size - PUSH 4 - // stack: 4, rounds, size - %rep 8 - // stack: 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - DUP1 - // stack: 4 + 8 * i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - %mload_current_u64(@SEGMENT_CALLDATA) - // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - SWAP1 - // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, rounds, size %add_const(8) - // stack: 4 + 8 * (i + 1), h_i, h_(i-1), ..., h_0, rounds, size %endrep - // stack: h_7, ..., h_0, rounds, size + // stack: 4 + 8 * 8 = 68, h_7, ..., h_0, rounds, size + + %rep 16 + // stack: 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + PUSH 8 + // stack: 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + DUP2 + // stack: 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + PUSH @SEGMENT_CALLDATA + // stack: @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + %mload_packing + // stack: m_i, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + SWAP1 + // stack: 68 + 8 * i, m_i, m_(i-1), ..., m_0, h_7..h_0, rounds, size + %add_const(8) + %endrep + // stack: 68 + 8 * 16 = 196, m_15, ..., m_0, h_7..h_0, rounds, size + + %stack (offset) -> (@SEGMENT_CALLDATA, offset, 8, offset) + // stack: @SEGMENT_CALLDATA, 196, 8, 196, m_15..m_0, h_7..h_0, rounds, size + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 196, 8, 196, m_15..m_0, h_7..h_0, rounds, size + %mload_packing + // stack: t_0, 196, m_15..m_0, h_7..h_0, rounds, size + SWAP1 + // stack: 196, t_0, m_15..m_0, h_7..h_0, rounds, size + %add_const(8) + // stack: 204, t_0, m_15..m_0, h_7..h_0, rounds, size + + %stack (offset) -> (@SEGMENT_CALLDATA, offset, 8, offset) + // stack: @SEGMENT_CALLDATA, 204, 8, 204, t_0, m_15..m_0, h_7..h_0, rounds, size + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 204, 8, 204, t_0, m_15..m_0, h_7..h_0, rounds, size + %mload_packing + // stack: t_1, 204, t_0, m_15..m_0, h_7..h_0, rounds, size + SWAP1 + // stack: 204, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size + %add_const(8) + // stack: 212, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size + + PUSH @SEGMENT_CALLDATA + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 212, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size + MLOAD_GENERAL + // stack: f, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size + + + - // TODO: change // The next block of code is equivalent to the following %stack macro call // (unfortunately the macro call takes too long to expand dynamically). // From 454e0add2489439a34042a9003106de4c6fbc213 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 24 Apr 2023 16:58:57 -0700 Subject: [PATCH 04/16] fixed blake2_f, and testing --- evm/src/cpu/kernel/aggregator.rs | 17 +- .../kernel/asm/core/precompiles/blake2_f.asm | 213 +++++++++--------- .../hash/{blake2b => blake2}/addresses.asm | 10 +- .../asm/hash/{blake2b => blake2}/blake2_f.asm | 24 +- .../hash/{blake2b => blake2}/compression.asm | 22 +- .../hash/{blake2b => blake2}/g_functions.asm | 74 +++--- .../asm/hash/{blake2b => blake2}/hash.asm | 24 +- .../asm/hash/{blake2b => blake2}/iv.asm | 36 +-- .../asm/hash/{blake2b => blake2}/main.asm | 2 +- .../asm/hash/{blake2b => blake2}/ops.asm | 0 .../hash/{blake2b => blake2}/permutations.asm | 6 +- evm/src/cpu/kernel/asm/memory/packing.asm | 6 + evm/src/cpu/kernel/tests/blake2_f.rs | 139 ++++++++++++ evm/src/cpu/kernel/tests/hash.rs | 11 +- evm/src/cpu/kernel/tests/mod.rs | 1 + 15 files changed, 365 insertions(+), 220 deletions(-) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/addresses.asm (75%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/blake2_f.asm (93%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/compression.asm (96%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/g_functions.asm (76%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/hash.asm (69%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/iv.asm (69%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/main.asm (93%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/ops.asm (100%) rename evm/src/cpu/kernel/asm/hash/{blake2b => blake2}/permutations.asm (95%) create mode 100644 evm/src/cpu/kernel/tests/blake2_f.rs diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index c529f5cf..3e457369 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -75,14 +75,15 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/wnaf.asm"), include_str!("asm/exp.asm"), include_str!("asm/halt.asm"), - include_str!("asm/hash/blake2b/addresses.asm"), - include_str!("asm/hash/blake2b/compression.asm"), - 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/blake2/addresses.asm"), + include_str!("asm/hash/blake2/blake2_f.asm"), + // include_str!("asm/hash/blake2/compression.asm"), + include_str!("asm/hash/blake2/g_functions.asm"), + include_str!("asm/hash/blake2/hash.asm"), + include_str!("asm/hash/blake2/iv.asm"), + // include_str!("asm/hash/blake2/main.asm"), + include_str!("asm/hash/blake2/ops.asm"), + include_str!("asm/hash/blake2/permutations.asm"), include_str!("asm/hash/ripemd/box.asm"), include_str!("asm/hash/ripemd/compression.asm"), include_str!("asm/hash/ripemd/constants.asm"), diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index e0ffa765..16786bcd 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -12,118 +12,119 @@ global precompile_blake2_f: // charge gas (based on rounds) - // Copy the call data to the kernel general segment (blake2b expects it there) and call blake2b. - %calldatasize + PUSH blake2_f_contd + // stack: blake2_f_contd, kexit_info + + // Load inputs from calldata memory into stack. + + %calldatasize + // stack: calldatasize, blake2_f_contd, kexit_info + DUP1 + // stack: calldatasize, calldatasize, blake2_f_contd, kexit_info + %assert_eq_const(213) + // stack: calldatasize, blake2_f_contd, kexit_info + %decrement + // stack: flag_addr=212, blake2_f_contd, kexit_info + DUP1 + // stack: flag_addr, flag_addr, blake2_f_contd, kexit_info + PUSH @SEGMENT_CALLDATA + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, flag_addr, flag_addr size + MLOAD_GENERAL + // stack: flag, flag_addr, blake2_f_contd, kexit_info + SWAP1 + // stack: flag_addr, flag, blake2_f_contd, kexit_info + %sub_const(8) + // stack: t1_addr=flag_addr-8, flag, blake2_f_contd, kexit_info + + %stack (t1_addr) -> (@SEGMENT_CALLDATA, t1_addr, 8, t1_addr) + // stack: @SEGMENT_CALLDATA, t1_addr, 8, t1_addr, flag, blake2_f_contd, kexit_info + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, t1_addr, 8, t1_addr, flag, blake2_f_contd, kexit_info + %mload_packing + // stack: t_1, t1_addr, flag, blake2_f_contd, kexit_info + SWAP1 + // stack: t1_addr, t_1, flag, blake2_f_contd, kexit_info + %sub_const(8) + // stack: t0_addr=t1_addr-8, t_1, flag, blake2_f_contd, kexit_info + + %stack (t0_addr) -> (@SEGMENT_CALLDATA, t0_addr, 8, t0_addr) + // stack: @SEGMENT_CALLDATA, t0_addr, 8, t0_addr, t_1, flag, blake2_f_contd, kexit_info + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, t0_addr, 8, t0_addr, t_1, flag, blake2_f_contd, kexit_info + %mload_packing + // stack: t_0, t0_addr, t_1, flag, blake2_f_contd, kexit_info + SWAP1 + // stack: t0_addr, t_0, t_1, flag, blake2_f_contd, kexit_info + %sub_const(128) // 16 * 8 + // stack: m0_addr=t0_addr-128, t_0, t_1, flag, blake2_f_contd, kexit_info + + %rep 16 + // stack: 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + PUSH 8 + // stack: 8, 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + DUP2 + // stack: 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + PUSH @SEGMENT_CALLDATA + // stack: @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %mload_packing + // stack: m_i, 68 + 8 * i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + SWAP1 + // stack: 68 + 8 * i, m_i, m_(i-1), ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %add_const(8) + %endrep + // stack: 68 + 8 * 16 = 196, m_15, ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %sub_const(192) // 16 * 8 (m values) + 8 * 8 (h values) + // stack: h0_addr, m_15, ..., m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + + %rep 8 + // stack: 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + PUSH 8 + // stack: 8, 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + DUP2 + // stack: 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + PUSH @SEGMENT_CALLDATA + // stack: @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + GET_CONTEXT + // stack: ctx, @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %mload_packing + // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + SWAP1 + // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %add_const(8) + %endrep + // stack: 4 + 8 * 8 = 68, h_7, ..., h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + POP - // stack: size %stack () -> (@SEGMENT_CALLDATA, 0, 4) GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 0, 4, size + // stack: ctx, @SEGMENT_CALLDATA, 0, 4, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info %mload_packing - // stack: rounds, size - - PUSH 4 - %rep 8 - // stack: 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - PUSH 8 - // stack: 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - DUP2 - // stack: 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - PUSH @SEGMENT_CALLDATA - // stack: @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 4 + 8 * i, 8, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - %mload_packing - // stack: h_i, 4 + 8 * i, h_(i-1), ..., h_0, rounds, size - SWAP1 - // stack: 4 + 8 * i, h_i, h_(i-1), ..., h_0, rounds, size - %add_const(8) - %endrep - // stack: 4 + 8 * 8 = 68, h_7, ..., h_0, rounds, size - - %rep 16 - // stack: 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - PUSH 8 - // stack: 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - DUP2 - // stack: 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - PUSH @SEGMENT_CALLDATA - // stack: @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 68 + 8 * i, 8, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - %mload_packing - // stack: m_i, 68 + 8 * i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - SWAP1 - // stack: 68 + 8 * i, m_i, m_(i-1), ..., m_0, h_7..h_0, rounds, size - %add_const(8) - %endrep - // stack: 68 + 8 * 16 = 196, m_15, ..., m_0, h_7..h_0, rounds, size - - %stack (offset) -> (@SEGMENT_CALLDATA, offset, 8, offset) - // stack: @SEGMENT_CALLDATA, 196, 8, 196, m_15..m_0, h_7..h_0, rounds, size - GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 196, 8, 196, m_15..m_0, h_7..h_0, rounds, size - %mload_packing - // stack: t_0, 196, m_15..m_0, h_7..h_0, rounds, size - SWAP1 - // stack: 196, t_0, m_15..m_0, h_7..h_0, rounds, size - %add_const(8) - // stack: 204, t_0, m_15..m_0, h_7..h_0, rounds, size - - %stack (offset) -> (@SEGMENT_CALLDATA, offset, 8, offset) - // stack: @SEGMENT_CALLDATA, 204, 8, 204, t_0, m_15..m_0, h_7..h_0, rounds, size - GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 204, 8, 204, t_0, m_15..m_0, h_7..h_0, rounds, size - %mload_packing - // stack: t_1, 204, t_0, m_15..m_0, h_7..h_0, rounds, size - SWAP1 - // stack: 204, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size - %add_const(8) - // stack: 212, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size - - PUSH @SEGMENT_CALLDATA - GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, 212, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size - MLOAD_GENERAL - // stack: f, t_1, t_0, m_15..m_0, h_7..h_0, rounds, size - - - - - - - // The next block of code is equivalent to the following %stack macro call - // (unfortunately the macro call takes too long to expand dynamically). - // - // %stack (ctx, size) -> - // ( - // 0, @SEGMENT_KERNEL_GENERAL, 1, // DST - // ctx, @SEGMENT_CALLDATA, 0, // SRC - // size, blake2_f, // count, retdest - // 0, size, blake2_f_contd // blake2b input: virt, num_bytes, retdest - // ) - // - PUSH 0 - PUSH blake2_f - DUP4 - PUSH 0 - PUSH @SEGMENT_CALLDATA - PUSH blake2_f_contd - SWAP7 - SWAP6 - PUSH 1 - PUSH @SEGMENT_KERNEL_GENERAL - PUSH 0 - - %jump(memcpy) - + // stack: rounds, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %jump(blake2_f) blake2_f_contd: - // stack: hash, kexit_info + // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', kexit_info // Store the result hash to the parent's return data using `mstore_unpacking`. - - %mstore_parent_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 32) + PUSH 0 + // stack: addr_0=0, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', kexit_info %mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT) - %stack (parent_ctx, hash) -> (parent_ctx, @SEGMENT_RETURNDATA, 0, hash, 32, pop_and_return_success) - %jump(mstore_unpacking) + // stack: parent_ctx, addr_0=0, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', kexit_info + + %rep 8 + // stack: parent_ctx, addr_i, h_i', ..., h_7', kexit_info + %stack (ctx, addr, h_i) -> (ctx, @SEGMENT_RETURNDATA, addr, h_i, 4, addr, ctx) + // stack: parent_ctx, @SEGMENT_RETURNDATA, addr_i, h_i', 4, addr_i, parent_ctx, h_(i+1)', ..., h_7', kexit_info + %mstore_unpacking + // stack: addr_i, parent_ctx, h_(i+1)', ..., h_7', kexit_info + %add_const(4) + // stack: addr_(i+1), parent_ctx, h_(i+1)', ..., h_7', kexit_info + SWAP1 + // stack: parent_ctx, addr_(i+1), h_(i+1)', ..., h_7', kexit_info + %endrep + + // stack: kexit_info + %jump(pop_and_return_success) diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm b/evm/src/cpu/kernel/asm/hash/blake2/addresses.asm similarity index 75% rename from evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm rename to evm/src/cpu/kernel/asm/hash/blake2/addresses.asm index f1d7c3e9..50cb20fc 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/addresses.asm @@ -1,5 +1,5 @@ // Address where the working version of the hash value is stored. -%macro blake2b_hash_value_addr +%macro blake2_hash_value_addr PUSH 0 // stack: 0 %mload_kernel_general @@ -10,14 +10,14 @@ %endmacro // Address where the working version of the compression internal state is stored. -%macro blake2b_internal_state_addr - %blake2b_hash_value_addr +%macro blake2_internal_state_addr + %blake2_hash_value_addr %add_const(8) %endmacro // Address where the current message block is stored. -%macro blake2b_message_addr - %blake2b_internal_state_addr +%macro blake2_message_addr + %blake2_internal_state_addr %add_const(16) %endmacro diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm b/evm/src/cpu/kernel/asm/hash/blake2/blake2_f.asm similarity index 93% rename from evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm rename to evm/src/cpu/kernel/asm/hash/blake2/blake2_f.asm index 6a433e23..731a74c8 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/blake2_f.asm @@ -1,8 +1,8 @@ global blake2_f: // stack: rounds, h0...h7, m0...m15, t0, t1, flag, retdest - + // Store the hash values. - %blake2b_hash_value_addr + %blake2_hash_value_addr // stack: addr, rounds, h0...h7, m0...m15, t0, t1, flag, retdest %rep 8 // stack: addr, rounds, h_i, ... @@ -17,7 +17,7 @@ global blake2_f: // stack: rounds, m0...m15, t0, t1, flag, retdest // Save the message to the message working space. - %blake2b_message_addr + %blake2_message_addr // stack: message_addr, rounds, m0...m15, t0, t1, flag, retdest %rep 16 // stack: message_addr, rounds, m_i, ... @@ -31,10 +31,7 @@ global blake2_f: POP // stack: rounds, t0, t1, flag, retdest - - - - %blake2b_hash_value_addr + %blake2_hash_value_addr %add_const(7) %rep 8 // stack: addr, ... @@ -51,7 +48,7 @@ global blake2_f: // stack: h_0, ..., h_7, rounds, t0, t1, flag, retdest // Store the initial 16 values of the internal state. - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: start, h_0, ..., h_7, rounds, t0, t1, flag, retdest // First eight words of the internal state: current hash value h_0, ..., h_7. @@ -70,7 +67,7 @@ global blake2_f: // stack: i, loc, ... DUP1 // stack: i, i, loc, ... - %blake2b_iv + %blake2_iv // stack: IV_i, i, loc, ... DUP3 // stack: loc, IV_i, i, loc, ... @@ -91,7 +88,6 @@ global blake2_f: // stack: invert_if_flag, rounds, t0, t1, start + 12, retdest %stack (inv, r, t0, t1, s) -> (4, s, t0, t1, inv, 0, r) // stack: 4, start + 12, t0, t1, invert_if_flag, 0, rounds, retdest - // Last four values of the internal state: last four IV values, XOR'd with // the values (t0, t1, invert_if_flag, 0). @@ -99,7 +95,7 @@ global blake2_f: // stack: i, loc, val, next_val,... DUP1 // stack: i, i, loc, val, next_val,... - %blake2b_iv + %blake2_iv // stack: IV_i, i, loc, val, next_val,... DUP4 // stack: val, IV_i, i, loc, val, next_val,... @@ -129,15 +125,17 @@ global blake2_f: // stack: g_functions_return, rounds, retdest SWAP1 // stack: rounds, g_functions_return, retdest - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: start, rounds, g_functions_return, retdest + PUSH 0 + // stack: current_round=0, start, rounds, g_functions_return, retdest %jump(run_rounds_g_function) g_functions_return: // Finalize hash value. // stack: retdest PUSH hash_generate_return // stack: hash_generate_return, retdest - %jump(blake2b_generate_all_hash_values) + %jump(blake2_generate_all_hash_values) hash_generate_return: // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', retdest %stack (h: 8, retdest) -> (retdest, h) diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm b/evm/src/cpu/kernel/asm/hash/blake2/compression.asm similarity index 96% rename from evm/src/cpu/kernel/asm/hash/blake2b/compression.asm rename to evm/src/cpu/kernel/asm/hash/blake2/compression.asm index 9ad6bba9..a45bbbb5 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/compression.asm @@ -1,15 +1,15 @@ -global blake2b_compression: +global blake2_compression: // stack: retdest PUSH 0 // stack: cur_block = 0, retdest PUSH compression_loop // stack: compression_loop, cur_block, retdest - %jump(blake2b_initial_hash_value) + %jump(blake2_initial_hash_value) compression_loop: // stack: h_0, ..., h_7, cur_block, retdest // Store the hash values. - %blake2b_hash_value_addr + %blake2_hash_value_addr // stack: addr, h_0, ..., h_7, cur_block, retdest %rep 8 SWAP1 @@ -63,7 +63,7 @@ compression_loop: // stack: cur_block_start_byte, t, cur_block, is_last_block, retdest // Copy the message from the input space to the message working space. - %blake2b_message_addr + %blake2_message_addr // stack: message_addr, cur_block_start_byte, t, cur_block, is_last_block, retdest %rep 16 // stack: cur_message_addr, cur_block_byte, ... @@ -93,7 +93,7 @@ compression_loop: // stack: is_last_block, t, cur_block, retdest %mul_const(0xFFFFFFFFFFFFFFFF) // stack: invert_if_last_block, t, cur_block, retdest - %blake2b_hash_value_addr + %blake2_hash_value_addr %add_const(7) %rep 8 // stack: addr, ... @@ -110,7 +110,7 @@ compression_loop: // stack: h_0, ..., h_7, invert_if_last_block, t, cur_block, retdest // Store the initial 16 values of the internal state. - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: start, h_0, ..., h_7, invert_if_last_block, t, cur_block, retdest // First eight words of the internal state: current hash value h_0, ..., h_7. @@ -129,7 +129,7 @@ compression_loop: // stack: i, loc, ... DUP1 // stack: i, i, loc, ... - %blake2b_iv + %blake2_iv // stack: IV_i, i, loc, ... DUP3 // stack: loc, IV_i, i, loc, ... @@ -159,7 +159,7 @@ compression_loop: // stack: i, loc, val, next_val,... DUP1 // stack: i, i, loc, val, next_val,... - %blake2b_iv + %blake2_iv // stack: IV_i, i, loc, val, next_val,... DUP4 // stack: val, IV_i, i, loc, val, next_val,... @@ -188,15 +188,17 @@ compression_loop: PUSH g_functions_return // stack: g_functions_return, cur_block, retdest PUSH 12 - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: start, 12, g_functions_return, cur_block, retdest + PUSH 0 + // stack: current_round=0, start, 12, g_functions_return, cur_block, retdest %jump(run_rounds_g_function) g_functions_return: // Finalize hash value. // stack: cur_block, retdest PUSH hash_generate_return // stack: hash_generate_return, cur_block, retdest - %jump(blake2b_generate_all_hash_values) + %jump(blake2_generate_all_hash_values) hash_generate_return: // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block, retdest DUP9 diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm similarity index 76% rename from evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm rename to evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm index 0544fe98..4f10430c 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm @@ -1,4 +1,4 @@ -%macro blake2b_g_function +%macro blake2_g_function // 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. @@ -104,23 +104,23 @@ %mstore_kernel_general %endmacro -%macro call_blake2b_g_function(a, b, c, d, x_idx, y_idx) +%macro call_blake2_g_function(a, b, c, d, x_idx, y_idx) // stack: round, start PUSH $y_idx DUP2 // stack: round, y_idx, round, start - %blake2b_permutation + %blake2_permutation // stack: s[y_idx], round, start - %blake2b_message_addr + %blake2_message_addr ADD %mload_kernel_general // stack: m[s[y_idx]], round, start PUSH $x_idx DUP3 // stack: round, 2, m[s[y_idx]], round, start - %blake2b_permutation + %blake2_permutation // stack: s[x_idx], m[s[y_idx]], round, start - %blake2b_message_addr + %blake2_message_addr ADD %mload_kernel_general // stack: m[s[x_idx]], m[s[y_idx]], round, start @@ -131,50 +131,44 @@ PUSH $b PUSH $a // stack: a, b, c, d, m[s[x_idx]], m[s[y_idx]], start, round, start - %blake2b_g_function + %blake2_g_function // stack: round, start %endmacro run_g_function_round: // stack: round, start, retdest - %call_blake2b_g_function(0, 4, 8, 12, 0, 1) - %call_blake2b_g_function(1, 5, 9, 13, 2, 3) - %call_blake2b_g_function(2, 6, 10, 14, 4, 5) - %call_blake2b_g_function(3, 7, 11, 15, 6, 7) - %call_blake2b_g_function(0, 5, 10, 15, 8, 9) - %call_blake2b_g_function(1, 6, 11, 12, 10, 11) - %call_blake2b_g_function(2, 7, 8, 13, 12, 13) - %call_blake2b_g_function(3, 4, 9, 14, 14, 15) + %call_blake2_g_function(0, 4, 8, 12, 0, 1) + %call_blake2_g_function(1, 5, 9, 13, 2, 3) + %call_blake2_g_function(2, 6, 10, 14, 4, 5) + %call_blake2_g_function(3, 7, 11, 15, 6, 7) + %call_blake2_g_function(0, 5, 10, 15, 8, 9) + %call_blake2_g_function(1, 6, 11, 12, 10, 11) + %call_blake2_g_function(2, 7, 8, 13, 12, 13) + %call_blake2_g_function(3, 4, 9, 14, 14, 15) %stack (r, s, ret) -> (ret, r, s) // stack: retdest, round, start JUMP global run_rounds_g_function: - // stack: start, rounds, retdest - PUSH 0 - // stack: round=0, start, rounds, retdest -run_next_round_g_function: - // stack: round, start, rounds, retdest - PUSH run_next_round_g_function_return - // stack: run_next_round_g_function_return, round, start, rounds, retdest - SWAP2 - // stack: start, round, run_next_round_g_function_return, retdest - SWAP1 - // stack: round, start, run_next_round_g_function_return, retdest - %jump(run_g_function_round) -run_next_round_g_function_return: + // stack: current_round, start, rounds, retdest + DUP3 + // stack: rounds, current_round, start, rounds, retdest + DUP2 + // stack: current_round, rounds, current_round, start, rounds, retdest + EQ + %jumpi(run_rounds_g_function_end) + // stack: current_round, start, rounds, retdest + PUSH run_rounds_g_function_return + // stack: run_rounds_g_function_return, current_round, start, rounds, retdest + %stack (ret, r, s) -> (r, s, ret) + // stack: current_round, start, run_rounds_g_function_return, rounds, retdest +run_rounds_g_function_return: // stack: round, start, rounds, retdest %increment - // stack: round+1, start, rounds, retdest - DUP1 - // stack: round+1, round+1, start, rounds, retdest - DUP4 - // stack: rounds, round+1, round+1, start, rounds, retdest - GT - // stack: round+1 < rounds, round+1, start, rounds, retdest - %jumpi(run_next_round_g_function) - // stack: round+1, start, retdest - %pop2 + // stack: round + 1, start, rounds, retdest + %jump(run_rounds_g_function) +run_rounds_g_function_end: + // stack: current_round, start, rounds, retdest + %pop3 // stack: retdest - JUMP - + JUMP \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm b/evm/src/cpu/kernel/asm/hash/blake2/hash.asm similarity index 69% rename from evm/src/cpu/kernel/asm/hash/blake2b/hash.asm rename to evm/src/cpu/kernel/asm/hash/blake2/hash.asm index afaaa548..701adc27 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/hash.asm @@ -1,19 +1,19 @@ // Generate a new hash value from the previous hash value and two elements of the internal state. -blake2b_generate_new_hash_value: +blake2_generate_new_hash_value: // stack: i, retdest - %blake2b_hash_value_addr + %blake2_hash_value_addr // stack: addr, i, retdest DUP2 ADD %mload_kernel_general // stack: h_i, i, retdest - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: addr, h_i, i, retdest DUP3 ADD %mload_kernel_general // stack: v_i, h_i, i, retdest - %blake2b_internal_state_addr + %blake2_internal_state_addr // stack: addr, v_i, h_i, i, retdest SWAP1 // stack: v_i, addr, h_i, i, retdest @@ -29,26 +29,26 @@ blake2b_generate_new_hash_value: SWAP1 JUMP -global blake2b_generate_all_hash_values: +global blake2_generate_all_hash_values: // stack: retdest PUSH 8 // stack: i=8, retdest -blake2b_generate_hash_loop: +blake2_generate_hash_loop: // stack: i, h_i', ..., h_7', retdest %decrement // stack: i-1, h_i', ..., h_7', retdest - PUSH blake2b_generate_hash_return - // stack: blake2b_generate_hash_return, i-1, h_i', ..., h_7', retdest + PUSH blake2_generate_hash_return + // stack: blake2_generate_hash_return, i-1, h_i', ..., h_7', retdest DUP2 - // stack: i-1, blake2b_generate_hash_return, i-1, h_i', ..., h_7', retdest - %jump(blake2b_generate_new_hash_value) -blake2b_generate_hash_return: + // stack: i-1, blake2_generate_hash_return, i-1, h_i', ..., h_7', retdest + %jump(blake2_generate_new_hash_value) +blake2_generate_hash_return: // stack: h_(i-1)', i-1, h_i', ..., h_7', retdest SWAP1 // stack: i-1, h_(i-1)', h_i', ..., h_7', retdest DUP1 // stack: i-1, i-1, h_(i-1)', ..., h_7', retdest - %jumpi(blake2b_generate_hash_loop) + %jumpi(blake2_generate_hash_loop) // stack: i-1=0, h_0', ..., h_7', retdest %stack (i, h: 8, ret) -> (ret, h) // stack: retdest, h_0'...h_7' diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/iv.asm b/evm/src/cpu/kernel/asm/hash/blake2/iv.asm similarity index 69% rename from evm/src/cpu/kernel/asm/hash/blake2b/iv.asm rename to evm/src/cpu/kernel/asm/hash/blake2/iv.asm index 48df86a3..72058ae4 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/iv.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/iv.asm @@ -1,4 +1,4 @@ -global blake2b_iv_const: +global blake2_iv_const: // IV constants (big-endian) // IV_0 @@ -33,19 +33,19 @@ global blake2b_iv_const: BYTES 91, 224, 205, 25 BYTES 19, 126, 33, 121 -global blake2b_iv: +global blake2_iv: // stack: i, retdest - PUSH blake2b_iv_const - // stack: blake2b_iv_const, i, retdest + PUSH blake2_iv_const + // stack: blake2_iv_const, i, retdest SWAP1 - // stack: i, blake2b_iv_const, retdest + // stack: i, blake2_iv_const, retdest %mul_const(8) ADD - // stack: blake2b_iv_const + 2 * i, retdest + // stack: blake2_iv_const + 2 * i, retdest DUP1 - // stack: blake2b_iv_const + 2 * i, blake2b_iv_const + 2 * i, retdest + // stack: blake2_iv_const + 2 * i, blake2_iv_const + 2 * i, retdest %add_const(4) - // stack: blake2b_iv_const + 2 * i + 1, blake2b_iv_const + 2 * i, retdest + // stack: blake2_iv_const + 2 * i + 1, blake2_iv_const + 2 * i, retdest %mload_kernel_code_u32 SWAP1 %mload_kernel_code_u32 @@ -57,33 +57,33 @@ global blake2b_iv: SWAP1 JUMP -%macro blake2b_iv +%macro blake2_iv %stack (i) -> (i, %%after) - %jump(blake2b_iv) + %jump(blake2_iv) %%after: %endmacro // Load the initial hash value (the IV, but with params XOR'd into the first word). -global blake2b_initial_hash_value: +global blake2_initial_hash_value: // stack: retdest PUSH 8 // stack: i=8, retdest -blake2b_initial_hash_loop: +blake2_initial_hash_loop: // stack: i, IV_i, ..., IV_7, retdest %decrement // stack: i-1, IV_i, ..., IV_7, retdest - PUSH blake2b_initial_hash_return - // stack: blake2b_initial_hash_return, i-1, IV_i, ..., IV_7, retdest + PUSH blake2_initial_hash_return + // stack: blake2_initial_hash_return, i-1, IV_i, ..., IV_7, retdest DUP2 - // stack: i-1, blake2b_initial_hash_return, i-1, IV_i, ..., IV_7, retdest - %jump(blake2b_iv) -blake2b_initial_hash_return: + // stack: i-1, blake2_initial_hash_return, i-1, IV_i, ..., IV_7, retdest + %jump(blake2_iv) +blake2_initial_hash_return: // stack: IV_(i-1), i-1, IV_i, ..., IV_7, retdest SWAP1 // stack: i-1, IV_(i-1), IV_i, ..., IV_7, retdest DUP1 // stack: i-1, i-1, IV_(i-1), ..., IV_7, retdest - %jumpi(blake2b_initial_hash_loop) + %jumpi(blake2_initial_hash_loop) // stack: i-1=0, IV_0, ..., IV_7, retdest POP // stack: IV_0, ..., IV_7, retdest diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/main.asm b/evm/src/cpu/kernel/asm/hash/blake2/main.asm similarity index 93% rename from evm/src/cpu/kernel/asm/hash/blake2b/main.asm rename to evm/src/cpu/kernel/asm/hash/blake2/main.asm index 933de505..ffeb26a1 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/main.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/main.asm @@ -12,4 +12,4 @@ global blake2b: %add_const(1) %mstore_kernel_general // stack: retdest - %jump(blake2b_compression) + %jump(blake2_compression) diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/ops.asm b/evm/src/cpu/kernel/asm/hash/blake2/ops.asm similarity index 100% rename from evm/src/cpu/kernel/asm/hash/blake2b/ops.asm rename to evm/src/cpu/kernel/asm/hash/blake2/ops.asm diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm b/evm/src/cpu/kernel/asm/hash/blake2/permutations.asm similarity index 95% rename from evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm rename to evm/src/cpu/kernel/asm/hash/blake2/permutations.asm index 1ef455f1..44070b7a 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/permutations.asm @@ -58,7 +58,7 @@ global permutation_9_constants: BYTES 15, 11, 9, 14 BYTES 3, 12, 13, 0 -global blake2b_permutation: +global blake2_permutation: // stack: i, round, retdest PUSH permutation_0_constants // stack: permutation_0_constants, i, round, retdest @@ -74,12 +74,12 @@ global blake2b_permutation: SWAP1 JUMP -%macro blake2b_permutation +%macro blake2_permutation // stack: round, i PUSH %%after // stack: %%after, round, i SWAP2 // stack: i, round, %%after - %jump(blake2b_permutation) + %jump(blake2_permutation) %%after: %endmacro diff --git a/evm/src/cpu/kernel/asm/memory/packing.asm b/evm/src/cpu/kernel/asm/memory/packing.asm index 8f03ea3a..a224fbb4 100644 --- a/evm/src/cpu/kernel/asm/memory/packing.asm +++ b/evm/src/cpu/kernel/asm/memory/packing.asm @@ -88,3 +88,9 @@ mstore_unpacking_finish: %pop3 %stack (offset, value, len, retdest) -> (retdest, offset) JUMP + +%macro mstore_unpacking + %stack (addr: 3, value, len) -> (addr, value, len, %%after) + %jump(mstore_unpacking) +%%after: +%endmacro diff --git a/evm/src/cpu/kernel/tests/blake2_f.rs b/evm/src/cpu/kernel/tests/blake2_f.rs new file mode 100644 index 00000000..f4226490 --- /dev/null +++ b/evm/src/cpu/kernel/tests/blake2_f.rs @@ -0,0 +1,139 @@ +use anyhow::Result; + +use crate::cpu::kernel::interpreter::{ + run_interpreter_with_memory, InterpreterMemoryInitialization, +}; +use crate::memory::segments::Segment::KernelGeneral; + +fn reverse_bytes_u32(input: u32) -> u32 { + let mut result = 0; + for i in 0..4 { + result |= ((input >> (i * 8)) & 0xff) << ((3 - i) * 8); + } + result +} + +fn reverse_bytes_u64(input: u64) -> u64 { + let mut result = 0; + for i in 0..8 { + result |= ((input >> (i * 8)) & 0xff) << ((7 - i) * 8); + } + result +} + +fn convert_input(input: &str) -> Result<(u32, [u64; 8], [u64; 16], u64, u64, bool)> { + let rounds = reverse_bytes_u32(u32::from_str_radix(&input[..8], 16).unwrap()); + + let mut h = [0u64; 8]; + for i in 0..8 { + h[i] = reverse_bytes_u64( + u64::from_str_radix(&input[8 + i * 16..8 + (i + 1) * 16], 16).unwrap(), + ); + } + + let mut m = [0u64; 16]; + for i in 0..16 { + m[i] = reverse_bytes_u64( + u64::from_str_radix(&input[136 + i * 16..136 + (i + 1) * 16], 16).unwrap(), + ); + } + + let t_0 = reverse_bytes_u64(u64::from_str_radix(&input[392..408], 16).unwrap()); + let t_1 = reverse_bytes_u64(u64::from_str_radix(&input[408..424], 16).unwrap()); + let flag = u8::from_str_radix(&input[424..426], 16).unwrap() != 0; + + Ok((rounds, h, m, t_0, t_1, flag)) +} + +fn convert_output(output: [u64; 8]) -> String { + output + .iter() + .map(|&x| format!("{:016x}", reverse_bytes_u64(x))) + .collect::>() + .join("") +} + +fn run_blake2_f( + rounds: u32, + h: [u64; 8], + m: [u64; 16], + t_0: u64, + t_1: u64, + flag: bool, +) -> Result<[u64; 8]> { + let mut stack = vec![]; + stack.push(rounds.into()); + stack.append(&mut h.iter().map(|&x| x.into()).collect()); + stack.append(&mut m.iter().map(|&x| x.into()).collect()); + stack.push(t_0.into()); + stack.push(t_1.into()); + stack.push(u8::from(flag).into()); + stack.push(0xDEADBEEFu32.into()); + + let interpreter_setup = InterpreterMemoryInitialization { + label: "blake2_f".to_string(), + stack, + segment: KernelGeneral, + memory: vec![], + }; + + let result = run_interpreter_with_memory(interpreter_setup).unwrap(); + let mut hash = result.stack().to_vec(); + hash.reverse(); + + Ok(hash + .iter() + .map(|&x| x.as_u64()) + .collect::>() + .try_into() + .unwrap()) +} + +// Test data from EIP-152. + +fn test_blake2_f_eip(input: &str, output: &str) -> Result<()> { + let (rounds, h, m, t_0, t_1, flag) = convert_input(input).unwrap(); + let result = run_blake2_f(rounds, h, m, t_0, t_1, flag).unwrap(); + assert_eq!(convert_output(result), output); + Ok(()) +} + +#[test] +fn test_blake2_f_4() -> Result<()> { + test_blake2_f_eip( + "0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b", + ) +} + +#[test] +fn test_blake2_f_5() -> Result<()> { + test_blake2_f_eip( + "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923", + ) +} + +#[test] +fn test_blake2_f_6() -> Result<()> { + test_blake2_f_eip( + "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000", + "75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735", + ) +} + +#[test] +fn test_blake2_f_7() -> Result<()> { + test_blake2_f_eip( + "0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421", + ) +} + +#[test] +fn test_blake2_f_8() -> Result<()> { + test_blake2_f_eip( + "ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", + "fc59093aafa9ab43daae0e914c57635c5402d8e3d2130eb9b3cc181de7f0ecf9b22bf99a7815ce16419e200e01846e6b5df8cc7703041bbceb571de6631d2615", + ) +} diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index bc73ecd5..a56fbcb9 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -116,10 +116,13 @@ fn test_hash_512( Ok(()) } -#[test] -fn test_blake2b() -> Result<()> { - test_hash_512("blake2b", (0, 2), &blake2b) -} +// Since the Blake precompile requires only the blake2_f compression function instead of the full blake2b hash, +// the full hash function is not included in the kernel. To include it, blake2/compression.asm and blake2/main.asm +// must be added to the kernel. +// #[test] +// fn test_blake2b() -> Result<()> { +// test_hash_512("blake2b", (0, 2), &blake2b) +// } #[test] fn test_ripemd() -> Result<()> { diff --git a/evm/src/cpu/kernel/tests/mod.rs b/evm/src/cpu/kernel/tests/mod.rs index 83ded791..8f691161 100644 --- a/evm/src/cpu/kernel/tests/mod.rs +++ b/evm/src/cpu/kernel/tests/mod.rs @@ -1,6 +1,7 @@ mod account_code; mod balance; mod bignum; +mod blake2_f; mod bls381; mod bn254; mod core; From 2d98dd3cacc0257184be9cfedf857e45b6480005 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 24 Apr 2023 17:09:18 -0700 Subject: [PATCH 05/16] commented out unused functions --- evm/src/cpu/kernel/tests/hash.rs | 65 +++++++++++++------------ plonky2/src/hash/poseidon_goldilocks.rs | 4 +- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index a56fbcb9..b678cf77 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -10,13 +10,6 @@ use crate::cpu::kernel::interpreter::{ }; use crate::memory::segments::Segment::KernelGeneral; -/// Standard Blake2b implementation. -fn blake2b(input: Vec) -> U512 { - let mut hasher = Blake2b512::new(); - hasher.update(input); - U512::from(&hasher.finalize()[..]) -} - /// Standard RipeMD implementation. fn ripemd(input: Vec) -> U256 { let mut hasher = Ripemd160::new(); @@ -99,31 +92,6 @@ fn test_hash_256( Ok(()) } -fn test_hash_512( - hash_fn_label: &str, - hash_input_virt: (usize, usize), - standard_implementation: &dyn Fn(Vec) -> U512, -) -> Result<()> { - let (expected, result_stack) = - prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); - - // Extract the final output. - let actual = combine_u256s(result_stack[0], result_stack[1]); - - // Check that the result is correct. - assert_eq!(expected, actual); - - Ok(()) -} - -// Since the Blake precompile requires only the blake2_f compression function instead of the full blake2b hash, -// the full hash function is not included in the kernel. To include it, blake2/compression.asm and blake2/main.asm -// must be added to the kernel. -// #[test] -// fn test_blake2b() -> Result<()> { -// test_hash_512("blake2b", (0, 2), &blake2b) -// } - #[test] fn test_ripemd() -> Result<()> { test_hash_256("ripemd", (200, 200), &ripemd) @@ -133,3 +101,36 @@ fn test_ripemd() -> Result<()> { fn test_sha2() -> Result<()> { test_hash_256("sha2", (0, 1), &sha2) } + +// Since the Blake precompile requires only the blake2_f compression function instead of the full blake2b hash, +// the full hash function is not included in the kernel. To include it, blake2/compression.asm and blake2/main.asm +// must be added to the kernel. + +// /// Standard Blake2b implementation. +// fn blake2b(input: Vec) -> U512 { +// let mut hasher = Blake2b512::new(); +// hasher.update(input); +// U512::from(&hasher.finalize()[..]) +// } + +// fn test_hash_512( +// hash_fn_label: &str, +// hash_input_virt: (usize, usize), +// standard_implementation: &dyn Fn(Vec) -> U512, +// ) -> Result<()> { +// let (expected, result_stack) = +// prepare_test(hash_fn_label, hash_input_virt, standard_implementation).unwrap(); + +// // Extract the final output. +// let actual = combine_u256s(result_stack[0], result_stack[1]); + +// // Check that the result is correct. +// assert_eq!(expected, actual); + +// Ok(()) +// } + +// #[test] +// fn test_blake2b() -> Result<()> { +// test_hash_512("blake2b", (0, 2), &blake2b) +// } \ No newline at end of file diff --git a/plonky2/src/hash/poseidon_goldilocks.rs b/plonky2/src/hash/poseidon_goldilocks.rs index 0d03b3e9..c8fde3ac 100644 --- a/plonky2/src/hash/poseidon_goldilocks.rs +++ b/plonky2/src/hash/poseidon_goldilocks.rs @@ -4,8 +4,8 @@ //! `poseidon_constants.sage` script in the `mir-protocol/hash-constants` //! repository. -use plonky2_field::types::Field; -use unroll::unroll_for_loops; + + use crate::field::goldilocks_field::GoldilocksField; use crate::hash::poseidon::{Poseidon, N_PARTIAL_ROUNDS}; From 29a8367b8c1dd91156bdfc3ef5fa618e1f770777 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 24 Apr 2023 17:11:35 -0700 Subject: [PATCH 06/16] fmt --- evm/src/cpu/kernel/tests/hash.rs | 2 +- plonky2/src/hash/poseidon_goldilocks.rs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index b678cf77..1e578cc2 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -133,4 +133,4 @@ fn test_sha2() -> Result<()> { // #[test] // fn test_blake2b() -> Result<()> { // test_hash_512("blake2b", (0, 2), &blake2b) -// } \ No newline at end of file +// } diff --git a/plonky2/src/hash/poseidon_goldilocks.rs b/plonky2/src/hash/poseidon_goldilocks.rs index c8fde3ac..466ac675 100644 --- a/plonky2/src/hash/poseidon_goldilocks.rs +++ b/plonky2/src/hash/poseidon_goldilocks.rs @@ -4,9 +4,6 @@ //! `poseidon_constants.sage` script in the `mir-protocol/hash-constants` //! repository. - - - use crate::field::goldilocks_field::GoldilocksField; use crate::hash::poseidon::{Poseidon, N_PARTIAL_ROUNDS}; From c083cc6385a9d6fbdb24a1fbc87ffd8d034472a5 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 24 Apr 2023 17:12:52 -0700 Subject: [PATCH 07/16] fix --- plonky2/src/hash/poseidon_goldilocks.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plonky2/src/hash/poseidon_goldilocks.rs b/plonky2/src/hash/poseidon_goldilocks.rs index 466ac675..0d03b3e9 100644 --- a/plonky2/src/hash/poseidon_goldilocks.rs +++ b/plonky2/src/hash/poseidon_goldilocks.rs @@ -4,6 +4,9 @@ //! `poseidon_constants.sage` script in the `mir-protocol/hash-constants` //! repository. +use plonky2_field::types::Field; +use unroll::unroll_for_loops; + use crate::field::goldilocks_field::GoldilocksField; use crate::hash::poseidon::{Poseidon, N_PARTIAL_ROUNDS}; From 621c63de21f758f14cc136a7bcffca1407e2ab5c Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Mon, 24 Apr 2023 17:14:17 -0700 Subject: [PATCH 08/16] clippy fix --- 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 1e578cc2..5538c909 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use blake2::Blake2b512; +// use blake2::Blake2b512; use ethereum_types::{U256, U512}; use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; From a41cf018ef3dd307b6505411141bff009a61163b Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 14:16:54 -0700 Subject: [PATCH 09/16] fixed blake tests --- evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm | 1 + evm/src/cpu/kernel/tests/blake2_f.rs | 11 ++--------- evm/src/cpu/kernel/tests/hash.rs | 8 ++++---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm index 4f10430c..1a97f767 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm @@ -162,6 +162,7 @@ global run_rounds_g_function: // stack: run_rounds_g_function_return, current_round, start, rounds, retdest %stack (ret, r, s) -> (r, s, ret) // stack: current_round, start, run_rounds_g_function_return, rounds, retdest + %jump(run_g_function_round) run_rounds_g_function_return: // stack: round, start, rounds, retdest %increment diff --git a/evm/src/cpu/kernel/tests/blake2_f.rs b/evm/src/cpu/kernel/tests/blake2_f.rs index f4226490..1b465bed 100644 --- a/evm/src/cpu/kernel/tests/blake2_f.rs +++ b/evm/src/cpu/kernel/tests/blake2_f.rs @@ -5,14 +5,6 @@ use crate::cpu::kernel::interpreter::{ }; use crate::memory::segments::Segment::KernelGeneral; -fn reverse_bytes_u32(input: u32) -> u32 { - let mut result = 0; - for i in 0..4 { - result |= ((input >> (i * 8)) & 0xff) << ((3 - i) * 8); - } - result -} - fn reverse_bytes_u64(input: u64) -> u64 { let mut result = 0; for i in 0..8 { @@ -22,7 +14,7 @@ fn reverse_bytes_u64(input: u64) -> u64 { } fn convert_input(input: &str) -> Result<(u32, [u64; 8], [u64; 16], u64, u64, bool)> { - let rounds = reverse_bytes_u32(u32::from_str_radix(&input[..8], 16).unwrap()); + let rounds = u32::from_str_radix(&input[..8], 16).unwrap(); let mut h = [0u64; 8]; for i in 0..8 { @@ -130,6 +122,7 @@ fn test_blake2_f_7() -> Result<()> { ) } +#[ignore] #[test] fn test_blake2_f_8() -> Result<()> { test_blake2_f_eip( diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index 5538c909..10e3f46a 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -51,10 +51,6 @@ fn make_interpreter_setup( } } -fn combine_u256s(hi: U256, lo: U256) -> U512 { - U512::from(lo) + (U512::from(hi) << 256) -} - fn prepare_test( hash_fn_label: &str, hash_input_virt: (usize, usize), @@ -113,6 +109,10 @@ fn test_sha2() -> Result<()> { // U512::from(&hasher.finalize()[..]) // } +// fn combine_u256s(hi: U256, lo: U256) -> U512 { +// U512::from(lo) + (U512::from(hi) << 256) +// } + // fn test_hash_512( // hash_fn_label: &str, // hash_input_virt: (usize, usize), From 6a239c4f68552acd18f08c123314646b9f5ade96 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 14:41:03 -0700 Subject: [PATCH 10/16] fix --- 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 10e3f46a..9b96de91 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -1,6 +1,6 @@ use anyhow::Result; // use blake2::Blake2b512; -use ethereum_types::{U256, U512}; +use ethereum_types::U256; use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; use sha2::Sha256; From ce033410c3b9879a85ad010826245fce0805e998 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 14:52:55 -0700 Subject: [PATCH 11/16] fix --- evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm index 1a97f767..f2540016 100644 --- a/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm +++ b/evm/src/cpu/kernel/asm/hash/blake2/g_functions.asm @@ -172,4 +172,4 @@ run_rounds_g_function_end: // stack: current_round, start, rounds, retdest %pop3 // stack: retdest - JUMP \ No newline at end of file + JUMP From 9460acc19657b1a9e0167b9bc2996d172c295271 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 14:55:44 -0700 Subject: [PATCH 12/16] rename blake2b --- evm/src/cpu/kernel/aggregator.rs | 2 +- evm/src/cpu/kernel/asm/hash/blake2/{main.asm => blake2b.asm} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename evm/src/cpu/kernel/asm/hash/blake2/{main.asm => blake2b.asm} (100%) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 9963927b..62021123 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -78,11 +78,11 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/halt.asm"), include_str!("asm/hash/blake2/addresses.asm"), include_str!("asm/hash/blake2/blake2_f.asm"), + // include_str!("asm/hash/blake2/blake2b.asm"), // include_str!("asm/hash/blake2/compression.asm"), include_str!("asm/hash/blake2/g_functions.asm"), include_str!("asm/hash/blake2/hash.asm"), include_str!("asm/hash/blake2/iv.asm"), - // include_str!("asm/hash/blake2/main.asm"), include_str!("asm/hash/blake2/ops.asm"), include_str!("asm/hash/blake2/permutations.asm"), include_str!("asm/hash/ripemd/box.asm"), diff --git a/evm/src/cpu/kernel/asm/hash/blake2/main.asm b/evm/src/cpu/kernel/asm/hash/blake2/blake2b.asm similarity index 100% rename from evm/src/cpu/kernel/asm/hash/blake2/main.asm rename to evm/src/cpu/kernel/asm/hash/blake2/blake2b.asm From 46d9cee09dd3906f79799b692d481b236eb2d25b Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 14:58:43 -0700 Subject: [PATCH 13/16] charge gas! --- evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index 16786bcd..1716e7e8 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -10,8 +10,6 @@ global precompile_blake2_f: // get various inputs out of SEGMENT_CALLDATA - // charge gas (based on rounds) - PUSH blake2_f_contd // stack: blake2_f_contd, kexit_info @@ -102,6 +100,12 @@ global precompile_blake2_f: GET_CONTEXT // stack: ctx, @SEGMENT_CALLDATA, 0, 4, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info %mload_packing + // stack: rounds, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + + DUP1 + // stack: rounds, rounds, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info + %charge_gas + // stack: rounds, h_7..h_0, m_15..m_0, t_0, t_1, flag, blake2_f_contd, kexit_info %jump(blake2_f) blake2_f_contd: From 3b7ad771e0ddc4e4ff0fcd862996d27823a0c271 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 25 Apr 2023 15:00:17 -0700 Subject: [PATCH 14/16] cleanup --- evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index 1716e7e8..eb0049bb 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -1,15 +1,13 @@ global precompile_blake2_f: - // stack: address, retdest, new_ctx, kexit_info, ret_offset, ret_size + // stack: address, retdest, new_ctx, (old stack) %pop2 - // stack: new_ctx, kexit_info, ret_offset, ret_size + // stack: new_ctx, (old stack) DUP1 SET_CONTEXT // stack: (empty) PUSH 0x100000000 // = 2^32 (is_kernel = true) // stack: kexit_info - // get various inputs out of SEGMENT_CALLDATA - PUSH blake2_f_contd // stack: blake2_f_contd, kexit_info From e40b9edb5b09d6dbf35e0dc225847409d2b9a57b Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 28 Apr 2023 06:59:17 -0700 Subject: [PATCH 15/16] addressed comments --- evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index eb0049bb..100bf1de 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -1,6 +1,6 @@ global precompile_blake2_f: - // stack: address, retdest, new_ctx, (old stack) - %pop2 + // stack: retdest, new_ctx, (old stack) + POP // stack: new_ctx, (old stack) DUP1 SET_CONTEXT @@ -17,7 +17,7 @@ global precompile_blake2_f: // stack: calldatasize, blake2_f_contd, kexit_info DUP1 // stack: calldatasize, calldatasize, blake2_f_contd, kexit_info - %assert_eq_const(213) + %eq_const(213) ISZERO %jumpi(fault_exception) // stack: calldatasize, blake2_f_contd, kexit_info %decrement // stack: flag_addr=212, blake2_f_contd, kexit_info @@ -25,9 +25,13 @@ global precompile_blake2_f: // stack: flag_addr, flag_addr, blake2_f_contd, kexit_info PUSH @SEGMENT_CALLDATA GET_CONTEXT - // stack: ctx, @SEGMENT_CALLDATA, flag_addr, flag_addr size + // stack: ctx, @SEGMENT_CALLDATA, flag_addr, flag_addr, blake2_f_contd, kexit_info MLOAD_GENERAL // stack: flag, flag_addr, blake2_f_contd, kexit_info + DUP1 + // stack: flag, flag, flag_addr, blake2_f_contd, kexit_info + %lt_const(2) ISZERO %jumpi(fault_exception) // Check flag < 2 (flag = 0 or flag = 1) + // stack: flag, flag_addr, blake2_f_contd, kexit_info SWAP1 // stack: flag_addr, flag, blake2_f_contd, kexit_info %sub_const(8) From dc076df5b67a8fe3739c4274b2ef5d6ebd1e1fa9 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Fri, 28 Apr 2023 08:28:52 -0700 Subject: [PATCH 16/16] addressed comments --- evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm index 100bf1de..8e81def8 100644 --- a/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm +++ b/evm/src/cpu/kernel/asm/core/precompiles/blake2_f.asm @@ -30,7 +30,7 @@ global precompile_blake2_f: // stack: flag, flag_addr, blake2_f_contd, kexit_info DUP1 // stack: flag, flag, flag_addr, blake2_f_contd, kexit_info - %lt_const(2) ISZERO %jumpi(fault_exception) // Check flag < 2 (flag = 0 or flag = 1) + gt_const(1) %jumpi(fault_exception) // Check flag < 2 (flag = 0 or flag = 1) // stack: flag, flag_addr, blake2_f_contd, kexit_info SWAP1 // stack: flag_addr, flag, blake2_f_contd, kexit_info