mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-02 22:03:07 +00:00
Merge pull request #956 from mir-protocol/doubly_encode_storage_values
Doubly RLP-encode storage values
This commit is contained in:
commit
9690b60b80
@ -109,6 +109,7 @@ pub(crate) fn combined_kernel() -> Kernel {
|
||||
include_str!("asm/mpt/util.asm"),
|
||||
include_str!("asm/rlp/decode.asm"),
|
||||
include_str!("asm/rlp/encode.asm"),
|
||||
include_str!("asm/rlp/encode_rlp_scalar.asm"),
|
||||
include_str!("asm/rlp/encode_rlp_string.asm"),
|
||||
include_str!("asm/rlp/num_bytes.asm"),
|
||||
include_str!("asm/rlp/read_to_memory.asm"),
|
||||
|
||||
@ -19,7 +19,7 @@ global mpt_hash_storage_trie:
|
||||
%jump(mpt_hash)
|
||||
|
||||
%macro mpt_hash_storage_trie
|
||||
PUSH %%after
|
||||
%stack (node_ptr) -> (node_ptr, %%after)
|
||||
%jump(mpt_hash_storage_trie)
|
||||
%%after:
|
||||
%endmacro
|
||||
@ -83,12 +83,9 @@ global encode_account:
|
||||
// stack: balance, rlp_pos_4, value_ptr, retdest
|
||||
SWAP1 %encode_rlp_scalar
|
||||
// stack: rlp_pos_5, value_ptr, retdest
|
||||
PUSH encode_account_after_hash_storage_trie
|
||||
PUSH encode_storage_value
|
||||
DUP4 %add_const(2) %mload_trie_data // storage_root_ptr = value[2]
|
||||
// stack: storage_root_ptr, encode_storage_value, encode_account_after_hash_storage_trie, rlp_pos_5, value_ptr, retdest
|
||||
%jump(mpt_hash)
|
||||
encode_account_after_hash_storage_trie:
|
||||
DUP2 %add_const(2) %mload_trie_data // storage_root_ptr = value[2]
|
||||
// stack: storage_root_ptr, rlp_pos_5, value_ptr, retdest
|
||||
%mpt_hash_storage_trie
|
||||
// stack: storage_root_digest, rlp_pos_5, value_ptr, retdest
|
||||
SWAP1 %encode_rlp_256
|
||||
// stack: rlp_pos_6, value_ptr, retdest
|
||||
@ -113,7 +110,7 @@ global encode_storage_value:
|
||||
// which seems to imply that this should be %encode_rlp_256. But %encode_rlp_scalar
|
||||
// causes the tests to pass, so it seems storage values should be treated as variable-
|
||||
// length after all.
|
||||
%encode_rlp_scalar
|
||||
%doubly_encode_rlp_scalar
|
||||
// stack: rlp_pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
@ -1,55 +1,3 @@
|
||||
// RLP-encode a scalar, i.e. a variable-length integer.
|
||||
// Pre stack: pos, scalar, retdest
|
||||
// Post stack: pos
|
||||
global encode_rlp_scalar:
|
||||
// stack: pos, scalar, retdest
|
||||
// If scalar > 0x7f, this is the "medium" case.
|
||||
DUP2
|
||||
%gt_const(0x7f)
|
||||
%jumpi(encode_rlp_scalar_medium)
|
||||
|
||||
// Else, if scalar != 0, this is the "small" case, where the value is its own encoding.
|
||||
DUP2 %jumpi(encode_rlp_scalar_small)
|
||||
|
||||
// scalar = 0, so BE(scalar) is the empty string, which RLP encodes as a single byte 0x80.
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, 0x80, pos)
|
||||
%mstore_rlp
|
||||
// stack: pos, retdest
|
||||
%increment
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
encode_rlp_scalar_small:
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, scalar, pos)
|
||||
// stack: pos, scalar, pos, retdest
|
||||
%mstore_rlp
|
||||
// stack: pos, retdest
|
||||
%increment
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
encode_rlp_scalar_medium:
|
||||
// This is the "medium" case, where we write 0x80 + len followed by the
|
||||
// (big-endian) scalar bytes. We first compute the minimal number of bytes
|
||||
// needed to represent this scalar, then treat it as if it was a fixed-
|
||||
// length string with that length.
|
||||
// stack: pos, scalar, retdest
|
||||
DUP2
|
||||
%num_bytes
|
||||
// stack: scalar_bytes, pos, scalar, retdest
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Convenience macro to call encode_rlp_scalar and return where we left off.
|
||||
%macro encode_rlp_scalar
|
||||
%stack (pos, scalar) -> (pos, scalar, %%after)
|
||||
%jump(encode_rlp_scalar)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length 160 bit (20 byte) string. Assumes string < 2^160.
|
||||
// Pre stack: pos, string, retdest
|
||||
// Post stack: pos
|
||||
@ -79,7 +27,7 @@ global encode_rlp_256:
|
||||
%endmacro
|
||||
|
||||
// RLP-encode a fixed-length string with the given byte length. Assumes string < 2^(8 * len).
|
||||
encode_rlp_fixed:
|
||||
global encode_rlp_fixed:
|
||||
// stack: len, pos, string, retdest
|
||||
DUP1
|
||||
%add_const(0x80)
|
||||
@ -99,6 +47,31 @@ encode_rlp_fixed_finish:
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
// Doubly-RLP-encode a fixed-length string with the given byte length.
|
||||
// I.e. writes encode(encode(string). Assumes string < 2^(8 * len).
|
||||
global doubly_encode_rlp_fixed:
|
||||
// stack: len, pos, string, retdest
|
||||
DUP1
|
||||
%add_const(0x81)
|
||||
// stack: first_byte, len, pos, string, retdest
|
||||
DUP3
|
||||
// stack: pos, first_byte, len, pos, string, retdest
|
||||
%mstore_rlp
|
||||
// stack: len, pos, string, retdest
|
||||
DUP1
|
||||
%add_const(0x80)
|
||||
// stack: second_byte, len, original_pos, string, retdest
|
||||
DUP3 %increment
|
||||
// stack: pos', second_byte, len, pos, string, retdest
|
||||
%mstore_rlp
|
||||
// stack: len, pos, string, retdest
|
||||
SWAP1
|
||||
%add_const(2) // advance past the two prefix bytes
|
||||
// stack: pos'', len, string, retdest
|
||||
%stack (pos, len, string) -> (pos, string, len, encode_rlp_fixed_finish)
|
||||
// stack: context, segment, pos'', string, len, encode_rlp_fixed_finish, retdest
|
||||
%jump(mstore_unpacking_rlp)
|
||||
|
||||
// Writes the RLP prefix for a string of the given length. This does not handle
|
||||
// the trivial encoding of certain single-byte strings, as handling that would
|
||||
// require access to the actual string, while this method only accesses its
|
||||
|
||||
99
evm/src/cpu/kernel/asm/rlp/encode_rlp_scalar.asm
Normal file
99
evm/src/cpu/kernel/asm/rlp/encode_rlp_scalar.asm
Normal file
@ -0,0 +1,99 @@
|
||||
// RLP-encode a scalar, i.e. a variable-length integer.
|
||||
// Pre stack: pos, scalar, retdest
|
||||
// Post stack: pos
|
||||
global encode_rlp_scalar:
|
||||
// stack: pos, scalar, retdest
|
||||
// If scalar > 0x7f, this is the "medium" case.
|
||||
DUP2
|
||||
%gt_const(0x7f)
|
||||
%jumpi(encode_rlp_scalar_medium)
|
||||
|
||||
// Else, if scalar != 0, this is the "small" case, where the value is its own encoding.
|
||||
DUP2 %jumpi(encode_rlp_scalar_small)
|
||||
|
||||
// scalar = 0, so BE(scalar) is the empty string, which RLP encodes as a single byte 0x80.
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, 0x80, pos)
|
||||
%mstore_rlp
|
||||
// stack: pos, retdest
|
||||
%increment
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
encode_rlp_scalar_medium:
|
||||
// This is the "medium" case, where we write 0x80 + len followed by the
|
||||
// (big-endian) scalar bytes. We first compute the minimal number of bytes
|
||||
// needed to represent this scalar, then treat it as if it was a fixed-
|
||||
// length string with that length.
|
||||
// stack: pos, scalar, retdest
|
||||
DUP2
|
||||
%num_bytes
|
||||
// stack: scalar_bytes, pos, scalar, retdest
|
||||
%jump(encode_rlp_fixed)
|
||||
|
||||
// Doubly-RLP-encode a scalar, i.e. return encode(encode(scalar)).
|
||||
// Pre stack: pos, scalar, retdest
|
||||
// Post stack: pos
|
||||
global doubly_encode_rlp_scalar:
|
||||
// stack: pos, scalar, retdest
|
||||
// If scalar > 0x7f, this is the "medium" case.
|
||||
DUP2
|
||||
%gt_const(0x7f)
|
||||
%jumpi(doubly_encode_rlp_scalar_medium)
|
||||
|
||||
// Else, if scalar != 0, this is the "small" case, where the value is its own encoding.
|
||||
DUP2 %jumpi(encode_rlp_scalar_small)
|
||||
|
||||
// scalar = 0, so BE(scalar) is the empty string, encode(scalar) = 0x80, and encode(encode(scalar)) = 0x8180.
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, 0x81, pos, 0x80, pos)
|
||||
%mstore_rlp
|
||||
// stack: pos, 0x80, pos, retdest
|
||||
%increment
|
||||
%mstore_rlp
|
||||
// stack: pos, retdest
|
||||
%increment
|
||||
// stack: pos, retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
doubly_encode_rlp_scalar_medium:
|
||||
// This is the "medium" case, where
|
||||
// encode(scalar) = [0x80 + len] || BE(scalar)
|
||||
// and so
|
||||
// encode(encode(scalar)) = [0x80 + len + 1] || [0x80 + len] || BE(scalar)
|
||||
// We first compute the length of the scalar with %num_bytes, then treat the scalar as if it was a
|
||||
// fixed-length string with that length.
|
||||
// stack: pos, scalar, retdest
|
||||
DUP2
|
||||
%num_bytes
|
||||
// stack: scalar_bytes, pos, scalar, retdest
|
||||
%jump(doubly_encode_rlp_fixed)
|
||||
|
||||
// The "small" case of RLP-encoding a scalar, where the value is its own encoding.
|
||||
// This can be used for both for singly encoding or doubly encoding, since encode(encode(x)) = encode(x) = x.
|
||||
encode_rlp_scalar_small:
|
||||
// stack: pos, scalar, retdest
|
||||
%stack (pos, scalar) -> (pos, scalar, pos)
|
||||
// stack: pos, scalar, pos, retdest
|
||||
%mstore_rlp
|
||||
// stack: pos, retdest
|
||||
%increment
|
||||
// stack: pos', retdest
|
||||
SWAP1
|
||||
JUMP
|
||||
|
||||
// Convenience macro to call encode_rlp_scalar and return where we left off.
|
||||
%macro encode_rlp_scalar
|
||||
%stack (pos, scalar) -> (pos, scalar, %%after)
|
||||
%jump(encode_rlp_scalar)
|
||||
%%after:
|
||||
%endmacro
|
||||
|
||||
// Convenience macro to call doubly_encode_rlp_scalar and return where we left off.
|
||||
%macro doubly_encode_rlp_scalar
|
||||
%stack (pos, scalar) -> (pos, scalar, %%after)
|
||||
%jump(doubly_encode_rlp_scalar)
|
||||
%%after:
|
||||
%endmacro
|
||||
Loading…
x
Reference in New Issue
Block a user