revm_precompile/hash.rs
1//! Hash precompiles, it contains SHA-256 and RIPEMD-160 hash precompiles
2//! More details in [`sha256_run`] and [`ripemd160_run`]
3use super::calc_linear_cost_u32;
4use crate::{crypto, PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress};
5
6/// SHA-256 precompile
7pub const SHA256: PrecompileWithAddress =
8 PrecompileWithAddress(crate::u64_to_address(2), sha256_run);
9
10/// RIPEMD-160 precompile
11pub const RIPEMD160: PrecompileWithAddress =
12 PrecompileWithAddress(crate::u64_to_address(3), ripemd160_run);
13
14/// Computes the SHA-256 hash of the input data
15///
16/// This function follows specifications defined in the following references:
17/// - [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf)
18/// - [Solidity Documentation on Mathematical and Cryptographic Functions](https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions)
19/// - [Address 0x02](https://etherscan.io/address/0000000000000000000000000000000000000002)
20pub fn sha256_run(input: &[u8], gas_limit: u64) -> PrecompileResult {
21 let cost = calc_linear_cost_u32(input.len(), 60, 12);
22 if cost > gas_limit {
23 Err(PrecompileError::OutOfGas)
24 } else {
25 let output = crypto().sha256(input);
26 Ok(PrecompileOutput::new(cost, output.to_vec().into()))
27 }
28}
29
30/// Computes the RIPEMD-160 hash of the input data
31///
32/// This function follows specifications defined in the following references:
33/// - [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf)
34/// - [Solidity Documentation on Mathematical and Cryptographic Functions](https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions)
35/// - [Address 03](https://etherscan.io/address/0000000000000000000000000000000000000003)
36pub fn ripemd160_run(input: &[u8], gas_limit: u64) -> PrecompileResult {
37 let gas_used = calc_linear_cost_u32(input.len(), 600, 120);
38 if gas_used > gas_limit {
39 Err(PrecompileError::OutOfGas)
40 } else {
41 let output = crypto().ripemd160(input);
42 Ok(PrecompileOutput::new(gas_used, output.to_vec().into()))
43 }
44}