Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Return Fatal error on bls precompiles if in no_std #2249

Merged
Merged
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
30 changes: 15 additions & 15 deletions crates/optimism/src/evm.rs
Original file line number Diff line number Diff line change
@@ -265,7 +265,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_g1_add_out_of_gas() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G1_ADD_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G1_ADD_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::G1_ADD_BASE_GAS_FEE - 1;
})
.modify_chain_chained(|l1_block| {
@@ -293,7 +293,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_g1_add_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G1_ADD_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G1_ADD_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::G1_ADD_BASE_GAS_FEE;
})
.modify_chain_chained(|l1_block| {
@@ -321,7 +321,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_g1_msm_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G1_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G1_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G1_MSM_INPUT_LENGTH - 1]);
})
.modify_chain_chained(|l1_block| {
@@ -355,7 +355,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G1_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G1_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G1_MSM_INPUT_LENGTH]);
tx.base.gas_limit = 23_560 //initial gas for input
+ gs1_msm_gas
@@ -392,7 +392,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G1_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G1_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G1_MSM_INPUT_LENGTH]);
tx.base.gas_limit = 23_560 //initial gas for input
+ gs1_msm_gas;
@@ -422,7 +422,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_g2_msm_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G2_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G2_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G2_MSM_INPUT_LENGTH - 1]);
})
.modify_chain_chained(|l1_block| {
@@ -456,7 +456,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G2_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G2_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G2_MSM_INPUT_LENGTH]);
tx.base.gas_limit = 25_608 //initial gas for input
+ gs2_msm_gas
@@ -493,7 +493,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G2_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G2_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G2_MSM_INPUT_LENGTH]);
tx.base.gas_limit = 25_608 //initial gas for input
+ gs2_msm_gas;
@@ -523,7 +523,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_pairing_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::G2_MSM_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::G2_MSM_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::G2_MSM_INPUT_LENGTH - 1]);
})
.modify_chain_chained(|l1_block| {
@@ -554,7 +554,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::PAIRING_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::PAIRING_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::PAIRING_INPUT_LENGTH]);
tx.base.gas_limit = 27_144 //initial gas for input
+ pairing_gas
@@ -588,7 +588,7 @@ mod tests {

let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::PAIRING_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::PAIRING_ADDRESS);
tx.base.data = Bytes::from([1; bls12_381_const::PAIRING_INPUT_LENGTH]);
tx.base.gas_limit = 27_144 //initial gas for input
+ pairing_gas;
@@ -618,7 +618,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_map_fp_to_g1_out_of_gas() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::MAP_FP_TO_G1_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::MAP_FP_TO_G1_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::MAP_FP_TO_G1_BASE_GAS_FEE - 1;
})
.modify_chain_chained(|l1_block| {
@@ -646,7 +646,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_map_fp_to_g1_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::MAP_FP_TO_G1_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::MAP_FP_TO_G1_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::MAP_FP_TO_G1_BASE_GAS_FEE;
})
.modify_chain_chained(|l1_block| {
@@ -674,7 +674,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_map_fp2_to_g2_out_of_gas() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::MAP_FP2_TO_G2_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::MAP_FP2_TO_G2_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::MAP_FP2_TO_G2_BASE_GAS_FEE - 1;
})
.modify_chain_chained(|l1_block| {
@@ -702,7 +702,7 @@ mod tests {
fn test_halted_tx_call_bls12_381_map_fp2_to_g2_input_wrong_size() {
let ctx = Context::op()
.modify_tx_chained(|tx| {
tx.base.kind = TxKind::Call(u64_to_address(bls12_381_const::MAP_FP2_TO_G2_ADDRESS));
tx.base.kind = TxKind::Call(bls12_381_const::MAP_FP2_TO_G2_ADDRESS);
tx.base.gas_limit = 21_000 + bls12_381_const::MAP_FP2_TO_G2_BASE_GAS_FEE;
})
.modify_chain_chained(|l1_block| {
5 changes: 2 additions & 3 deletions crates/precompile/src/bls12_381/g1_add.rs
Original file line number Diff line number Diff line change
@@ -3,13 +3,12 @@ use super::g1::{encode_g1_point, extract_g1_input_no_subgroup_check};
use crate::bls12_381_const::{
G1_ADD_ADDRESS, G1_ADD_BASE_GAS_FEE, G1_ADD_INPUT_LENGTH, PADDED_G1_LENGTH,
};
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1ADD precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(G1_ADD_ADDRESS), g1_add);
pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(G1_ADD_ADDRESS, g1_add);

/// G1 addition call expects `256` bytes as an input that is interpreted as byte
/// concatenation of two G1 points (`128` bytes each).
5 changes: 2 additions & 3 deletions crates/precompile/src/bls12_381/g1_msm.rs
Original file line number Diff line number Diff line change
@@ -8,14 +8,13 @@ use crate::bls12_381_const::{
PADDED_G1_LENGTH, SCALAR_LENGTH,
};
use crate::bls12_381_utils::msm_required_gas;
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use blst::blst_p1_affine;
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(G1_MSM_ADDRESS), g1_msm);
pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(G1_MSM_ADDRESS, g1_msm);

/// Implements EIP-2537 G1MSM precompile.
/// G1 multi-scalar-multiplication call expects `160*k` bytes as an input that is interpreted
5 changes: 2 additions & 3 deletions crates/precompile/src/bls12_381/g2_add.rs
Original file line number Diff line number Diff line change
@@ -3,13 +3,12 @@ use super::g2::{encode_g2_point, extract_g2_input_no_subgroup_check};
use crate::bls12_381_const::{
G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, PADDED_G2_LENGTH,
};
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2ADD precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(G2_ADD_ADDRESS), g2_add);
pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(G2_ADD_ADDRESS, g2_add);

/// G2 addition call expects `512` bytes as an input that is interpreted as byte
/// concatenation of two G2 points (`256` bytes each).
5 changes: 2 additions & 3 deletions crates/precompile/src/bls12_381/g2_msm.rs
Original file line number Diff line number Diff line change
@@ -8,14 +8,13 @@ use crate::bls12_381_const::{
PADDED_G2_LENGTH, SCALAR_LENGTH,
};
use crate::bls12_381_utils::msm_required_gas;
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use blst::blst_p2_affine;
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(G2_MSM_ADDRESS), g2_msm);
pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(G2_MSM_ADDRESS, g2_msm);

/// Implements EIP-2537 G2MSM precompile.
/// G2 multi-scalar-multiplication call expects `288*k` bytes as an input that is interpreted
4 changes: 2 additions & 2 deletions crates/precompile/src/bls12_381/map_fp2_to_g2.rs
Original file line number Diff line number Diff line change
@@ -5,13 +5,13 @@ use super::{
use crate::bls12_381_const::{
MAP_FP2_TO_G2_ADDRESS, MAP_FP2_TO_G2_BASE_GAS_FEE, PADDED_FP2_LENGTH, PADDED_FP_LENGTH,
};
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP2_TO_G2 precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(MAP_FP2_TO_G2_ADDRESS), map_fp2_to_g2);
PrecompileWithAddress(MAP_FP2_TO_G2_ADDRESS, map_fp2_to_g2);

/// Field-to-curve call expects 128 bytes as an input that is interpreted as
/// an element of Fp2. Output of this call is 256 bytes and is an encoded G2
4 changes: 2 additions & 2 deletions crates/precompile/src/bls12_381/map_fp_to_g1.rs
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@ use super::{
utils::{fp_from_bendian, remove_padding},
};
use crate::bls12_381_const::{MAP_FP_TO_G1_ADDRESS, MAP_FP_TO_G1_BASE_GAS_FEE, PADDED_FP_LENGTH};
use crate::{u64_to_address, PrecompileWithAddress};
use crate::PrecompileWithAddress;
use crate::{PrecompileError, PrecompileOutput, PrecompileResult};
use primitives::Bytes;

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_MAP_FP_TO_G1 precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(MAP_FP_TO_G1_ADDRESS), map_fp_to_g1);
PrecompileWithAddress(MAP_FP_TO_G1_ADDRESS, map_fp_to_g1);

/// Field-to-curve call expects 64 bytes as an input that is interpreted as an
/// element of Fp. Output of this call is 128 bytes and is an encoded G1 point.
7 changes: 2 additions & 5 deletions crates/precompile/src/bls12_381/pairing.rs
Original file line number Diff line number Diff line change
@@ -3,14 +3,11 @@ use crate::bls12_381_const::{
PADDED_G1_LENGTH, PADDED_G2_LENGTH, PAIRING_ADDRESS, PAIRING_INPUT_LENGTH,
PAIRING_MULTIPLIER_BASE, PAIRING_OFFSET_BASE,
};
use crate::{
u64_to_address, PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress,
};
use crate::{PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress};
use primitives::{Bytes, B256};

/// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_PAIRING precompile.
pub const PRECOMPILE: PrecompileWithAddress =
PrecompileWithAddress(u64_to_address(PAIRING_ADDRESS), pairing);
pub const PRECOMPILE: PrecompileWithAddress = PrecompileWithAddress(PAIRING_ADDRESS, pairing);

/// Pairing call expects 384*k (k being a positive integer) bytes as an inputs
/// that is interpreted as byte concatenation of k slices. Each slice has the
17 changes: 10 additions & 7 deletions crates/precompile/src/bls12_381_const.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::u64_to_address;
use primitives::Address;

// Constants specifying the precompile addresses for each precompile
// in EIP-2537
pub const G1_ADD_ADDRESS: u64 = 0x0b;
pub const G1_MSM_ADDRESS: u64 = 0x0c;
pub const G2_ADD_ADDRESS: u64 = 0x0d;
pub const G2_MSM_ADDRESS: u64 = 0x0e;
pub const PAIRING_ADDRESS: u64 = 0x0f;
pub const MAP_FP_TO_G1_ADDRESS: u64 = 0x10;
pub const MAP_FP2_TO_G2_ADDRESS: u64 = 0x11;
pub const G1_ADD_ADDRESS: Address = u64_to_address(0x0b);
pub const G1_MSM_ADDRESS: Address = u64_to_address(0x0c);
pub const G2_ADD_ADDRESS: Address = u64_to_address(0x0d);
pub const G2_MSM_ADDRESS: Address = u64_to_address(0x0e);
pub const PAIRING_ADDRESS: Address = u64_to_address(0x0f);
pub const MAP_FP_TO_G1_ADDRESS: Address = u64_to_address(0x10);
pub const MAP_FP2_TO_G2_ADDRESS: Address = u64_to_address(0x11);

/// G1_ADD_BASE_GAS_FEE specifies the amount of gas needed
/// to perform the G1_ADD precompile.
48 changes: 46 additions & 2 deletions crates/precompile/src/bls12_381_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use crate::bls12_381_const::MSM_MULTIPLIER;

use crate::bls12_381_const::{
G1_ADD_ADDRESS, G1_MSM_ADDRESS, G2_ADD_ADDRESS, G2_MSM_ADDRESS, MAP_FP2_TO_G2_ADDRESS,
MAP_FP_TO_G1_ADDRESS, MSM_MULTIPLIER, PAIRING_ADDRESS,
};
use crate::Vec;
use crate::{PrecompileError, PrecompileWithAddress};
/// Implements the gas schedule for G1/G2 Multiscalar-multiplication assuming 30
/// MGas/second, see also: <https://eips.ethereum.org/EIPS/eip-2537#g1g2-multiexponentiation>
#[inline]
@@ -13,3 +17,43 @@ pub fn msm_required_gas(k: usize, discount_table: &[u16], multiplication_cost: u

(k as u64 * discount * multiplication_cost) / MSM_MULTIPLIER
}

pub fn bls12_381_precompiles_not_supported() -> Vec<PrecompileWithAddress> {
vec![
PrecompileWithAddress(G1_ADD_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(G1_MSM_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(G2_ADD_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(G2_MSM_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(PAIRING_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(MAP_FP_TO_G1_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
PrecompileWithAddress(MAP_FP2_TO_G2_ADDRESS, |_, _| {
Err(PrecompileError::Fatal(
"no_std is not supported for BLS12-381 precompiles".into(),
))
}),
]
}
19 changes: 10 additions & 9 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
@@ -161,15 +161,16 @@ impl Precompiles {
pub fn prague() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let precompiles = Self::cancun().clone();

// Don't include BLS12-381 precompiles in no_std builds.
#[cfg(feature = "blst")]
let precompiles = {
let mut precompiles = precompiles;
precompiles.extend(bls12_381::precompiles());
precompiles
};
let mut precompiles = Self::cancun().clone();

cfg_if! {
if #[cfg(feature = "blst")] { // if blst is enabled
let bls = bls12_381::precompiles();
} else {
let bls = bls12_381_utils:: bls12_381_precompiles_not_supported();
}
}
precompiles.extend(bls);

Box::new(precompiles)
})