Skip to content

Commit

Permalink
feat: make all precompiles public (#1213)
Browse files Browse the repository at this point in the history
* feat: make all precompiles public

* make inner function pub
  • Loading branch information
rakita authored Mar 19, 2024
1 parent 713ed4f commit 29c587b
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 38 deletions.
10 changes: 5 additions & 5 deletions crates/precompile/src/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub const FUN: PrecompileWithAddress =
/// reference: <https://eips.ethereum.org/EIPS/eip-152>
/// 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 {
Expand Down Expand Up @@ -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: <https://datatracker.ietf.org/doc/html/rfc7693#section-2.7>
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],
Expand All @@ -70,7 +70,7 @@ mod algo {
];

/// got IV from: <https://en.wikipedia.org/wiki/BLAKE_(hash_function)>
const IV: [u64; 8] = [
pub const IV: [u64; 8] = [
0x6a09e667f3bcc908,
0xbb67ae8584caa73b,
0x3c6ef372fe94f82b,
Expand All @@ -84,7 +84,7 @@ mod algo {
#[inline(always)]
#[allow(clippy::many_single_char_names)]
/// G function: <https://tools.ietf.org/html/rfc7693#section-3.1>
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]);
Expand Down
20 changes: 10 additions & 10 deletions crates/precompile/src/bn128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -92,21 +92,21 @@ 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.
///
/// # Panics
///
/// Panics if the input is not at least 32 bytes long.
#[inline]
fn read_fq(input: &[u8]) -> Result<Fq, Error> {
pub fn read_fq(input: &[u8]) -> Result<Fq, Error> {
Fq::from_slice(&input[..32]).map_err(|_| Error::Bn128FieldPointNotAMember)
}

Expand All @@ -116,14 +116,14 @@ fn read_fq(input: &[u8]) -> Result<Fq, Error> {
///
/// Panics if the input is not at least 64 bytes long.
#[inline]
fn read_point(input: &[u8]) -> Result<G1, Error> {
pub fn read_point(input: &[u8]) -> Result<G1, Error> {
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<G1, Error> {
pub fn new_g1_point(px: Fq, py: Fq) -> Result<G1, Error> {
if px == Fq::zero() && py == Fq::zero() {
Ok(G1::zero())
} else {
Expand All @@ -133,7 +133,7 @@ fn new_g1_point(px: Fq, py: Fq) -> Result<G1, Error> {
}
}

fn run_add(input: &[u8]) -> Result<Bytes, Error> {
pub fn run_add(input: &[u8]) -> Result<Bytes, Error> {
let input = right_pad::<ADD_INPUT_LEN>(input);

let p1 = read_point(&input[..64])?;
Expand All @@ -154,7 +154,7 @@ fn run_add(input: &[u8]) -> Result<Bytes, Error> {
Ok(output.into())
}

fn run_mul(input: &[u8]) -> Result<Bytes, Error> {
pub fn run_mul(input: &[u8]) -> Result<Bytes, Error> {
let input = right_pad::<MUL_INPUT_LEN>(input);

let p = read_point(&input[..64])?;
Expand Down
4 changes: 2 additions & 2 deletions crates/precompile/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress(
/// See: <https://ethereum.github.io/yellowpaper/paper.pdf>
/// See: <https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions>
/// See: <https://etherscan.io/address/0000000000000000000000000000000000000002>
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)
Expand All @@ -27,7 +27,7 @@ fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult {
/// See: <https://ethereum.github.io/yellowpaper/paper.pdf>
/// See: <https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions>
/// See: <https://etherscan.io/address/0000000000000000000000000000000000000003>
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)
Expand Down
6 changes: 3 additions & 3 deletions crates/precompile/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: <https://ethereum.github.io/yellowpaper/paper.pdf>
/// See: <https://etherscan.io/address/0000000000000000000000000000000000000004>
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);
Expand Down
18 changes: 9 additions & 9 deletions crates/precompile/src/kzg_point_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
);
Expand Down Expand Up @@ -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,
Expand All @@ -75,20 +75,20 @@ fn verify_kzg_proof(

#[inline]
#[track_caller]
fn as_array<const N: usize>(bytes: &[u8]) -> &[u8; N] {
pub fn as_array<const N: usize>(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() }
}
Expand Down
8 changes: 4 additions & 4 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
15 changes: 10 additions & 5 deletions crates/precompile/src/modexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub const BERLIN: PrecompileWithAddress =

/// See: <https://eips.ethereum.org/EIPS/eip-198>
/// See: <https://etherscan.io/address/0000000000000000000000000000000000000005>
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)
})
Expand All @@ -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 {
Expand All @@ -44,7 +44,7 @@ fn calculate_iteration_count(exp_length: u64, exp_highp: &U256) -> u64 {
max(iteration_count, 1)
}

fn run_inner<F>(input: &[u8], gas_limit: u64, min_gas: u64, calc_gas: F) -> PrecompileResult
pub fn run_inner<F>(input: &[u8], gas_limit: u64, min_gas: u64, calc_gas: F) -> PrecompileResult
where
F: FnOnce(u64, u64, u64, &U256) -> u64,
{
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand Down

0 comments on commit 29c587b

Please sign in to comment.