From 29c587bc07dc1355958043d52aaa5cb88998b67d Mon Sep 17 00:00:00 2001 From: rakita Date: Wed, 20 Mar 2024 00:15:11 +0100 Subject: [PATCH] feat: make all precompiles public (#1213) * feat: make all precompiles public * make inner function pub --- crates/precompile/src/blake2.rs | 10 +++++----- crates/precompile/src/bn128.rs | 20 +++++++++---------- crates/precompile/src/hash.rs | 4 ++-- crates/precompile/src/identity.rs | 6 +++--- crates/precompile/src/kzg_point_evaluation.rs | 18 ++++++++--------- crates/precompile/src/lib.rs | 8 ++++---- crates/precompile/src/modexp.rs | 15 +++++++++----- 7 files changed, 43 insertions(+), 38 deletions(-) diff --git a/crates/precompile/src/blake2.rs b/crates/precompile/src/blake2.rs index 6a173494e9..48b566bb92 100644 --- a/crates/precompile/src/blake2.rs +++ b/crates/precompile/src/blake2.rs @@ -10,7 +10,7 @@ pub const FUN: PrecompileWithAddress = /// reference: /// input format: /// [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] -fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input = &input[..]; if input.len() != INPUT_LENGTH { @@ -54,9 +54,9 @@ fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult { Ok((gas_used, out.into())) } -mod algo { +pub mod algo { /// SIGMA from spec: - const SIGMA: [[usize; 16]; 10] = [ + pub const SIGMA: [[usize; 16]; 10] = [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], @@ -70,7 +70,7 @@ mod algo { ]; /// got IV from: - const IV: [u64; 8] = [ + pub const IV: [u64; 8] = [ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, @@ -84,7 +84,7 @@ mod algo { #[inline(always)] #[allow(clippy::many_single_char_names)] /// G function: - fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + pub fn g(v: &mut [u64], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { v[a] = v[a].wrapping_add(v[b]).wrapping_add(x); v[d] = (v[d] ^ v[a]).rotate_right(32); v[c] = v[c].wrapping_add(v[d]); diff --git a/crates/precompile/src/bn128.rs b/crates/precompile/src/bn128.rs index f88a5a9599..c243e7e477 100644 --- a/crates/precompile/src/bn128.rs +++ b/crates/precompile/src/bn128.rs @@ -76,8 +76,8 @@ pub mod pair { }), ); - const BYZANTIUM_PAIR_PER_POINT: u64 = 80_000; - const BYZANTIUM_PAIR_BASE: u64 = 100_000; + pub const BYZANTIUM_PAIR_PER_POINT: u64 = 80_000; + pub const BYZANTIUM_PAIR_BASE: u64 = 100_000; pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress( ADDRESS, Precompile::Standard(|input, gas_limit| { @@ -92,13 +92,13 @@ pub mod pair { } /// Input length for the add operation. -const ADD_INPUT_LEN: usize = 128; +pub const ADD_INPUT_LEN: usize = 128; /// Input length for the multiplication operation. -const MUL_INPUT_LEN: usize = 128; +pub const MUL_INPUT_LEN: usize = 128; /// Pair element length. -const PAIR_ELEMENT_LEN: usize = 192; +pub const PAIR_ELEMENT_LEN: usize = 192; /// Reads a single `Fq` from the input slice. /// @@ -106,7 +106,7 @@ const PAIR_ELEMENT_LEN: usize = 192; /// /// Panics if the input is not at least 32 bytes long. #[inline] -fn read_fq(input: &[u8]) -> Result { +pub fn read_fq(input: &[u8]) -> Result { Fq::from_slice(&input[..32]).map_err(|_| Error::Bn128FieldPointNotAMember) } @@ -116,14 +116,14 @@ fn read_fq(input: &[u8]) -> Result { /// /// Panics if the input is not at least 64 bytes long. #[inline] -fn read_point(input: &[u8]) -> Result { +pub fn read_point(input: &[u8]) -> Result { let px = read_fq(&input[0..32])?; let py = read_fq(&input[32..64])?; new_g1_point(px, py) } /// Creates a new `G1` point from the given `x` and `y` coordinates. -fn new_g1_point(px: Fq, py: Fq) -> Result { +pub fn new_g1_point(px: Fq, py: Fq) -> Result { if px == Fq::zero() && py == Fq::zero() { Ok(G1::zero()) } else { @@ -133,7 +133,7 @@ fn new_g1_point(px: Fq, py: Fq) -> Result { } } -fn run_add(input: &[u8]) -> Result { +pub fn run_add(input: &[u8]) -> Result { let input = right_pad::(input); let p1 = read_point(&input[..64])?; @@ -154,7 +154,7 @@ fn run_add(input: &[u8]) -> Result { Ok(output.into()) } -fn run_mul(input: &[u8]) -> Result { +pub fn run_mul(input: &[u8]) -> Result { let input = right_pad::(input); let p = read_point(&input[..64])?; diff --git a/crates/precompile/src/hash.rs b/crates/precompile/src/hash.rs index b170cd1c51..9fc6a8ae49 100644 --- a/crates/precompile/src/hash.rs +++ b/crates/precompile/src/hash.rs @@ -14,7 +14,7 @@ pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress( /// See: /// See: /// See: -fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let cost = calc_linear_cost_u32(input.len(), 60, 12); if cost > gas_limit { Err(Error::OutOfGas) @@ -27,7 +27,7 @@ fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { /// See: /// See: /// See: -fn ripemd160_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub fn ripemd160_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let gas_used = calc_linear_cost_u32(input.len(), 600, 120); if gas_used > gas_limit { Err(Error::OutOfGas) diff --git a/crates/precompile/src/identity.rs b/crates/precompile/src/identity.rs index efe97e8a32..85722ea810 100644 --- a/crates/precompile/src/identity.rs +++ b/crates/precompile/src/identity.rs @@ -6,15 +6,15 @@ 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; +pub const IDENTITY_BASE: u64 = 15; /// The cost per word. -const IDENTITY_PER_WORD: u64 = 3; +pub const IDENTITY_PER_WORD: u64 = 3; /// Takes the input bytes, copies them, and returns it as the output. /// /// See: /// See: -fn identity_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub fn identity_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { let gas_used = calc_linear_cost_u32(input.len(), IDENTITY_BASE, IDENTITY_PER_WORD); if gas_used > gas_limit { return Err(Error::OutOfGas); diff --git a/crates/precompile/src/kzg_point_evaluation.rs b/crates/precompile/src/kzg_point_evaluation.rs index a39b1724ef..5790186a99 100644 --- a/crates/precompile/src/kzg_point_evaluation.rs +++ b/crates/precompile/src/kzg_point_evaluation.rs @@ -6,12 +6,12 @@ use sha2::{Digest, Sha256}; pub const POINT_EVALUATION: PrecompileWithAddress = PrecompileWithAddress(ADDRESS, Precompile::Env(run)); -const ADDRESS: Address = crate::u64_to_address(0x0A); -const GAS_COST: u64 = 50_000; -const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; +pub const ADDRESS: Address = crate::u64_to_address(0x0A); +pub const GAS_COST: u64 = 50_000; +pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; /// `U256(FIELD_ELEMENTS_PER_BLOB).to_be_bytes() ++ BLS_MODULUS.to_bytes32()` -const RETURN_VALUE: &[u8; 64] = &hex!( +pub const RETURN_VALUE: &[u8; 64] = &hex!( "0000000000000000000000000000000000000000000000000000000000001000" "73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" ); @@ -56,14 +56,14 @@ pub fn run(input: &Bytes, gas_limit: u64, env: &Env) -> PrecompileResult { /// `VERSIONED_HASH_VERSION_KZG ++ sha256(commitment)[1..]` #[inline] -fn kzg_to_versioned_hash(commitment: &[u8]) -> [u8; 32] { +pub fn kzg_to_versioned_hash(commitment: &[u8]) -> [u8; 32] { let mut hash: [u8; 32] = Sha256::digest(commitment).into(); hash[0] = VERSIONED_HASH_VERSION_KZG; hash } #[inline] -fn verify_kzg_proof( +pub fn verify_kzg_proof( commitment: &Bytes48, z: &Bytes32, y: &Bytes32, @@ -75,20 +75,20 @@ fn verify_kzg_proof( #[inline] #[track_caller] -fn as_array(bytes: &[u8]) -> &[u8; N] { +pub fn as_array(bytes: &[u8]) -> &[u8; N] { bytes.try_into().expect("slice with incorrect length") } #[inline] #[track_caller] -fn as_bytes32(bytes: &[u8]) -> &Bytes32 { +pub fn as_bytes32(bytes: &[u8]) -> &Bytes32 { // SAFETY: `#[repr(C)] Bytes32([u8; 32])` unsafe { &*as_array::<32>(bytes).as_ptr().cast() } } #[inline] #[track_caller] -fn as_bytes48(bytes: &[u8]) -> &Bytes48 { +pub fn as_bytes48(bytes: &[u8]) -> &Bytes48 { // SAFETY: `#[repr(C)] Bytes48([u8; 48])` unsafe { &*as_array::<48>(bytes).as_ptr().cast() } } diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 53e45641ef..fd34bd6358 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -10,13 +10,13 @@ #[cfg(not(feature = "std"))] extern crate alloc as std; -mod blake2; +pub mod blake2; pub mod bn128; -mod hash; -mod identity; +pub mod hash; +pub mod identity; #[cfg(feature = "c-kzg")] pub mod kzg_point_evaluation; -mod modexp; +pub mod modexp; pub mod secp256k1; pub mod utilities; diff --git a/crates/precompile/src/modexp.rs b/crates/precompile/src/modexp.rs index 37981e321b..a55b445912 100644 --- a/crates/precompile/src/modexp.rs +++ b/crates/precompile/src/modexp.rs @@ -17,7 +17,7 @@ pub const BERLIN: PrecompileWithAddress = /// See: /// See: -fn byzantium_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { +pub fn byzantium_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { run_inner(input, gas_limit, 0, |a, b, c, d| { byzantium_gas_calc(a, b, c, d) }) @@ -29,7 +29,7 @@ pub fn berlin_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { }) } -fn calculate_iteration_count(exp_length: u64, exp_highp: &U256) -> u64 { +pub fn calculate_iteration_count(exp_length: u64, exp_highp: &U256) -> u64 { let mut iteration_count: u64 = 0; if exp_length <= 32 && *exp_highp == U256::ZERO { @@ -44,7 +44,7 @@ fn calculate_iteration_count(exp_length: u64, exp_highp: &U256) -> u64 { max(iteration_count, 1) } -fn run_inner(input: &[u8], gas_limit: u64, min_gas: u64, calc_gas: F) -> PrecompileResult +pub fn run_inner(input: &[u8], gas_limit: u64, min_gas: u64, calc_gas: F) -> PrecompileResult where F: FnOnce(u64, u64, u64, &U256) -> u64, { @@ -116,7 +116,7 @@ where Ok((gas_cost, left_pad_vec(&output, mod_len).into_owned().into())) } -fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &U256) -> u64 { +pub fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &U256) -> u64 { // output of this function is bounded by 2^128 fn mul_complexity(x: u64) -> U256 { if x <= 64 { @@ -140,7 +140,12 @@ fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &U25 // Calculate gas cost according to EIP 2565: // https://eips.ethereum.org/EIPS/eip-2565 -fn berlin_gas_calc(base_length: u64, exp_length: u64, mod_length: u64, exp_highp: &U256) -> u64 { +pub fn berlin_gas_calc( + base_length: u64, + exp_length: u64, + mod_length: u64, + exp_highp: &U256, +) -> u64 { fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> U256 { let max_length = max(base_length, mod_length); let mut words = max_length / 8;