1use super::calc_linear_cost_u32;
2use crate::{PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress};
3use primitives::Bytes;
4use sha2::Digest;
5
6pub const SHA256: PrecompileWithAddress =
7 PrecompileWithAddress(crate::u64_to_address(2), sha256_run);
8
9pub const RIPEMD160: PrecompileWithAddress =
10 PrecompileWithAddress(crate::u64_to_address(3), ripemd160_run);
11
12pub fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult {
19 let cost = calc_linear_cost_u32(input.len(), 60, 12);
20 if cost > gas_limit {
21 Err(PrecompileError::OutOfGas)
22 } else {
23 let output = sha2::Sha256::digest(input);
24 Ok(PrecompileOutput::new(cost, output.to_vec().into()))
25 }
26}
27
28pub fn ripemd160_run(input: &Bytes, gas_limit: u64) -> PrecompileResult {
35 let gas_used = calc_linear_cost_u32(input.len(), 600, 120);
36 if gas_used > gas_limit {
37 Err(PrecompileError::OutOfGas)
38 } else {
39 let mut hasher = ripemd::Ripemd160::new();
40 hasher.update(input);
41
42 let mut output = [0u8; 32];
43 hasher.finalize_into((&mut output[12..]).into());
44 Ok(PrecompileOutput::new(gas_used, output.to_vec().into()))
45 }
46}