Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions src/precompile/blake2.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
use super::precompile_not_implemented;

use revm::{
precompile::{u64_to_address, PrecompileWithAddress},
precompile::{blake2, PrecompileWithAddress},
primitives::Address,
};

// CONSTANTS
// ================================================================================================

/// The BLAKE2 precompile index.
const BLAKE2_PRECOMPILE_INDEX: u64 = 9;

/// The BLAKE2 precompile address.
const BLAKE2_PRECOMPILE_ADDRESS: Address = u64_to_address(BLAKE2_PRECOMPILE_INDEX);

// BLAKE2 PRECOMPILE
// ================================================================================================
pub const ADDRESS: Address = blake2::FUN.0;

/// The shanghai BLAKE2 precompile implementation with address.
/// The BLAKE2 precompile is not implemented in the SHANGHAI hardfork.
///
/// This precompile is not implemented and will return `PrecompileError::Other("Precompile not
/// implemented".into())`.
pub const SHANGHAI: PrecompileWithAddress = precompile_not_implemented(BLAKE2_PRECOMPILE_ADDRESS);
pub const SHANGHAI: PrecompileWithAddress = precompile_not_implemented(ADDRESS);
46 changes: 11 additions & 35 deletions src/precompile/bn128.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,33 @@
use revm::{
precompile::{
bn128::{
pair::{ISTANBUL_PAIR_BASE, ISTANBUL_PAIR_PER_POINT},
run_pair,
},
u64_to_address, PrecompileError, PrecompileResult, PrecompileWithAddress,
},
primitives::Address,
use revm::precompile::{
bn128::{self, run_pair, PAIR_ELEMENT_LEN},
PrecompileError, PrecompileResult, PrecompileWithAddress,
};

pub mod pair {
use super::*;

// CONSTANTS
// --------------------------------------------------------------------------------------------

/// The BN128 pairing precompile index.
const BN128_PAIRING_PRECOMPILE_INDEX: u64 = 8;

/// The BN128 pairing precompile address.
pub const BN128_PAIRING_PRECOMPILE_ADDRESS: Address =
u64_to_address(BN128_PAIRING_PRECOMPILE_INDEX);
pub use bn128::pair::{ADDRESS, ISTANBUL_PAIR_BASE, ISTANBUL_PAIR_PER_POINT};

/// The number of pairing inputs per pairing operation. If the inputs provided to the precompile
/// call are < 4, we append (G1::infinity, G2::generator) until we have the required no. of
/// inputs.
const N_PAIRING_PER_OP: usize = 4;

/// The number of bytes taken to represent a pair (G1, G2).
const N_BYTES_PER_PAIR: usize = 192;

// BN128 PAIRING PRECOMPILE
// --------------------------------------------------------------------------------------------
const BERNOULLI_LEN_LIMIT: usize = 4;

/// The BN128 PAIRING precompile with address.
pub const BERNOULLI: PrecompileWithAddress =
PrecompileWithAddress(BN128_PAIRING_PRECOMPILE_ADDRESS, bernoulli_run);
/// The Bn128 pair precompile with BERNOULLI input rules.
pub const BERNOULLI: PrecompileWithAddress = PrecompileWithAddress(ADDRESS, bernoulli_run);

/// The bernoulli BN128 PAIRING precompile implementation.
/// The bernoulli Bn128 pair precompile implementation.
///
/// # Errors
/// - `PrecompileError::Other("BN128PairingInputOverflow: input overflow".into())` if the input
/// length is greater than 768 bytes.
fn bernoulli_run(input: &[u8], gas_limit: u64) -> PrecompileResult {
if input.len() > N_PAIRING_PER_OP * N_BYTES_PER_PAIR {
if input.len() > BERNOULLI_LEN_LIMIT * PAIR_ELEMENT_LEN {
return Err(PrecompileError::Other("BN128PairingInputOverflow: input overflow".into()));
}
run_pair(input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, gas_limit)
}

/// The BN128 PAIRING precompile with address.
pub const FEYNMAN: PrecompileWithAddress =
PrecompileWithAddress(BN128_PAIRING_PRECOMPILE_ADDRESS, |input, gas_limit| {
run_pair(input, ISTANBUL_PAIR_PER_POINT, ISTANBUL_PAIR_BASE, gas_limit)
});
/// The Bn128 pair precompile in FEYNMAN hardfork.
pub const FEYNMAN: PrecompileWithAddress = bn128::pair::ISTANBUL;
}
42 changes: 9 additions & 33 deletions src/precompile/hash.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
use super::precompile_not_implemented;

use revm::{
precompile::{hash::sha256_run, u64_to_address, PrecompileWithAddress},
precompile::{hash, PrecompileWithAddress},
primitives::Address,
};

pub mod sha256 {
use super::*;

// CONSTANTS
// ------------------------------------------------------------------------------------------------
/// SHA-256 precompile address
pub const ADDRESS: Address = hash::SHA256.0;

/// The SHA256 precompile index.
const SHA256_PRECOMPILE_INDEX: u64 = 2;

/// The SHA256 precompile address.
const SHA256_PRECOMPILE_ADDRESS: Address = u64_to_address(SHA256_PRECOMPILE_INDEX);

// SHA256 SHANGHAI PRECOMPILE
// --------------------------------------------------------------------------------------------

/// The shanghai SHA256 precompile implementation with address.
pub const SHA256_SHANGHAI: PrecompileWithAddress =
precompile_not_implemented(SHA256_PRECOMPILE_ADDRESS);

// SHA256 BERNOULLI PRECOMPILE
// --------------------------------------------------------------------------------------------
/// The SHA256 precompile is not implemented in the Shanghai hardfork.
pub const SHANGHAI: PrecompileWithAddress = precompile_not_implemented(ADDRESS);

/// The bernoulli SHA256 precompile implementation with address.
pub const SHA256_BERNOULLI: PrecompileWithAddress =
PrecompileWithAddress(SHA256_PRECOMPILE_ADDRESS, sha256_run);
pub const BERNOULLI: PrecompileWithAddress = PrecompileWithAddress(ADDRESS, hash::sha256_run);
}

pub mod ripemd160 {
use super::*;

// CONSTANTS
// --------------------------------------------------------------------------------------------

/// The RIPEMD160 precompile index.
const RIPEMD160_PRECOMPILE_INDEX: u64 = 3;

/// The RIPEMD160 precompile address.
const RIPEMD160_PRECOMPILE_ADDRESS: Address = u64_to_address(RIPEMD160_PRECOMPILE_INDEX);

// RIPEMD160 SHANGHAI PRECOMPILE
// --------------------------------------------------------------------------------------------
pub const ADDRESS: Address = hash::RIPEMD160.0;

/// The shanghai RIPEMD160 precompile implementation with address.
/// The shanghai RIPEMD160 precompile is not implemented in the Shanghai hardfork.
///
/// This precompile is not implemented and will return `PrecompileError::Other("Precompile not
/// implemented".into())`.
pub const RIPEMD160_SHANGHAI: PrecompileWithAddress =
precompile_not_implemented(RIPEMD160_PRECOMPILE_ADDRESS);
pub const SHANGHAI: PrecompileWithAddress = precompile_not_implemented(ADDRESS);
}
12 changes: 6 additions & 6 deletions src/precompile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ pub(crate) fn pre_bernoulli() -> &'static Precompiles {

precompiles.extend([
precompile::secp256k1::ECRECOVER,
hash::sha256::SHA256_SHANGHAI,
hash::ripemd160::RIPEMD160_SHANGHAI,
hash::sha256::SHANGHAI,
hash::ripemd160::SHANGHAI,
precompile::identity::FUN,
modexp::BERNOULLI,
precompile::bn128::add::ISTANBUL,
Expand All @@ -77,7 +77,7 @@ pub(crate) fn bernoulli() -> &'static Precompiles {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let mut precompiles = pre_bernoulli().clone();
precompiles.extend([hash::sha256::SHA256_BERNOULLI]);
precompiles.extend([hash::sha256::BERNOULLI]);
Box::new(precompiles)
})
}
Expand Down Expand Up @@ -149,7 +149,7 @@ impl Default for ScrollPrecompileProvider {
#[cfg(test)]
mod tests {
use super::*;
use crate::precompile::bn128::pair::BN128_PAIRING_PRECOMPILE_ADDRESS;
use crate::precompile::bn128::pair;
use revm::primitives::hex;

#[test]
Expand All @@ -162,12 +162,12 @@ mod tests {
.unwrap();

// Euclid version should reject this input
let f = euclid().get(&BN128_PAIRING_PRECOMPILE_ADDRESS).expect("precompile exists");
let f = euclid().get(&pair::ADDRESS).expect("precompile exists");
let outcome = f(&input, u64::MAX);
assert!(outcome.is_err());

// Feynman version should accept this input
let f = feynman().get(&BN128_PAIRING_PRECOMPILE_ADDRESS).expect("precompile exists");
let f = feynman().get(&pair::ADDRESS).expect("precompile exists");
let outcome = f(&input, u64::MAX).expect("call succeeds");
assert_eq!(outcome.bytes, expected);
}
Expand Down
31 changes: 10 additions & 21 deletions src/precompile/modexp.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
use revm::{
precompile::{
modexp::{berlin_gas_calc, run_inner},
u64_to_address,
modexp::{self, berlin_gas_calc, run_inner},
utilities::right_pad_with_offset,
PrecompileError, PrecompileResult, PrecompileWithAddress,
},
primitives::{Address, U256},
};

// CONSTANTS
// ================================================================================================

/// The MODEXP precompile index.
const MODEXP_PRECOMPILE_INDEX: u64 = 5;

/// The MODEXP precompile address.
const MODEXP_PRECOMPILE_ADDRESS: Address = u64_to_address(MODEXP_PRECOMPILE_INDEX);

/// The maximum length of the input for the MODEXP precompile.
const SCROLL_LEN_LIMIT: U256 = U256::from_limbs([32, 0, 0, 0]);
pub const ADDRESS: Address = modexp::BYZANTIUM.0;

// MODEXP PRECOMPILE
// ================================================================================================
/// The maximum length of the input for the MODEXP precompile in BERNOULLI hardfork.
pub const BERNOULLI_LEN_LIMIT: U256 = U256::from_limbs([32, 0, 0, 0]);

/// The bernoulli MODEXP precompile implementation with address.
pub const BERNOULLI: PrecompileWithAddress =
PrecompileWithAddress(MODEXP_PRECOMPILE_ADDRESS, bernoulli_run);
/// The MODEXP precompile with BERNOULLI length limit rule.
pub const BERNOULLI: PrecompileWithAddress = PrecompileWithAddress(ADDRESS, bernoulli_run);

/// The bernoulli MODEXP precompile implementation.
///
Expand All @@ -36,19 +25,19 @@ pub const BERNOULLI: PrecompileWithAddress =
/// length is greater than 32 bytes.
/// - `PrecompileError::Other("ModexpModOverflow: modexp mod overflow".into())` if the modulus
/// length is greater than 32 bytes.
fn bernoulli_run(input: &[u8], gas_limit: u64) -> PrecompileResult {
pub fn bernoulli_run(input: &[u8], gas_limit: u64) -> PrecompileResult {
let base_len = U256::from_be_bytes(right_pad_with_offset::<32>(input, 0).into_owned());
let exp_len = U256::from_be_bytes(right_pad_with_offset::<32>(input, 32).into_owned());
let mod_len = U256::from_be_bytes(right_pad_with_offset::<32>(input, 64).into_owned());

// modexp temporarily only accepts inputs of 32 bytes (256 bits) or less
if base_len > SCROLL_LEN_LIMIT {
if base_len > BERNOULLI_LEN_LIMIT {
return Err(PrecompileError::Other("ModexpBaseOverflow: modexp base overflow".into()));
}
if exp_len > SCROLL_LEN_LIMIT {
if exp_len > BERNOULLI_LEN_LIMIT {
return Err(PrecompileError::Other("ModexpExpOverflow: modexp exp overflow".into()));
}
if mod_len > SCROLL_LEN_LIMIT {
if mod_len > BERNOULLI_LEN_LIMIT {
return Err(PrecompileError::Other("ModexpModOverflow: modexp mod overflow".into()));
}

Expand Down
Loading