initial work on blake precompile

This commit is contained in:
Nicholas Ward 2023-04-20 15:11:19 -07:00
parent c0ced26f5e
commit 5f564b6782
7 changed files with 217 additions and 15 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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),
];