1use alloy_primitives::{keccak256, B256, U256};
2
3pub fn storage_key_map(storage_key: &[u8], offset: u64) -> U256 {
8 const BOUNDARY: usize = 31;
9
10 let mut key_bytes = [0u8; 32];
11 key_bytes[24..32].copy_from_slice(&offset.to_be_bytes());
12
13 let mut buf = [0u8; 64];
14 let sk_len = storage_key.len();
15 buf[..sk_len].copy_from_slice(storage_key);
16 buf[sk_len..sk_len + BOUNDARY].copy_from_slice(&key_bytes[..BOUNDARY]);
17 let h = keccak256(&buf[..sk_len + BOUNDARY]);
18
19 let mut mapped = [0u8; 32];
20 mapped[..BOUNDARY].copy_from_slice(&h.0[..BOUNDARY]);
21 mapped[BOUNDARY] = key_bytes[BOUNDARY];
22 U256::from_be_bytes(mapped)
23}
24
25pub fn storage_key_map_b256(storage_key: &[u8], key: &[u8; 32]) -> U256 {
27 const BOUNDARY: usize = 31;
28
29 let mut buf = [0u8; 64];
30 let sk_len = storage_key.len();
31 buf[..sk_len].copy_from_slice(storage_key);
32 buf[sk_len..sk_len + BOUNDARY].copy_from_slice(&key[..BOUNDARY]);
33 let h = keccak256(&buf[..sk_len + BOUNDARY]);
34
35 let mut mapped = [0u8; 32];
36 mapped[..BOUNDARY].copy_from_slice(&h.0[..BOUNDARY]);
37 mapped[BOUNDARY] = key[BOUNDARY];
38 U256::from_be_bytes(mapped)
39}
40
41pub fn derive_sub_key(parent_key: B256, sub_key: &[u8]) -> B256 {
46 let base_slice: &[u8] = if parent_key == B256::ZERO {
47 &[]
48 } else {
49 parent_key.as_slice()
50 };
51 let base_len = base_slice.len();
52 let sub_len = sub_key.len();
53 if base_len + sub_len <= 64 {
54 let mut buf = [0u8; 64];
55 buf[..base_len].copy_from_slice(base_slice);
56 buf[base_len..base_len + sub_len].copy_from_slice(sub_key);
57 keccak256(&buf[..base_len + sub_len])
58 } else {
59 let mut v = Vec::with_capacity(base_len + sub_len);
60 v.extend_from_slice(base_slice);
61 v.extend_from_slice(sub_key);
62 keccak256(&v)
63 }
64}