Skip to content

Commit

Permalink
feat: blst reprice, remove g1/g2 mul, eest test bump (#1951)
Browse files Browse the repository at this point in the history
* chore: eip7702 chainid u256 change

* feat: remove g1/g2 mul, shift address

* bump tests

* rm test with non empty storage

* no std

* rm obsolete tests
  • Loading branch information
rakita authored Dec 25, 2024
1 parent 0c69ccd commit 66ee506
Show file tree
Hide file tree
Showing 268 changed files with 366,266 additions and 160,829 deletions.
4 changes: 2 additions & 2 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use revm::{
interpreter::analysis::to_analysed,
primitives::{
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult,
SpecId, TxKind, B256, TARGET_BLOB_GAS_PER_BLOCK,
SpecId, TxKind, B256,
},
Evm, State,
};
Expand Down Expand Up @@ -331,7 +331,7 @@ pub fn execute_test_suite(
unit.env
.parent_target_blobs_per_block
.map(|i| i.to())
.unwrap_or(TARGET_BLOB_GAS_PER_BLOCK),
.unwrap_or(3),
),
spec_id.is_enabled_in(SpecId::PRAGUE),
);
Expand Down
126 changes: 0 additions & 126 deletions crates/precompile/src/bls12_381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use crate::PrecompileWithAddress;
mod g1;
pub mod g1_add;
pub mod g1_msm;
pub mod g1_mul;
mod g2;
pub mod g2_add;
pub mod g2_msm;
pub mod g2_mul;
pub mod map_fp2_to_g2;
pub mod map_fp_to_g1;
mod msm;
Expand All @@ -18,136 +16,12 @@ mod utils;
pub fn precompiles() -> impl Iterator<Item = PrecompileWithAddress> {
[
g1_add::PRECOMPILE,
g1_mul::PRECOMPILE,
g1_msm::PRECOMPILE,
g2_add::PRECOMPILE,
g2_mul::PRECOMPILE,
g2_msm::PRECOMPILE,
pairing::PRECOMPILE,
map_fp_to_g1::PRECOMPILE,
map_fp2_to_g2::PRECOMPILE,
]
.into_iter()
}

#[cfg(test)]
mod test {
use super::g1_add;
use super::g1_msm;
use super::g1_mul;
use super::g2_add;
use super::g2_msm;
use super::g2_mul;
use super::map_fp2_to_g2;
use super::map_fp_to_g1;
use super::msm::msm_required_gas;
use super::pairing;
use eyre::Result;
use revm_primitives::{hex::FromHex, Bytes, PrecompileResult};
use rstest::rstest;
use serde_derive::{Deserialize, Serialize};
use std::{fs, path::Path};

/// Test vector structure for BLS12-381 precompile tests.
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct TestVector {
input: String,
expected: Option<String>,
name: String,
gas: Option<u64>,
expected_error: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
struct TestVectors(Vec<TestVector>);

fn load_test_vectors<P: AsRef<Path>>(path: P) -> Result<TestVectors> {
let file_contents = fs::read_to_string(path)?;
Ok(serde_json::from_str(&file_contents)?)
}

#[rstest]
#[case::fail_g1_add(g1_add::g1_add, "fail-add_G1_bls.json")]
#[case::fail_g1_mul(g1_mul::g1_mul, "fail-mul_G1_bls.json")]
#[case::fail_g1_msm(g1_msm::g1_msm, "fail-multiexp_G1_bls.json")]
#[case::fail_g2_add(g2_add::g2_add, "fail-add_G2_bls.json")]
#[case::fail_g2_mul(g2_mul::g2_mul, "fail-mul_G2_bls.json")]
#[case::fail_g2_msm(g2_msm::g2_msm, "fail-multiexp_G2_bls.json")]
#[case::fail_pairing(pairing::pairing, "fail-pairing_check_bls.json")]
#[case::fail_map_fp_to_g1(map_fp_to_g1::map_fp_to_g1, "fail-map_fp_to_G1_bls.json")]
#[case::fail_map_fp2_to_g2(map_fp2_to_g2::map_fp2_to_g2, "fail-map_fp2_to_G2_bls.json")]
#[case::g1_add(g1_add::g1_add, "add_G1_bls.json")]
#[case::g1_mul(g1_mul::g1_mul, "mul_G1_bls.json")]
#[case::g1_msm(g1_msm::g1_msm, "multiexp_G1_bls.json")]
#[case::g2_add(g2_add::g2_add, "add_G2_bls.json")]
#[case::g2_mul(g2_mul::g2_mul, "mul_G2_bls.json")]
#[case::g2_msm(g2_msm::g2_msm, "multiexp_G2_bls.json")]
#[case::pairing(pairing::pairing, "pairing_check_bls.json")]
#[case::map_fp_to_g1(map_fp_to_g1::map_fp_to_g1, "map_fp_to_G1_bls.json")]
#[case::map_fp2_to_g2(map_fp2_to_g2::map_fp2_to_g2, "map_fp2_to_G2_bls.json")]
fn test_bls(
#[case] precompile: fn(input: &Bytes, gas_limit: u64) -> PrecompileResult,
#[case] file_name: &str,
) {
let test_vectors = load_test_vectors(format!("test-vectors/{file_name}"))
.unwrap_or_else(|e| panic!("Failed to load test vectors from {file_name}: {e}"));

for vector in test_vectors.0 {
let test_name = format!("{file_name}/{}", vector.name);
let input = Bytes::from_hex(vector.input.clone()).unwrap_or_else(|e| {
panic!(
"could not deserialize input {} as hex in {test_name}: {e}",
&vector.input
)
});
let target_gas: u64 = 30_000_000;
let res = precompile(&input, target_gas);
if let Some(expected_error) = vector.expected_error {
assert!(res.is_err(), "expected error {expected_error} didn't happen in {test_name}, got result {res:?}");
} else {
let Some(gas) = vector.gas else {
panic!("gas is missing in {test_name}");
};
let outcome = res.unwrap_or_else(|e: revm_primitives::PrecompileErrors| {
panic!("precompile call failed for {test_name}: {e}")
});
assert_eq!(
gas, outcome.gas_used,
"expected gas: {}, actual gas: {} in {test_name}",
gas, outcome.gas_used
);
let Some(expected) = vector.expected else {
panic!("expected output is missing in {test_name}");
};
let expected_output = Bytes::from_hex(expected).unwrap();
assert_eq!(
expected_output, outcome.bytes,
"expected output: {expected_output}, actual output: {:?} in {test_name}",
outcome.bytes
);
}
}
}

#[rstest]
#[case::g1_empty(0, g1_mul::BASE_GAS_FEE, 0)]
#[case::g1_one_item(160, g1_mul::BASE_GAS_FEE, 14400)]
#[case::g1_two_items(320, g1_mul::BASE_GAS_FEE, 21312)]
#[case::g1_ten_items(1600, g1_mul::BASE_GAS_FEE, 50760)]
#[case::g1_sixty_four_items(10240, g1_mul::BASE_GAS_FEE, 170496)]
#[case::g1_one_hundred_twenty_eight_items(20480, g1_mul::BASE_GAS_FEE, 267264)]
#[case::g1_one_hundred_twenty_nine_items(20640, g1_mul::BASE_GAS_FEE, 269352)]
#[case::g1_two_hundred_fifty_six_items(40960, g1_mul::BASE_GAS_FEE, 534528)]
fn test_g1_msm_required_gas(
#[case] input_len: usize,
#[case] multiplication_cost: u64,
#[case] expected_output: u64,
) {
let k = input_len / g1_mul::INPUT_LENGTH;

let actual_output = msm_required_gas(k, multiplication_cost);

assert_eq!(expected_output, actual_output);
}
}
2 changes: 1 addition & 1 deletion crates/precompile/src/bls12_381/g1_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub const PRECOMPILE: PrecompileWithAddress =
/// BLS12_G1ADD precompile address.
pub const ADDRESS: u64 = 0x0b;
/// Base gas fee for BLS12-381 g1_add operation.
const BASE_GAS_FEE: u64 = 500;
const BASE_GAS_FEE: u64 = 375;

/// Input length of g1_add operation.
const INPUT_LENGTH: usize = 256;
Expand Down
36 changes: 25 additions & 11 deletions crates/precompile/src/bls12_381/g1_msm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{
g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH},
g1_mul,
msm::msm_required_gas,
utils::{extract_scalar_input, NBITS, SCALAR_LENGTH},
};
Expand All @@ -13,7 +12,24 @@ pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g1_msm));

/// BLS12_G1MSM precompile address.
pub const ADDRESS: u64 = 0x0d;
pub const ADDRESS: u64 = 0x0c;

/// Base gas fee for BLS12-381 g1_mul operation.
pub(super) const BASE_GAS_FEE: u64 = 12000;

/// Input length of g1_mul operation.
pub(super) const INPUT_LENGTH: usize = 160;

/// Discounts table for G1 MSM as a vector of pairs `[k, discount]`.
pub static DISCOUNT_TABLE: [u16; 128] = [
1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673, 669, 665,
661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621, 619, 617, 615,
613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591, 589, 588, 586, 585,
584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568, 567, 566, 565, 564, 563,
562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 547, 546, 545,
544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535, 534, 533, 532, 532, 531, 530, 529,
528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521, 520, 520, 519,
];

/// Implements EIP-2537 G1MSM precompile.
/// G1 multi-scalar-multiplication call expects `160*k` bytes as an input that is interpreted
Expand All @@ -25,26 +41,24 @@ pub const ADDRESS: u64 = 0x0d;
/// See also: <https://eips.ethereum.org/EIPS/eip-2537#abi-for-g1-multiexponentiation>
pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {
let input_len = input.len();
if input_len == 0 || input_len % g1_mul::INPUT_LENGTH != 0 {
if input_len == 0 || input_len % INPUT_LENGTH != 0 {
return Err(PrecompileError::Other(format!(
"G1MSM input length should be multiple of {}, was {}",
g1_mul::INPUT_LENGTH,
input_len
INPUT_LENGTH, input_len
))
.into());
}

let k = input_len / g1_mul::INPUT_LENGTH;
let required_gas = msm_required_gas(k, g1_mul::BASE_GAS_FEE);
let k = input_len / INPUT_LENGTH;
let required_gas = msm_required_gas(k, &DISCOUNT_TABLE, BASE_GAS_FEE);
if required_gas > gas_limit {
return Err(PrecompileError::OutOfGas.into());
}

let mut g1_points: Vec<blst_p1> = Vec::with_capacity(k);
let mut scalars: Vec<u8> = Vec::with_capacity(k * SCALAR_LENGTH);
for i in 0..k {
let slice =
&input[i * g1_mul::INPUT_LENGTH..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH];
let slice = &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH];

// BLST batch API for p1_affines blows up when you pass it a point at infinity, so we must
// filter points at infinity (and their corresponding scalars) from the input.
Expand All @@ -64,8 +78,8 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult {

scalars.extend_from_slice(
&extract_scalar_input(
&input[i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH
..i * g1_mul::INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH],
&input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH
..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH],
)?
.b,
);
Expand Down
60 changes: 0 additions & 60 deletions crates/precompile/src/bls12_381/g1_mul.rs

This file was deleted.

4 changes: 2 additions & 2 deletions crates/precompile/src/bls12_381/g2_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use revm_primitives::{Bytes, Precompile, PrecompileError, PrecompileOutput, Prec
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(ADDRESS), Precompile::Standard(g2_add));
/// BLS12_G2ADD precompile address.
pub const ADDRESS: u64 = 0x0e;
pub const ADDRESS: u64 = 0x0d;
/// Base gas fee for BLS12-381 g2_add operation.
const BASE_GAS_FEE: u64 = 800;
const BASE_GAS_FEE: u64 = 600;

/// Input length of g2_add operation.
const INPUT_LENGTH: usize = 512;
Expand Down
Loading

0 comments on commit 66ee506

Please sign in to comment.