|
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