diff --git a/evm/Cargo.toml b/evm/Cargo.toml index 03850f7a..f6494d7a 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" [dependencies] anyhow = "1.0.40" -env_logger = "0.9.0" +blake2 = "0.10.5" +env_logger = "0.10.0" eth_trie_utils = "0.4.0" ethereum-types = "0.14.0" hex = { version = "0.4.3", optional = true } @@ -23,11 +24,9 @@ plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] plonky2_util = { path = "../util" } rand = "0.8.5" rand_chacha = "0.3.1" -ripemd = "0.1.3" rlp = "0.5.1" rlp-derive = "0.1.0" serde = { version = "1.0.144", features = ["derive"] } -sha2 = "0.10.2" static_assertions = "1.1.0" tiny-keccak = "2.0.2" @@ -37,6 +36,8 @@ jemallocator = "0.5.0" [dev-dependencies] criterion = "0.4.0" hex = "0.4.3" +ripemd = "0.1.3" +sha2 = "0.10.6" [features] default = ["parallel"] diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index af112613..7504a26c 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -43,6 +43,28 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/moddiv.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/ops.asm"), + include_str!("asm/hash/blake2b/permutations.asm"), + include_str!("asm/hash/blake2b/store.asm"), + include_str!("asm/hash/ripemd/box.asm"), + include_str!("asm/hash/ripemd/compression.asm"), + include_str!("asm/hash/ripemd/constants.asm"), + include_str!("asm/hash/ripemd/functions.asm"), + include_str!("asm/hash/ripemd/main.asm"), + include_str!("asm/hash/ripemd/memory.asm"), + include_str!("asm/hash/ripemd/update.asm"), + include_str!("asm/hash/sha2/compression.asm"), + include_str!("asm/hash/sha2/constants.asm"), + include_str!("asm/hash/sha2/message_schedule.asm"), + include_str!("asm/hash/sha2/ops.asm"), + include_str!("asm/hash/sha2/store_pad.asm"), + include_str!("asm/hash/sha2/temp_words.asm"), + include_str!("asm/hash/sha2/write_length.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), include_str!("asm/memory/memcpy.asm"), @@ -65,25 +87,11 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), include_str!("asm/mpt/util.asm"), - include_str!("asm/ripemd/box.asm"), - include_str!("asm/ripemd/compression.asm"), - include_str!("asm/ripemd/constants.asm"), - include_str!("asm/ripemd/functions.asm"), - include_str!("asm/ripemd/main.asm"), - include_str!("asm/ripemd/memory.asm"), - include_str!("asm/ripemd/update.asm"), include_str!("asm/rlp/decode.asm"), include_str!("asm/rlp/encode.asm"), include_str!("asm/rlp/encode_rlp_string.asm"), include_str!("asm/rlp/num_bytes.asm"), include_str!("asm/rlp/read_to_memory.asm"), - include_str!("asm/sha2/compression.asm"), - include_str!("asm/sha2/constants.asm"), - include_str!("asm/sha2/message_schedule.asm"), - include_str!("asm/sha2/ops.asm"), - include_str!("asm/sha2/store_pad.asm"), - include_str!("asm/sha2/temp_words.asm"), - include_str!("asm/sha2/write_length.asm"), include_str!("asm/shift.asm"), include_str!("asm/transactions/router.asm"), include_str!("asm/transactions/type_0.asm"), diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm b/evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm new file mode 100644 index 00000000..9d65b9ed --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/addresses.asm @@ -0,0 +1,43 @@ +// Load the initial hash value (the IV, but with params XOR'd into the first word). +%macro blake2b_initial_hash_value + %blake2b_iv_i(7) + %blake2b_iv_i(6) + %blake2b_iv_i(5) + %blake2b_iv_i(4) + %blake2b_iv_i(3) + %blake2b_iv_i(2) + %blake2b_iv_i(1) + // stack: IV_1, IV_2, IV_3, IV_4, IV_5, IV_6, IV_7 + PUSH 0x01010040 // params: key = 00, digest_size = 64 = 0x40 + %blake2b_iv_i(0) + XOR + // stack: IV_0 ^ params, IV_1, IV_2, IV_3, IV_4, IV_5, IV_6, IV_7 +%endmacro + +// Address where the working version of the hash value is stored. +%macro blake2b_hash_value_addr + PUSH 0 + // stack: 0 + %mload_kernel_general + // stack: num_blocks + %block_size + %add_const(2) + // stack: num_bytes+2 +%endmacro + +// Address where the working version of the compression internal state is stored. +%macro blake2b_internal_state_addr + %blake2b_hash_value_addr + %add_const(8) +%endmacro + +// Address where the current message block is stored. +%macro blake2b_message_addr + %blake2b_internal_state_addr + %add_const(16) +%endmacro + +// Block size is 128 bytes. +%macro block_size + %mul_const(128) +%endmacro \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm b/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm new file mode 100644 index 00000000..a25158d9 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/compression.asm @@ -0,0 +1,280 @@ +global blake2b_compression: + // stack: retdest + PUSH 0 + // stack: cur_block = 0, retdest + %blake2b_initial_hash_value +compression_loop: + // stack: h_0, ..., h_7, cur_block, retdest + + // Store the hash values. + %blake2b_hash_value_addr + // stack: addr, h_0, ..., h_7, cur_block, retdest + %rep 8 + SWAP1 + DUP2 + %mstore_kernel_general + %increment + %endrep + + // stack: addr, cur_block, retdest + POP + // stack: cur_block, retdest + PUSH 0 + %mload_kernel_general + // stack: num_blocks, cur_block, retdest + %decrement + // stack: num_blocks - 1, cur_block, retdest + DUP2 + // stack: cur_block, num_blocks - 1, cur_block, retdest + EQ + // stack: is_last_block, cur_block, retdest + SWAP1 + // stack: cur_block, is_last_block, retdest + PUSH 1 + %mload_kernel_general + // stack: num_bytes, cur_block, is_last_block, retdest + + // Calculate t counter value. + DUP3 + // stack: is_last_block, num_bytes, cur_block, is_last_block, retdest + MUL + // stack: is_last_block * num_bytes, cur_block, is_last_block, retdest + DUP2 + // stack: cur_block, is_last_block * num_bytes, cur_block, is_last_block, retdest + %increment + %block_size + // stack: (cur_block + 1) * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest + DUP4 + // stack: is_last_block, (cur_block + 1) * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest + ISZERO + // stack: not_last_block, (cur_block + 1) * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest + MUL + // stack: not_last_block * ((cur_block + 1) * 128), is_last_block * num_bytes, cur_block, is_last_block, retdest + ADD + // stack: t = not_last_block * ((cur_block + 1) * 128) + is_last_block * num_bytes, cur_block, is_last_block, retdest + SWAP1 + // stack: cur_block, t, is_last_block, retdest + DUP1 + // stack: cur_block, cur_block, t, is_last_block, retdest + %block_size + %add_const(2) + // 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 + // stack: message_addr, cur_block_start_byte, t, cur_block, is_last_block, retdest + %rep 16 + // stack: cur_message_addr, cur_block_byte, ... + DUP2 + // stack: cur_block_byte, cur_message_addr, cur_block_byte, ... + %mload_kernel_general_u64_LE + // stack: m_i, cur_message_addr, cur_block_byte, ... + DUP2 + // stack: cur_message_addr, m_i, cur_message_addr, cur_block_byte, ... + %mstore_kernel_general + // stack: cur_message_addr, cur_block_byte, ... + %increment + // stack: cur_message_addr + 1, cur_block_byte, ... + SWAP1 + // stack: cur_block_byte, cur_message_addr + 1, ... + %add_const(8) + // stack: cur_block_byte + 8, cur_message_addr + 1, ... + SWAP1 + // stack: cur_message_addr + 1, cur_block_byte + 8, ... + %endrep + // stack: end_message_addr, end_block_start_byte, t, cur_block, is_last_block, retdest + POP + POP + // stack: t, cur_block, is_last_block, retdest + SWAP1 + // stack: cur_block, t, is_last_block, retdest + SWAP2 + // stack: is_last_block, t, cur_block, retdest + %mul_const(0xFFFFFFFFFFFFFFFF) + // stack: invert_if_last_block, t, cur_block, 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, invert_if_last_block, t, cur_block, retdest + POP + // 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 + // 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. + %rep 8 + SWAP1 + DUP2 + %mstore_kernel_general + %increment + %endrep + // stack: start + 8, invert_if_last_block, t, cur_block, retdest + + // Next four values of the internal state: first four IV values. + PUSH 0 + // stack: 0, start + 8, invert_if_last_block, t, cur_block, retdest + %rep 4 + // stack: i, loc, ... + DUP2 + DUP2 + // stack: i, loc, i, loc,... + %blake2b_iv + // stack: IV_i, loc, i, loc,... + SWAP1 + // 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, invert_if_last_block, t, cur_block, retdest + %stack (i, loc, inv, last, t) -> (t, t, i, loc, inv, last) + // stack: t, t, 4, start + 12, invert_if_last_block, cur_block, retdest + %shr_const(64) + // stack: t >> 64, t, 4, start + 12, invert_if_last_block, cur_block, retdest + SWAP1 + // stack: t, t >> 64, 4, start + 12, invert_if_last_block, cur_block, retdest + PUSH 1 + %shl_const(64) + // stack: 1 << 64, t, t >> 64, 4, start + 12, invert_if_last_block, cur_block, retdest + SWAP1 + MOD + // stack: t_lo = t % (1 << 64), t_hi = t >> 64, 4, start + 12, invert_if_last_block, cur_block, retdest + %stack (t_lo, t_hi, i, loc, inv) -> (i, loc, t_lo, t_hi, inv, 0) + // stack: 4, start + 12, t_lo, t_hi, invert_if_last_block, 0, cur_block, retdest + + // Last four values of the internal state: last four IV values, XOR'd with + // the values (t % 2**64, t >> 64, invert_if, 0). + %rep 4 + // stack: i, loc, val, next_val,... + %stack (i, loc, val) -> (i, val, loc, i, loc) + // stack: i, val, loc, i, loc, next_val,... + %blake2b_iv + // stack: IV_i, val, loc, i, loc, next_val,... + XOR + // stack: val ^ IV_i, loc, i, loc, next_val,... + SWAP1 + // stack: loc, val ^ IV_i, i, loc, next_val,... + %mstore_kernel_general + // stack: i, loc, next_val,... + %increment + SWAP1 + %increment + SWAP1 + // stack: i + 1, loc + 1, next_val,... + %endrep + // stack: 8, loc + 16, cur_block, retdest + POP + POP + // stack: cur_block, retdest + %blake2b_internal_state_addr + // stack: start, cur_block, retdest + PUSH 0 + // stack: round=0, start, cur_block, retdest + + // Run 12 rounds of G functions. + %rep 12 + // stack: round, start, cur_block, 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) + // stack: round, start, cur_block, retdest + %increment + // stack: round + 1, start, cur_block, retdest + %endrep + // stack: 12, start, cur_block, retdest + POP + POP + + // Finalize hash value. + // stack: cur_block, retdest + %blake2b_generate_new_hash_value(7) + %blake2b_generate_new_hash_value(6) + %blake2b_generate_new_hash_value(5) + %blake2b_generate_new_hash_value(4) + %blake2b_generate_new_hash_value(3) + %blake2b_generate_new_hash_value(2) + %blake2b_generate_new_hash_value(1) + %blake2b_generate_new_hash_value(0) + // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block, retdest + DUP9 + // stack: cur_block, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block, retdest + %increment + // stack: cur_block + 1, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block, retdest + SWAP9 + // stack: cur_block, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + %increment + // stack: cur_block + 1, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + PUSH 0 + %mload_kernel_general + // stack: num_blocks, cur_block + 1, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + EQ + // stack: last_block, h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + %jumpi(compression_end) + %jump(compression_loop) +compression_end: + // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + + // Invert the bytes of each hash value. + %reverse_bytes_u64 + // stack: h_0'', h_1', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + SWAP1 + // stack: h_1', h_0'', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_1'', h_0'', h_2', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + SWAP2 + // stack: h_2', h_0'', h_1'', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_2'', h_0'', h_1'', h_3', h_4', h_5', h_6', h_7', cur_block + 1, retdest + SWAP3 + // stack: h_3', h_0'', h_1'', h_2'', h_4', h_5', h_6', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_3'', h_0'', h_1'', h_2'', h_4', h_5', h_6', h_7', cur_block + 1, retdest + SWAP4 + // stack: h_4', h_0'', h_1'', h_2'', h_3'', h_5', h_6', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_4'', h_0'', h_1'', h_2'', h_3'', h_5', h_6', h_7', cur_block + 1, retdest + SWAP5 + // stack: h_5', h_0'', h_1'', h_2'', h_3'', h_4'', h_6', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_5'', h_0'', h_1'', h_2'', h_3'', h_4'', h_6', h_7', cur_block + 1, retdest + SWAP6 + // stack: h_6', h_0'', h_1'', h_2'', h_3'', h_4'', h_5'', h_7', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_6'', h_0'', h_1'', h_2'', h_3'', h_4'', h_5'', h_7', cur_block + 1, retdest + SWAP7 + // stack: h_7', h_0'', h_1'', h_2'', h_3'', h_4'', h_5'', h_6'', cur_block + 1, retdest + %reverse_bytes_u64 + // stack: h_7'', h_0'', h_1'', h_2'', h_3'', h_4'', h_5'', h_6'', cur_block + 1, retdest + %stack (h_7, h_s: 7) -> (h_s, h_7) + // stack: h_0'', h_1'', h_2'', h_3'', h_4'', h_5'', h_6'', h_7'', cur_block + 1, retdest + + // Combine hash values. + %u64s_to_u256 + // stack: h_0'' || h_1'' || h_2'' || h_3'', h_4'', h_5'', h_6'', h_7'', cur_block + 1, retdest + %stack (first, second: 4, cur) -> (second, first) + // stack: h_4'', h_5'', h_6'', h_7'', h_0'' || h_1'' || h_2'' || h_3'', retdest + %u64s_to_u256 + // stack: hash_second = h_4'' || h_5'' || h_6'' || h_7'', hash_first = h_0'' || h_1'' || h_2'' || h_3'', retdest + %stack (second, first, ret) -> (ret, second, first) + // stack: retdest, hash_first, hash_second + JUMP diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm b/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm new file mode 100644 index 00000000..11e879fc --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/g_functions.asm @@ -0,0 +1,126 @@ +%macro blake2b_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. + // 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: 4, 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 +%endmacro + +%macro call_blake2b_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 + // stack: s[y_idx], round, start + %blake2b_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 + // stack: s[x_idx], m[s[y_idx]], round, start + %blake2b_message_addr + ADD + %mload_kernel_general + // stack: m[s[x_idx]], m[s[y_idx]], round, start + %stack (ss: 2, r, s) -> (ss, s, r, s) + // stack: m[s[x_idx]], m[s[y_idx]], start, round, start + PUSH $d + PUSH $c + PUSH $b + PUSH $a + // stack: a, b, c, d, m[s[x_idx]], m[s[y_idx]], start, round, start + %blake2b_g_function + // stack: round, start +%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm b/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm new file mode 100644 index 00000000..712a97c0 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/hash.asm @@ -0,0 +1,18 @@ +%macro blake2b_generate_new_hash_value(i) + %blake2b_hash_value_addr + %add_const($i) + %mload_kernel_general + // stack: h_i, ... + %blake2b_internal_state_addr + %add_const($i) + %mload_kernel_general + // stack: v_i, h_i, ... + %blake2b_internal_state_addr + %add_const($i) + %add_const(8) + %mload_kernel_general + // stack: v_(i+8), v_i, h_i, ... + XOR + XOR + // stack: h_i' = v_(i+8) ^ v_i ^ h_i, ... +%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/iv.asm b/evm/src/cpu/kernel/asm/hash/blake2b/iv.asm new file mode 100644 index 00000000..174afd33 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/iv.asm @@ -0,0 +1,62 @@ +global blake2b_iv_const: + // IV constants (big-endian) + + // IV_0 + BYTES 106, 9, 230, 103 + BYTES 243, 188, 201, 8 + + // IV_1 + BYTES 187, 103, 174, 133 + BYTES 132, 202, 167, 59 + + // IV_2 + BYTES 60, 110, 243, 114 + BYTES 254, 148, 248, 43 + + // IV_3 + BYTES 165, 79, 245, 58 + BYTES 95, 29, 54, 241 + + // IV_4 + BYTES 81, 14, 82, 127 + BYTES 173, 230, 130, 209 + + // IV_5 + BYTES 155, 5, 104, 140 + BYTES 43, 62, 108, 31 + + // IV_6 + BYTES 31, 131, 217, 171 + BYTES 251, 65, 189, 107 + + // IV_7 + BYTES 91, 224, 205, 25 + BYTES 19, 126, 33, 121 + +%macro blake2b_iv + // stack: i, ... + PUSH blake2b_iv_const + // stack: blake2b_iv_const, i, ... + SWAP1 + // stack: i, blake2b_iv_const, ... + %mul_const(8) + ADD + // stack: blake2b_iv_const + 2 * i, ... + DUP1 + // stack: blake2b_iv_const + 2 * i, blake2b_iv_const + 2 * i, ... + %add_const(4) + // stack: blake2b_iv_const + 2 * i + 1, blake2b_iv_const + 2 * i, ... + %mload_kernel_code_u32 + SWAP1 + %mload_kernel_code_u32 + // stack: IV_i[32:], IV_i[:32], ... + %shl_const(32) + // stack: IV_i[32:] << 32, IV_i[:32], ... + OR + // stack: IV_i, ... +%endmacro + +%macro blake2b_iv_i(i) + PUSH $i + %blake2b_iv +%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/ops.asm b/evm/src/cpu/kernel/asm/hash/blake2b/ops.asm new file mode 100644 index 00000000..2b40db7f --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/ops.asm @@ -0,0 +1,21 @@ +// 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 diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm b/evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm new file mode 100644 index 00000000..5277e611 --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/permutations.asm @@ -0,0 +1,74 @@ +global permutation_0_constants: + BYTES 0, 1, 2, 3 + BYTES 4, 5, 6, 7 + BYTES 8, 9, 10, 11 + BYTES 12, 13, 14, 15 + +global permutation_1_constants: + BYTES 14, 10, 4, 8 + BYTES 9, 15, 13, 6 + BYTES 1, 12, 0, 2 + BYTES 11, 7, 5, 3 + +global permutation_2_constants: + BYTES 11, 8, 12, 0 + BYTES 5, 2, 15, 13 + BYTES 10, 14, 3, 6 + BYTES 7, 1, 9, 4 + +global permutation_3_constants: + BYTES 7, 9, 3, 1 + BYTES 13, 12, 11, 14 + BYTES 2, 6, 5, 10 + BYTES 4, 0, 15, 8 + +global permutation_4_constants: + BYTES 9, 0, 5, 7 + BYTES 2, 4, 10, 15 + BYTES 14, 1, 11, 12 + BYTES 6, 8, 3, 13 + +global permutation_5_constants: + BYTES 2, 12, 6, 10 + BYTES 0, 11, 8, 3 + BYTES 4, 13, 7, 5 + BYTES 15, 14, 1, 9 + +global permutation_6_constants: + BYTES 12, 5, 1, 15 + BYTES 14, 13, 4, 10 + BYTES 0, 7, 6, 3 + BYTES 9, 2, 8, 11 + +global permutation_7_constants: + BYTES 13, 11, 7, 14 + BYTES 12, 1, 3, 9 + BYTES 5, 0, 15, 4 + BYTES 8, 6, 2, 10 + +global permutation_8_constants: + BYTES 6, 15, 14, 9 + BYTES 11, 3, 0, 8 + BYTES 12, 2, 13, 7 + BYTES 1, 4, 10, 5 + +global permutation_9_constants: + BYTES 10, 2, 8, 4 + BYTES 7, 6, 1, 5 + BYTES 15, 11, 9, 14 + BYTES 3, 12, 13, 0 + +%macro blake2b_permutation + // stack: round, i + PUSH permutation_0_constants + // stack: permutation_0_constants, round, i + SWAP1 + // stack: round, permutation_1_constants, i + %mod_const(10) + // stack: round % 10, permutation_1_constants, i + %mul_const(16) + ADD + // stack: permutation_(round)_constants, i + ADD + %mload_kernel_code +%endmacro diff --git a/evm/src/cpu/kernel/asm/hash/blake2b/store.asm b/evm/src/cpu/kernel/asm/hash/blake2b/store.asm new file mode 100644 index 00000000..0b2a9a7a --- /dev/null +++ b/evm/src/cpu/kernel/asm/hash/blake2b/store.asm @@ -0,0 +1,45 @@ +global blake2b: + %jump(blake2b_store) + +global blake2b_store: + // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + DUP1 + // stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + %add_const(127) + %div_const(128) + // stack: num_blocks = ceil(num_bytes / 128), num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + PUSH 0 + // stack: addr=0, num_blocks, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + %mstore_kernel_general + // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + DUP1 + // stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + PUSH 1 + // stack: 1, num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + %mstore_kernel_general + // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest + PUSH 2 + // stack: addr=2, counter=num_bytes, x[0], x[1], x[2], ... , x[num_bytes-1], retdest +store_loop: + // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest + DUP2 + // stack: counter, addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest + ISZERO + %jumpi(store_end) + // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest + %stack (addr, counter, val) -> (addr, val, counter, addr) + // stack: addr, x[num_bytes-counter], counter, addr, ... , x[num_bytes-1], retdest + %mstore_kernel_general + // stack: counter, addr, ... , x[num_bytes-1], retdest + %decrement + // stack: counter-1, addr, ... , x[num_bytes-1], retdest + SWAP1 + // stack: addr, counter-1, ... , x[num_bytes-1], retdest + %increment + // stack: addr+1, counter-1, ... , x[num_bytes-1], retdest + %jump(store_loop) +store_end: + // stack: addr, counter, retdest + %pop2 + // stack: retdest + %jump(blake2b_compression) diff --git a/evm/src/cpu/kernel/asm/ripemd/box.asm b/evm/src/cpu/kernel/asm/hash/ripemd/box.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/box.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/box.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/compression.asm b/evm/src/cpu/kernel/asm/hash/ripemd/compression.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/compression.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/compression.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/constants.asm b/evm/src/cpu/kernel/asm/hash/ripemd/constants.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/constants.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/constants.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/functions.asm b/evm/src/cpu/kernel/asm/hash/ripemd/functions.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/functions.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/functions.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/main.asm b/evm/src/cpu/kernel/asm/hash/ripemd/main.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/main.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/main.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/memory.asm b/evm/src/cpu/kernel/asm/hash/ripemd/memory.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/memory.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/memory.asm diff --git a/evm/src/cpu/kernel/asm/ripemd/update.asm b/evm/src/cpu/kernel/asm/hash/ripemd/update.asm similarity index 100% rename from evm/src/cpu/kernel/asm/ripemd/update.asm rename to evm/src/cpu/kernel/asm/hash/ripemd/update.asm diff --git a/evm/src/cpu/kernel/asm/sha2/compression.asm b/evm/src/cpu/kernel/asm/hash/sha2/compression.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/compression.asm rename to evm/src/cpu/kernel/asm/hash/sha2/compression.asm diff --git a/evm/src/cpu/kernel/asm/sha2/constants.asm b/evm/src/cpu/kernel/asm/hash/sha2/constants.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/constants.asm rename to evm/src/cpu/kernel/asm/hash/sha2/constants.asm diff --git a/evm/src/cpu/kernel/asm/sha2/message_schedule.asm b/evm/src/cpu/kernel/asm/hash/sha2/message_schedule.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/message_schedule.asm rename to evm/src/cpu/kernel/asm/hash/sha2/message_schedule.asm diff --git a/evm/src/cpu/kernel/asm/sha2/ops.asm b/evm/src/cpu/kernel/asm/hash/sha2/ops.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/ops.asm rename to evm/src/cpu/kernel/asm/hash/sha2/ops.asm diff --git a/evm/src/cpu/kernel/asm/sha2/store_pad.asm b/evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/store_pad.asm rename to evm/src/cpu/kernel/asm/hash/sha2/store_pad.asm diff --git a/evm/src/cpu/kernel/asm/sha2/temp_words.asm b/evm/src/cpu/kernel/asm/hash/sha2/temp_words.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/temp_words.asm rename to evm/src/cpu/kernel/asm/hash/sha2/temp_words.asm diff --git a/evm/src/cpu/kernel/asm/sha2/write_length.asm b/evm/src/cpu/kernel/asm/hash/sha2/write_length.asm similarity index 100% rename from evm/src/cpu/kernel/asm/sha2/write_length.asm rename to evm/src/cpu/kernel/asm/hash/sha2/write_length.asm diff --git a/evm/src/cpu/kernel/asm/memory/core.asm b/evm/src/cpu/kernel/asm/memory/core.asm index f6bb99b6..a979f930 100644 --- a/evm/src/cpu/kernel/asm/memory/core.asm +++ b/evm/src/cpu/kernel/asm/memory/core.asm @@ -97,7 +97,7 @@ // stack: (((((c_3 << 8) | c_2) << 8) | c_1) << 8) | c_0 %endmacro -// Load from the kernel a little-endian u32, consisting of 4 bytes (c_0, c_1, c_2, c_3) +// Load from the kernel a little-endian u32, consisting of 4 bytes (c_0, c_1, c_2, c_3). %macro mload_kernel_u32_LE(segment) // stack: offset DUP1 @@ -123,6 +123,24 @@ // stack: c0 | (c1 << 8) | (c2 << 16) | (c3 << 24) %endmacro +// Load from the kernel a little-endian u64, consisting of 8 bytes +// (c_0, c_1, c_2, c_3, c_4, c_5, c_6, c_7). +%macro mload_kernel_u64_LE(segment) + // stack: offset + DUP1 + %mload_kernel_u32_LE($segment) + // stack: lo, offset + SWAP1 + // stack: offset, lo + %add_const(4) + %mload_kernel_u32_LE($segment) + // stack: hi, lo + %shl_const(32) + // stack: hi << 32, lo + OR + // stack: (hi << 32) | lo +%endmacro + // Load a u256 (big-endian) from the kernel. %macro mload_kernel_u256(segment) // stack: offset @@ -292,7 +310,7 @@ // stack: value %endmacro -// Load a little-endian u32, consisting of 4 bytes (c_3, c_2, c_1, c_0), +// Load a little-endian u32, consisting of 4 bytes (c_0, c_1, c_2, c_3), // from kernel general memory. %macro mload_kernel_general_u32_LE // stack: offset @@ -300,6 +318,14 @@ // stack: value %endmacro +// Load a little-endian u64, consisting of 8 bytes +// (c_0, c_1, c_2, c_3, c_4, c_5, c_6, c_7), from kernel general memory. +%macro mload_kernel_general_u64_LE + // stack: offset + %mload_kernel_u64_LE(@SEGMENT_KERNEL_GENERAL) + // stack: value +%endmacro + // Load a u256 (big-endian) from kernel code. %macro mload_kernel_code_u256 // stack: offset diff --git a/evm/src/cpu/kernel/asm/util/basic_macros.asm b/evm/src/cpu/kernel/asm/util/basic_macros.asm index 5b9358e3..cde86df8 100644 --- a/evm/src/cpu/kernel/asm/util/basic_macros.asm +++ b/evm/src/cpu/kernel/asm/util/basic_macros.asm @@ -240,6 +240,10 @@ %and_const(0xffffffff) %endmacro +%macro as_u64 + %and_const(0xffffffffffffffff) +%endmacro + %macro not_u32 // stack: x PUSH 0xffffffff @@ -311,6 +315,33 @@ // stack: dcba %endmacro -01 00 00 00 01 00 00 00 01 00 -ff 00 00 ff 00 ff 00 00 00 00 ff 00 00 -ff ff ff ff ff ff \ No newline at end of file +%macro reverse_bytes_u64 + // stack: word + DUP1 + // stack: word, word + %and_const(0xffffffff) + // stack: word_lo, word + SWAP1 + // stack: word, word_lo + %shr_const(32) + // stack: word_hi, word_lo + %reverse_bytes_u32 + // stack: word_hi_inverted, word_lo + SWAP1 + // stack: word_lo, word_hi_inverted + %reverse_bytes_u32 + // stack: word_lo_inverted, word_hi_inverted + %shl_const(32) + OR + // stack: word_inverted +%endmacro + +// Combine four big-endian u64s into a u256. +%macro u64s_to_u256 + // stack: a, b, c, d + %rep 3 + %shl_const(64) + OR + %endrep + // stack: a || b || c || d +%endmacro diff --git a/evm/src/cpu/kernel/constants/mod.rs b/evm/src/cpu/kernel/constants/mod.rs index e762a643..c9094338 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 { + + let hex_constants = EC_CONSTANTS.iter().chain(HASH_CONSTANTS.iter()).cloned(); + for (name, value) in hex_constants { c.insert(name.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()); } diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 2d62e2d8..40259d4e 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -163,17 +163,25 @@ impl<'a> Interpreter<'a> { &mut self.generation_state.memory.contexts[0].segments[Segment::TrieData as usize].content } - pub(crate) fn get_rlp_memory(&self) -> Vec { - self.generation_state.memory.contexts[0].segments[Segment::RlpRaw as usize] + pub(crate) fn get_memory_segment_bytes(&self, segment: Segment) -> Vec { + self.generation_state.memory.contexts[0].segments[segment as usize] .content .iter() .map(|x| x.as_u32() as u8) .collect() } + pub(crate) fn get_rlp_memory(&self) -> Vec { + self.get_memory_segment_bytes(Segment::RlpRaw) + } + + pub(crate) fn set_memory_segment_bytes(&mut self, segment: Segment, memory: Vec) { + self.generation_state.memory.contexts[0].segments[segment as usize].content = + memory.into_iter().map(U256::from).collect(); + } + pub(crate) fn set_rlp_memory(&mut self, rlp: Vec) { - self.generation_state.memory.contexts[0].segments[Segment::RlpRaw as usize].content = - rlp.into_iter().map(U256::from).collect(); + self.set_memory_segment_bytes(Segment::RlpRaw, rlp) } pub(crate) fn set_code(&mut self, context: usize, code: Vec) { diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index b7b2e5c2..b24317e0 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -1,7 +1,8 @@ use std::str::FromStr; use anyhow::Result; -use ethereum_types::U256; +use blake2::Blake2b512; +use ethereum_types::{U256, U512}; use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; use sha2::Sha256; @@ -23,6 +24,13 @@ fn ripemd(input: Vec) -> U256 { U256::from(&hasher.finalize()[..]) } +/// Standard Blake2b implementation. +fn blake2b(input: Vec) -> U512 { + let mut hasher = Blake2b512::new(); + hasher.update(input); + U512::from(&hasher.finalize()[..]) +} + fn make_random_input() -> Vec { // Generate a random message, between 0 and 9999 bytes. let mut rng = thread_rng(); @@ -48,7 +56,17 @@ fn make_input_stack(message: Vec) -> Vec { initial_stack } -fn test_hash(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec) -> U256) -> Result<()> { +fn combine_u256s(hi: U256, lo: U256) -> U512 { + let mut result = U512::from(hi); + result <<= 256; + result += U512::from(lo); + result +} + +fn prepare_test( + hash_fn_label: &str, + standard_implementation: &dyn Fn(Vec) -> T, +) -> Result<(T, T, Vec, Vec)> { // Make the input. let message_random = make_random_input(); let message_custom = make_custom_input(); @@ -68,9 +86,42 @@ fn test_hash(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec) -> U 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( + hash_fn_label: &str, + standard_implementation: &dyn Fn(Vec) -> U256, +) -> Result<()> { + let (expected_random, expected_custom, random_stack, custom_stack) = + prepare_test(hash_fn_label, standard_implementation).unwrap(); + // Extract the final output. - let actual_random = result_random.stack()[0]; - let actual_custom = result_custom.stack()[0]; + let actual_random = random_stack[0]; + let actual_custom = custom_stack[0]; + + // Check that the result is correct. + assert_eq!(expected_random, actual_random); + assert_eq!(expected_custom, actual_custom); + + Ok(()) +} + +fn test_hash_512( + hash_fn_label: &str, + standard_implementation: &dyn Fn(Vec) -> U512, +) -> Result<()> { + let (expected_random, expected_custom, random_stack, custom_stack) = + prepare_test(hash_fn_label, standard_implementation).unwrap(); + + // Extract the final output. + let actual_random = combine_u256s(random_stack[0], random_stack[1]); + let actual_custom = combine_u256s(custom_stack[0], custom_stack[1]); // Check that the result is correct. assert_eq!(expected_random, actual_random); @@ -81,10 +132,15 @@ fn test_hash(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec) -> U #[test] fn test_sha2() -> Result<()> { - test_hash("sha2", &sha2) + test_hash_256("sha2", &sha2) } #[test] fn test_ripemd() -> Result<()> { - test_hash("ripemd_stack", &ripemd) + test_hash_256("ripemd_stack", &ripemd) +} + +#[test] +fn test_blake2b() -> Result<()> { + test_hash_512("blake2b", &blake2b) } diff --git a/system_zero/Cargo.toml b/system_zero/Cargo.toml index 58a5e489..03aaea20 100644 --- a/system_zero/Cargo.toml +++ b/system_zero/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] anyhow = "1.0.40" -env_logger = "0.9.0" itertools = "0.10.0" log = "0.4.14" plonky2 = { path = "../plonky2" } @@ -17,6 +16,7 @@ starky = { path = "../starky" } [dev-dependencies] criterion = "0.4.0" +env_logger = "0.10.0" [[bench]] name = "lookup_permuted_cols" diff --git a/util/Cargo.toml b/util/Cargo.toml index 4e0b4b15..4419db2a 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -4,5 +4,5 @@ description = "Utilities used by Plonky2" version = "0.1.0" edition = "2021" -[dependencies] +[dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["getrandom"] }