|
1 | 1 | mod eip152; |
2 | 2 |
|
3 | | -use crate::{address, PurePrecompileSet}; |
| 3 | +use crate::PurePrecompile; |
4 | 4 | use evm::{ExitException, ExitResult, ExitSucceed, RuntimeState, StaticGasometer}; |
5 | | -use primitive_types::H160; |
6 | 5 |
|
7 | 6 | pub struct Blake2F; |
8 | 7 |
|
9 | 8 | impl Blake2F { |
10 | 9 | const GAS_COST_PER_ROUND: u64 = 1; // https://eips.ethereum.org/EIPS/eip-152#gas-costs-and-benchmarks |
11 | 10 | } |
12 | 11 |
|
13 | | -impl<G: StaticGasometer> PurePrecompileSet<G> for Blake2F { |
| 12 | +impl<G: StaticGasometer> PurePrecompile<G> for Blake2F { |
14 | 13 | /// Format of `input`: |
15 | 14 | /// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] |
16 | 15 | fn execute( |
17 | 16 | &self, |
18 | 17 | input: &[u8], |
19 | | - state: &RuntimeState, |
| 18 | + _state: &RuntimeState, |
20 | 19 | gasometer: &mut G, |
21 | | - ) -> Option<(ExitResult, Vec<u8>)> { |
22 | | - const ADDRESS: H160 = address(9); |
23 | | - |
24 | | - if state.context.address == ADDRESS { |
25 | | - const BLAKE2_F_ARG_LEN: usize = 213; |
26 | | - |
27 | | - if input.len() != BLAKE2_F_ARG_LEN { |
28 | | - return Some(( |
29 | | - ExitException::Other( |
30 | | - "input length for Blake2 F precompile should be exactly 213 bytes".into(), |
31 | | - ) |
32 | | - .into(), |
33 | | - Vec::new(), |
34 | | - )); |
35 | | - } |
36 | | - |
37 | | - let mut rounds_buf: [u8; 4] = [0; 4]; |
38 | | - rounds_buf.copy_from_slice(&input[0..4]); |
39 | | - let rounds: u32 = u32::from_be_bytes(rounds_buf); |
40 | | - |
41 | | - let gas_cost: u64 = (rounds as u64) * Blake2F::GAS_COST_PER_ROUND; |
42 | | - try_some!(gasometer.record_cost(gas_cost.into())); |
43 | | - |
44 | | - // we use from_le_bytes below to effectively swap byte order to LE if architecture is BE |
45 | | - let mut h_buf: [u8; 64] = [0; 64]; |
46 | | - h_buf.copy_from_slice(&input[4..68]); |
47 | | - let mut h = [0u64; 8]; |
48 | | - let mut ctr = 0; |
49 | | - for state_word in &mut h { |
50 | | - let mut temp: [u8; 8] = Default::default(); |
51 | | - temp.copy_from_slice(&h_buf[(ctr * 8)..(ctr + 1) * 8]); |
52 | | - *state_word = u64::from_le_bytes(temp); |
53 | | - ctr += 1; |
54 | | - } |
| 20 | + ) -> (ExitResult, Vec<u8>) { |
| 21 | + const BLAKE2_F_ARG_LEN: usize = 213; |
| 22 | + |
| 23 | + if input.len() != BLAKE2_F_ARG_LEN { |
| 24 | + return ( |
| 25 | + ExitException::Other( |
| 26 | + "input length for Blake2 F precompile should be exactly 213 bytes".into(), |
| 27 | + ) |
| 28 | + .into(), |
| 29 | + Vec::new(), |
| 30 | + ); |
| 31 | + } |
55 | 32 |
|
56 | | - let mut m_buf: [u8; 128] = [0; 128]; |
57 | | - m_buf.copy_from_slice(&input[68..196]); |
58 | | - let mut m = [0u64; 16]; |
59 | | - ctr = 0; |
60 | | - for msg_word in &mut m { |
61 | | - let mut temp: [u8; 8] = Default::default(); |
62 | | - temp.copy_from_slice(&m_buf[(ctr * 8)..(ctr + 1) * 8]); |
63 | | - *msg_word = u64::from_le_bytes(temp); |
64 | | - ctr += 1; |
65 | | - } |
| 33 | + let mut rounds_buf: [u8; 4] = [0; 4]; |
| 34 | + rounds_buf.copy_from_slice(&input[0..4]); |
| 35 | + let rounds: u32 = u32::from_be_bytes(rounds_buf); |
| 36 | + |
| 37 | + let gas_cost: u64 = (rounds as u64) * Blake2F::GAS_COST_PER_ROUND; |
| 38 | + try_some!(gasometer.record_cost(gas_cost.into())); |
| 39 | + |
| 40 | + // we use from_le_bytes below to effectively swap byte order to LE if architecture is BE |
| 41 | + let mut h_buf: [u8; 64] = [0; 64]; |
| 42 | + h_buf.copy_from_slice(&input[4..68]); |
| 43 | + let mut h = [0u64; 8]; |
| 44 | + let mut ctr = 0; |
| 45 | + for state_word in &mut h { |
| 46 | + let mut temp: [u8; 8] = Default::default(); |
| 47 | + temp.copy_from_slice(&h_buf[(ctr * 8)..(ctr + 1) * 8]); |
| 48 | + *state_word = u64::from_le_bytes(temp); |
| 49 | + ctr += 1; |
| 50 | + } |
66 | 51 |
|
67 | | - let mut t_0_buf: [u8; 8] = [0; 8]; |
68 | | - t_0_buf.copy_from_slice(&input[196..204]); |
69 | | - let t_0 = u64::from_le_bytes(t_0_buf); |
| 52 | + let mut m_buf: [u8; 128] = [0; 128]; |
| 53 | + m_buf.copy_from_slice(&input[68..196]); |
| 54 | + let mut m = [0u64; 16]; |
| 55 | + ctr = 0; |
| 56 | + for msg_word in &mut m { |
| 57 | + let mut temp: [u8; 8] = Default::default(); |
| 58 | + temp.copy_from_slice(&m_buf[(ctr * 8)..(ctr + 1) * 8]); |
| 59 | + *msg_word = u64::from_le_bytes(temp); |
| 60 | + ctr += 1; |
| 61 | + } |
70 | 62 |
|
71 | | - let mut t_1_buf: [u8; 8] = [0; 8]; |
72 | | - t_1_buf.copy_from_slice(&input[204..212]); |
73 | | - let t_1 = u64::from_le_bytes(t_1_buf); |
| 63 | + let mut t_0_buf: [u8; 8] = [0; 8]; |
| 64 | + t_0_buf.copy_from_slice(&input[196..204]); |
| 65 | + let t_0 = u64::from_le_bytes(t_0_buf); |
74 | 66 |
|
75 | | - let f = if input[212] == 1 { |
76 | | - true |
77 | | - } else if input[212] == 0 { |
78 | | - false |
79 | | - } else { |
80 | | - return Some(( |
81 | | - ExitException::Other("incorrect final block indicator flag".into()).into(), |
82 | | - Vec::new(), |
83 | | - )); |
84 | | - }; |
| 67 | + let mut t_1_buf: [u8; 8] = [0; 8]; |
| 68 | + t_1_buf.copy_from_slice(&input[204..212]); |
| 69 | + let t_1 = u64::from_le_bytes(t_1_buf); |
85 | 70 |
|
86 | | - eip152::compress(&mut h, m, [t_0, t_1], f, rounds as usize); |
| 71 | + let f = if input[212] == 1 { |
| 72 | + true |
| 73 | + } else if input[212] == 0 { |
| 74 | + false |
| 75 | + } else { |
| 76 | + return ( |
| 77 | + ExitException::Other("incorrect final block indicator flag".into()).into(), |
| 78 | + Vec::new(), |
| 79 | + ); |
| 80 | + }; |
87 | 81 |
|
88 | | - let mut output_buf = [0u8; u64::BITS as usize]; |
89 | | - for (i, state_word) in h.iter().enumerate() { |
90 | | - output_buf[i * 8..(i + 1) * 8].copy_from_slice(&state_word.to_le_bytes()); |
91 | | - } |
| 82 | + eip152::compress(&mut h, m, [t_0, t_1], f, rounds as usize); |
92 | 83 |
|
93 | | - Some((ExitSucceed::Returned.into(), output_buf.to_vec())) |
94 | | - } else { |
95 | | - None |
| 84 | + let mut output_buf = [0u8; u64::BITS as usize]; |
| 85 | + for (i, state_word) in h.iter().enumerate() { |
| 86 | + output_buf[i * 8..(i + 1) * 8].copy_from_slice(&state_word.to_le_bytes()); |
96 | 87 | } |
| 88 | + |
| 89 | + (ExitSucceed::Returned.into(), output_buf.to_vec()) |
97 | 90 | } |
98 | 91 | } |
0 commit comments