diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index e0cd3bc72d..211b898cac 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -1,13 +1,11 @@ -use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn}; +use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; use core::convert::TryInto; const F_ROUND: u64 = 1; const INPUT_LENGTH: usize = 213; -pub const FUN: PrecompileWithAddress = PrecompileWithAddress( - crate::u64_to_address(9), - Precompile::Standard(run as StandardPrecompileFn), -); +pub const FUN: PrecompileWithAddress = + PrecompileWithAddress(crate::u64_to_address(9), Precompile::Standard(run)); /// reference: /// input format: diff --git a/crates/precompile/src/hash.rs b/crates/precompile/src/hash.rs index 4afe59c4f3..c8ad6c9df1 100644 --- a/crates/precompile/src/hash.rs +++ b/crates/precompile/src/hash.rs @@ -1,14 +1,13 @@ use super::calc_linear_cost_u32; -use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn}; -use sha2::*; +use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; +use sha2::Digest; + +pub const SHA256: PrecompileWithAddress = + PrecompileWithAddress(crate::u64_to_address(2), Precompile::Standard(sha256_run)); -pub const SHA256: PrecompileWithAddress = PrecompileWithAddress( - crate::u64_to_address(2), - Precompile::Standard(sha256_run as StandardPrecompileFn), -); pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(3), - Precompile::Standard(ripemd160_run as StandardPrecompileFn), + Precompile::Standard(ripemd160_run), ); /// See: @@ -32,8 +31,11 @@ fn ripemd160_run(input: &[u8], gas_limit: u64) -> PrecompileResult { if gas_used > gas_limit { Err(Error::OutOfGas) } else { - let mut ret = [0u8; 32]; - ret[12..32].copy_from_slice(&ripemd::Ripemd160::digest(input)); - Ok((gas_used, ret.to_vec())) + let mut hasher = ripemd::Ripemd160::new(); + hasher.update(input); + + let mut output = [0u8; 32]; + hasher.finalize_into((&mut output[12..]).into()); + Ok((gas_used, output.to_vec())) } } diff --git a/crates/precompile/src/identity.rs b/crates/precompile/src/identity.rs index d3e9bfbd56..8b743799ee 100644 --- a/crates/precompile/src/identity.rs +++ b/crates/precompile/src/identity.rs @@ -1,10 +1,8 @@ use super::calc_linear_cost_u32; -use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn}; +use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress}; -pub const FUN: PrecompileWithAddress = PrecompileWithAddress( - crate::u64_to_address(4), - Precompile::Standard(identity_run as StandardPrecompileFn), -); +pub const FUN: PrecompileWithAddress = + PrecompileWithAddress(crate::u64_to_address(4), Precompile::Standard(identity_run)); /// The base cost of the operation. const IDENTITY_BASE: u64 = 15; diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index e26a990169..9a099f7885 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -176,7 +176,7 @@ impl Precompiles { /// Is the given address a precompile. #[inline] pub fn contains(&self, address: &Address) -> bool { - self.get(address).is_some() + self.inner.contains_key(address) } /// Returns the precompile for the given address. diff --git a/crates/precompile/src/modexp.rs b/crates/precompile/src/modexp.rs index 344bf1dd6c..953f4e1dd1 100644 --- a/crates/precompile/src/modexp.rs +++ b/crates/precompile/src/modexp.rs @@ -1,7 +1,7 @@ use crate::{ primitives::U256, utilities::{get_right_padded, get_right_padded_vec, left_padding, left_padding_vec}, - Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn, + Error, Precompile, PrecompileResult, PrecompileWithAddress, }; use alloc::vec::Vec; use aurora_engine_modexp::modexp; @@ -9,13 +9,11 @@ use core::cmp::{max, min}; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(5), - Precompile::Standard(byzantium_run as StandardPrecompileFn), + Precompile::Standard(byzantium_run), ); -pub const BERLIN: PrecompileWithAddress = PrecompileWithAddress( - crate::u64_to_address(5), - Precompile::Standard(berlin_run as StandardPrecompileFn), -); +pub const BERLIN: PrecompileWithAddress = + PrecompileWithAddress(crate::u64_to_address(5), Precompile::Standard(berlin_run)); /// See: /// See: @@ -39,7 +37,8 @@ fn calculate_iteration_count(exp_length: u64, exp_highp: &U256) -> u64 { } else if exp_length <= 32 { iteration_count = exp_highp.bit_len() as u64 - 1; } else if exp_length > 32 { - iteration_count = (8 * (exp_length - 32)) + max(1, exp_highp.bit_len() as u64) - 1; + iteration_count = (8u64.saturating_mul(exp_length - 32)) + .saturating_add(max(1, exp_highp.bit_len() as u64) - 1); } max(iteration_count, 1) @@ -139,12 +138,7 @@ fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &U25 let iter_count = U256::from(calculate_iteration_count(exp_len, exp_highp)); // mul * iter_count bounded by 2^195 < 2^256 (no overflow) let gas = (mul * iter_count) / U256::from(20); - - if gas.as_limbs()[1] != 0 || gas.as_limbs()[2] != 0 || gas.as_limbs()[3] != 0 { - u64::MAX - } else { - gas.as_limbs()[0] - } + gas.saturating_to() } // Calculate gas cost according to EIP 2565: @@ -163,12 +157,7 @@ fn berlin_gas_calc(base_length: u64, exp_length: u64, mod_length: u64, exp_highp let multiplication_complexity = calculate_multiplication_complexity(base_length, mod_length); let iteration_count = calculate_iteration_count(exp_length, exp_highp); let gas = (multiplication_complexity * U256::from(iteration_count)) / U256::from(3); - - if gas.as_limbs()[1] != 0 || gas.as_limbs()[2] != 0 || gas.as_limbs()[3] != 0 { - u64::MAX - } else { - max(200, gas.as_limbs()[0]) - } + max(200, gas.saturating_to()) } #[cfg(test)] diff --git a/crates/precompile/src/secp256k1.rs b/crates/precompile/src/secp256k1.rs index 4889a89488..48d528a22c 100644 --- a/crates/precompile/src/secp256k1.rs +++ b/crates/precompile/src/secp256k1.rs @@ -1,31 +1,30 @@ -use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn}; +use crate::{ + utilities::get_right_padded, Error, Precompile, PrecompileResult, PrecompileWithAddress, +}; use alloc::vec::Vec; -use core::cmp::min; -use revm_primitives::B256; +use revm_primitives::{alloy_primitives::B512, B256}; pub const ECRECOVER: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(1), - Precompile::Standard(ec_recover_run as StandardPrecompileFn), + Precompile::Standard(ec_recover_run), ); #[cfg(not(feature = "secp256k1"))] #[allow(clippy::module_inception)] mod secp256k1 { - use crate::B256; use k256::ecdsa::{Error, RecoveryId, Signature, VerifyingKey}; - use revm_primitives::keccak256; + use revm_primitives::{alloy_primitives::B512, keccak256, B256}; - pub fn ecrecover(sig: &[u8; 65], msg: &B256) -> Result { + pub fn ecrecover(sig: &B512, mut recid: u8, msg: &B256) -> Result { // parse signature - let mut recid = sig[64]; - let mut sig = Signature::from_slice(&sig[..64])?; + let mut sig = Signature::from_slice(sig.as_slice())?; // normalize signature and flip recovery id if needed. if let Some(sig_normalized) = sig.normalize_s() { sig = sig_normalized; recid = recid ^ 1; - }; - let recid = RecoveryId::from_byte(recid).expect("Recovery id is valid"); + } + let recid = RecoveryId::from_byte(recid).expect("recovery ID is valid"); // recover key let recovered_key = VerifyingKey::recover_from_prehash(&msg[..], &sig, recid)?; @@ -45,8 +44,7 @@ mod secp256k1 { #[cfg(feature = "secp256k1")] #[allow(clippy::module_inception)] mod secp256k1 { - use crate::B256; - use revm_primitives::keccak256; + use revm_primitives::{alloy_primitives::B512, keccak256, B256}; use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, Message, Secp256k1, @@ -55,12 +53,13 @@ mod secp256k1 { // Silence the unused crate dependency warning. use k256 as _; - pub fn ecrecover(sig: &[u8; 65], msg: &B256) -> Result { - let sig = - RecoverableSignature::from_compact(&sig[0..64], RecoveryId::from_i32(sig[64] as i32)?)?; + pub fn ecrecover(sig: &B512, recid: u8, msg: &B256) -> Result { + let recid = RecoveryId::from_i32(recid as i32).expect("recovery ID is valid"); + let sig = RecoverableSignature::from_compact(sig.as_slice(), recid)?; let secp = Secp256k1::new(); - let public = secp.recover_ecdsa(&Message::from_digest_slice(&msg[..])?, &sig)?; + let msg = Message::from_digest_slice(msg.as_slice())?; + let public = secp.recover_ecdsa(&msg, &sig)?; let mut hash = keccak256(&public.serialize_uncompressed()[1..]); hash[..12].fill(0); @@ -68,27 +67,25 @@ mod secp256k1 { } } -fn ec_recover_run(i: &[u8], target_gas: u64) -> PrecompileResult { +fn ec_recover_run(input: &[u8], target_gas: u64) -> PrecompileResult { const ECRECOVER_BASE: u64 = 3_000; if ECRECOVER_BASE > target_gas { return Err(Error::OutOfGas); } - let mut input = [0u8; 128]; - input[..min(i.len(), 128)].copy_from_slice(&i[..min(i.len(), 128)]); - let msg = B256::from_slice(&input[0..32]); + let input = get_right_padded::<128>(input, 0); - let mut sig = [0u8; 65]; - sig[0..64].copy_from_slice(&input[64..128]); - - if input[32..63] != [0u8; 31] || !matches!(input[63], 27 | 28) { + // `v` must be a 32-byte big-endian integer equal to 27 or 28. + if !(input[32..63].iter().all(|&b| b == 0) && matches!(input[63], 27 | 28)) { return Ok((ECRECOVER_BASE, Vec::new())); } - sig[64] = input[63] - 27; + let msg = <&B256>::try_from(&input[0..32]).unwrap(); + let recid = input[63] - 27; + let sig = <&B512>::try_from(&input[64..128]).unwrap(); - let out = secp256k1::ecrecover(&sig, &msg) + let out = secp256k1::ecrecover(sig, recid, msg) .map(|o| o.to_vec()) .unwrap_or_default(); diff --git a/crates/precompile/src/utilities.rs b/crates/precompile/src/utilities.rs index 3b0f19143c..5d63c9b33a 100644 --- a/crates/precompile/src/utilities.rs +++ b/crates/precompile/src/utilities.rs @@ -1,20 +1,19 @@ -use core::cmp::min; - use alloc::vec::Vec; +use core::cmp::min; -/// Get an array from the data, if data does not contain `start` to `len` bytes, add right padding with -/// zeroes +/// Get an array from the data, if data does not contain `start` to `len` bytes, +/// add right padding with zeroes. #[inline(always)] -pub fn get_right_padded(data: &[u8], offset: usize) -> [u8; S] { - let mut padded = [0; S]; +pub fn get_right_padded(data: &[u8], offset: usize) -> [u8; LEN] { + let mut padded = [0; LEN]; let start = min(offset, data.len()); - let end = min(start.saturating_add(S), data.len()); + let end = min(start.saturating_add(LEN), data.len()); padded[..end - start].copy_from_slice(&data[start..end]); padded } -/// Get a vector of the data, if data does not contain the slice of `start` to `len`, right pad missing -/// part with zeroes +/// Get a vector of the data, if data does not contain the slice of `start` to `len`, +/// right pad missing part with zeroes. #[inline(always)] pub fn get_right_padded_vec(data: &[u8], offset: usize, len: usize) -> Vec { let mut padded = vec![0; len]; @@ -26,10 +25,10 @@ pub fn get_right_padded_vec(data: &[u8], offset: usize, len: usize) -> Vec { /// Left padding until `len`. If data is more then len, truncate the right most bytes. #[inline(always)] -pub fn left_padding(data: &[u8]) -> [u8; S] { - let mut padded = [0; S]; - let end = min(S, data.len()); - padded[S - end..].copy_from_slice(&data[..end]); +pub fn left_padding(data: &[u8]) -> [u8; LEN] { + let mut padded = [0; LEN]; + let end = min(LEN, data.len()); + padded[LEN - end..].copy_from_slice(&data[..end]); padded } diff --git a/crates/revm/src/context.rs b/crates/revm/src/context.rs index 450f3f24a3..b53e73ac49 100644 --- a/crates/revm/src/context.rs +++ b/crates/revm/src/context.rs @@ -164,7 +164,7 @@ impl EvmContext { /// Sets precompiles pub fn set_precompiles(&mut self, precompiles: Precompiles) { self.journaled_state.warm_preloaded_addresses = - precompiles.addresses().cloned().collect::>(); + precompiles.addresses().copied().collect::>(); self.precompiles = precompiles; }