diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs index 912141f7e0..27d3db0bdf 100644 --- a/crates/precompile/src/bls12_381/g1.rs +++ b/crates/precompile/src/bls12_381/g1.rs @@ -1,14 +1,9 @@ -use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, PADDED_FP_LENGTH}; +use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding}; +use crate::bls12_381_const::{G1_INPUT_ITEM_LENGTH, G1_OUTPUT_LENGTH, PADDED_FP_LENGTH}; use crate::PrecompileError; use blst::{blst_p1_affine, blst_p1_affine_in_g1, blst_p1_affine_on_curve}; use primitives::Bytes; -/// Length of each of the elements in a g1 operation input. -pub(super) const G1_INPUT_ITEM_LENGTH: usize = 128; - -/// Output length of a g1 operation. -const G1_OUTPUT_LENGTH: usize = 128; - /// Encodes a G1 point in affine format into byte slice with padded elements. pub(super) fn encode_g1_point(input: *const blst_p1_affine) -> Bytes { let mut out = vec![0u8; G1_OUTPUT_LENGTH]; diff --git a/crates/precompile/src/bls12_381/g1_add.rs b/crates/precompile/src/bls12_381/g1_add.rs index eb5228743a..8607fa66eb 100644 --- a/crates/precompile/src/bls12_381/g1_add.rs +++ b/crates/precompile/src/bls12_381/g1_add.rs @@ -1,4 +1,7 @@ -use super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}; +use super::g1::{encode_g1_point, extract_g1_input}; +use crate::bls12_381_const::{ + G1_ADD_ADDRESS, G1_ADD_BASE_GAS_FEE, G1_ADD_INPUT_LENGTH, G1_INPUT_ITEM_LENGTH, +}; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; use blst::{ @@ -8,14 +11,7 @@ use primitives::Bytes; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1ADD precompile. pub const PRECOMPILE: PrecompileWithAddress = - PrecompileWithAddress(u64_to_address(ADDRESS), g1_add); -/// BLS12_G1ADD precompile address. -pub const ADDRESS: u64 = 0x0b; -/// Base gas fee for BLS12-381 g1_add operation. -const BASE_GAS_FEE: u64 = 375; - -/// Input length of g1_add operation. -const INPUT_LENGTH: usize = 256; + PrecompileWithAddress(u64_to_address(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). @@ -23,13 +19,13 @@ const INPUT_LENGTH: usize = 256; /// bytes). /// See also: pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if BASE_GAS_FEE > gas_limit { + if G1_ADD_BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } - if input.len() != INPUT_LENGTH { + if input.len() != G1_ADD_INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G1ADD input should be {INPUT_LENGTH} bytes, was {}", + "G1ADD input should be {G1_ADD_INPUT_LENGTH} bytes, was {}", input.len() )) .into()); @@ -54,5 +50,5 @@ pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); - Ok(PrecompileOutput::new(BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(G1_ADD_BASE_GAS_FEE, out)) } diff --git a/crates/precompile/src/bls12_381/g1_msm.rs b/crates/precompile/src/bls12_381/g1_msm.rs index 18cf51a123..ed390d7f69 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -1,7 +1,11 @@ use super::{ - g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, + g1::{encode_g1_point, extract_g1_input}, msm::msm_required_gas, - utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, + utils::extract_scalar_input, +}; +use crate::bls12_381_const::{ + DISCOUNT_TABLE_G1_MSM, G1_INPUT_ITEM_LENGTH, G1_MSM_ADDRESS, G1_MSM_BASE_GAS_FEE, + G1_MSM_INPUT_LENGTH, NBITS, SCALAR_LENGTH, }; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -10,27 +14,7 @@ use primitives::Bytes; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G1MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = - PrecompileWithAddress(u64_to_address(ADDRESS), g1_msm); - -/// BLS12_G1MSM precompile address. -pub const ADDRESS: u64 = 0x0c; - -/// Base gas fee for BLS12-381 g1_mul operation. -pub const BASE_GAS_FEE: u64 = 12000; - -/// Input length of g1_mul operation. -pub 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, -]; + PrecompileWithAddress(u64_to_address(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 @@ -42,16 +26,16 @@ pub static DISCOUNT_TABLE: [u16; 128] = [ /// See also: pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % INPUT_LENGTH != 0 { + if input_len == 0 || input_len % G1_MSM_INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( "G1MSM input length should be multiple of {}, was {}", - INPUT_LENGTH, input_len + G1_MSM_INPUT_LENGTH, input_len )) .into()); } - let k = input_len / INPUT_LENGTH; - let required_gas = msm_required_gas(k, &DISCOUNT_TABLE, BASE_GAS_FEE); + let k = input_len / G1_MSM_INPUT_LENGTH; + let required_gas = msm_required_gas(k, &DISCOUNT_TABLE_G1_MSM, G1_MSM_BASE_GAS_FEE); if required_gas > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -59,7 +43,7 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g1_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { - let slice = &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH]; + let slice = &input[i * G1_MSM_INPUT_LENGTH..i * G1_MSM_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. @@ -79,8 +63,8 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { scalars.extend_from_slice( &extract_scalar_input( - &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH - ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH], + &input[i * G1_MSM_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + ..i * G1_MSM_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + SCALAR_LENGTH], )? .b, ); diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs index 5a75808b28..38159cf073 100644 --- a/crates/precompile/src/bls12_381/g2.rs +++ b/crates/precompile/src/bls12_381/g2.rs @@ -1,14 +1,9 @@ -use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, FP_LENGTH, PADDED_FP_LENGTH}; +use super::utils::{fp_from_bendian, fp_to_bytes, remove_padding}; +use crate::bls12_381_const::{FP_LENGTH, G2_INPUT_ITEM_LENGTH, G2_OUTPUT_LENGTH, PADDED_FP_LENGTH}; use crate::PrecompileError; use blst::{blst_fp2, blst_p2_affine, blst_p2_affine_in_g2, blst_p2_affine_on_curve}; use primitives::Bytes; -/// Length of each of the elements in a g2 operation input. -pub(super) const G2_INPUT_ITEM_LENGTH: usize = 256; - -/// Output length of a g2 operation. -const G2_OUTPUT_LENGTH: usize = 256; - /// Encodes a G2 point in affine format into byte slice with padded elements. pub(super) fn encode_g2_point(input: &blst_p2_affine) -> Bytes { let mut out = vec![0u8; G2_OUTPUT_LENGTH]; diff --git a/crates/precompile/src/bls12_381/g2_add.rs b/crates/precompile/src/bls12_381/g2_add.rs index 142eb7e95d..70355579be 100644 --- a/crates/precompile/src/bls12_381/g2_add.rs +++ b/crates/precompile/src/bls12_381/g2_add.rs @@ -1,4 +1,7 @@ -use super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}; +use super::g2::{encode_g2_point, extract_g2_input}; +use crate::bls12_381_const::{ + G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, G2_INPUT_ITEM_LENGTH, +}; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; use blst::{ @@ -8,14 +11,7 @@ use primitives::Bytes; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2ADD precompile. pub const PRECOMPILE: PrecompileWithAddress = - PrecompileWithAddress(u64_to_address(ADDRESS), g2_add); -/// BLS12_G2ADD precompile address. -pub const ADDRESS: u64 = 0x0d; -/// Base gas fee for BLS12-381 g2_add operation. -const BASE_GAS_FEE: u64 = 600; - -/// Input length of g2_add operation. -const INPUT_LENGTH: usize = 512; + PrecompileWithAddress(u64_to_address(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). @@ -24,13 +20,13 @@ const INPUT_LENGTH: usize = 512; /// bytes). /// See also pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if BASE_GAS_FEE > gas_limit { + if G2_ADD_BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } - if input.len() != INPUT_LENGTH { + if input.len() != G2_ADD_INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G2ADD input should be {INPUT_LENGTH} bytes, was {}", + "G2ADD input should be {G2_ADD_INPUT_LENGTH} bytes, was {}", input.len() )) .into()); @@ -55,5 +51,5 @@ pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); - Ok(PrecompileOutput::new(BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(G2_ADD_BASE_GAS_FEE, out)) } diff --git a/crates/precompile/src/bls12_381/g2_msm.rs b/crates/precompile/src/bls12_381/g2_msm.rs index 9bc916f975..de5848b1bf 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -1,7 +1,11 @@ use super::{ - g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, + g2::{encode_g2_point, extract_g2_input}, msm::msm_required_gas, - utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, + utils::extract_scalar_input, +}; +use crate::bls12_381_const::{ + DISCOUNT_TABLE_G2_MSM, G2_ADD_ADDRESS, G2_ADD_BASE_GAS_FEE, G2_ADD_INPUT_LENGTH, + G2_INPUT_ITEM_LENGTH, NBITS, SCALAR_LENGTH, }; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -10,27 +14,7 @@ use primitives::Bytes; /// [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537#specification) BLS12_G2MSM precompile. pub const PRECOMPILE: PrecompileWithAddress = - PrecompileWithAddress(u64_to_address(ADDRESS), g2_msm); - -/// BLS12_G2MSM precompile address. -pub const ADDRESS: u64 = 0x0e; - -/// Base gas fee for BLS12-381 g2_mul operation. -pub const BASE_GAS_FEE: u64 = 22500; - -/// Input length of g2_mul operation. -pub const INPUT_LENGTH: usize = 288; - -// Discounts table for G2 MSM as a vector of pairs `[k, discount]`: -pub static DISCOUNT_TABLE: [u16; 128] = [ - 1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704, - 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632, - 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593, - 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568, - 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549, - 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534, - 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524, -]; + PrecompileWithAddress(u64_to_address(G2_ADD_ADDRESS), g2_msm); /// Implements EIP-2537 G2MSM precompile. /// G2 multi-scalar-multiplication call expects `288*k` bytes as an input that is interpreted @@ -42,16 +26,16 @@ pub static DISCOUNT_TABLE: [u16; 128] = [ /// See also: pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % INPUT_LENGTH != 0 { + if input_len == 0 || input_len % G2_ADD_INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( "G2MSM input length should be multiple of {}, was {}", - INPUT_LENGTH, input_len + G2_ADD_INPUT_LENGTH, input_len )) .into()); } - let k = input_len / INPUT_LENGTH; - let required_gas = msm_required_gas(k, &DISCOUNT_TABLE, BASE_GAS_FEE); + let k = input_len / G2_ADD_INPUT_LENGTH; + let required_gas = msm_required_gas(k, &DISCOUNT_TABLE_G2_MSM, G2_ADD_BASE_GAS_FEE); if required_gas > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -59,7 +43,7 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let mut g2_points: Vec = Vec::with_capacity(k); let mut scalars: Vec = Vec::with_capacity(k * SCALAR_LENGTH); for i in 0..k { - let slice = &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; + let slice = &input[i * G2_ADD_INPUT_LENGTH..i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; // BLST batch API for p2_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. if slice.iter().all(|i| *i == 0) { @@ -79,8 +63,8 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { scalars.extend_from_slice( &extract_scalar_input( - &input[i * INPUT_LENGTH + G2_INPUT_ITEM_LENGTH - ..i * INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + SCALAR_LENGTH], + &input[i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + ..i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + SCALAR_LENGTH], )? .b, ); diff --git a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs index 57bf76f034..926400329e 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -1,7 +1,6 @@ -use super::{ - g2::check_canonical_fp2, - g2::encode_g2_point, - utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, +use super::{g2::check_canonical_fp2, g2::encode_g2_point, utils::remove_padding}; +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::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -10,20 +9,14 @@ 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(ADDRESS), map_fp2_to_g2); - -/// BLS12_MAP_FP2_TO_G2 precompile address. -pub const ADDRESS: u64 = 0x11; - -/// Base gas fee for BLS12-381 map_fp2_to_g2 operation. -const BASE_GAS_FEE: u64 = 23800; + PrecompileWithAddress(u64_to_address(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 /// point. /// See also: pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if BASE_GAS_FEE > gas_limit { + if MAP_FP2_TO_G2_BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -49,5 +42,5 @@ pub(super) fn map_fp2_to_g2(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p2_to_affine(&mut p_aff, &p) }; let out = encode_g2_point(&p_aff); - Ok(PrecompileOutput::new(BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(MAP_FP2_TO_G2_BASE_GAS_FEE, out)) } diff --git a/crates/precompile/src/bls12_381/map_fp_to_g1.rs b/crates/precompile/src/bls12_381/map_fp_to_g1.rs index 13179cd590..90f6f12ca0 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -1,7 +1,8 @@ use super::{ g1::encode_g1_point, - utils::{fp_from_bendian, remove_padding, PADDED_FP_LENGTH}, + 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::{PrecompileError, PrecompileOutput, PrecompileResult}; use blst::{blst_map_to_g1, blst_p1, blst_p1_affine, blst_p1_to_affine}; @@ -9,19 +10,13 @@ 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(ADDRESS), map_fp_to_g1); - -/// BLS12_MAP_FP_TO_G1 precompile address. -pub const ADDRESS: u64 = 0x10; - -/// Base gas fee for BLS12-381 map_fp_to_g1 operation. -const MAP_FP_TO_G1_BASE: u64 = 5500; + PrecompileWithAddress(u64_to_address(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. /// See also: pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if MAP_FP_TO_G1_BASE > gas_limit { + if MAP_FP_TO_G1_BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -46,7 +41,7 @@ pub(super) fn map_fp_to_g1(input: &Bytes, gas_limit: u64) -> PrecompileResult { unsafe { blst_p1_to_affine(&mut p_aff, &p) }; let out = encode_g1_point(&p_aff); - Ok(PrecompileOutput::new(MAP_FP_TO_G1_BASE, out)) + Ok(PrecompileOutput::new(MAP_FP_TO_G1_BASE_GAS_FEE, out)) } #[cfg(test)] @@ -57,7 +52,7 @@ mod test { #[test] fn sanity_test() { let input = Bytes::from(hex!("000000000000000000000000000000006900000000000000636f6e7472616374595a603f343061cd305a03f40239f5ffff31818185c136bc2595f2aa18e08f17")); - let fail = map_fp_to_g1(&input, MAP_FP_TO_G1_BASE); + let fail = map_fp_to_g1(&input, MAP_FP_TO_G1_BASE_GAS_FEE); assert_eq!( fail, Err(PrecompileError::Other("non-canonical fp value".to_string()).into()) diff --git a/crates/precompile/src/bls12_381/msm.rs b/crates/precompile/src/bls12_381/msm.rs index 674135cd16..b72fd90dcd 100644 --- a/crates/precompile/src/bls12_381/msm.rs +++ b/crates/precompile/src/bls12_381/msm.rs @@ -1,5 +1,4 @@ -/// Amount used to calculate the multi-scalar-multiplication discount -const MSM_MULTIPLIER: u64 = 1000; +use crate::bls12_381_const::MSM_MULTIPLIER; /// Implements the gas schedule for G1/G2 Multiscalar-multiplication assuming 30 /// MGas/second, see also: diff --git a/crates/precompile/src/bls12_381/pairing.rs b/crates/precompile/src/bls12_381/pairing.rs index bb85f0414b..1fa1f19fd3 100644 --- a/crates/precompile/src/bls12_381/pairing.rs +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -1,6 +1,7 @@ -use super::{ - g1::{extract_g1_input, G1_INPUT_ITEM_LENGTH}, - g2::{extract_g2_input, G2_INPUT_ITEM_LENGTH}, +use super::{g1::extract_g1_input, g2::extract_g2_input}; +use crate::bls12_381_const::{ + G1_INPUT_ITEM_LENGTH, G2_INPUT_ITEM_LENGTH, PAIRING_ADDRESS, PAIRING_INPUT_LENGTH, + PAIRING_PAIRING_MULTIPLIER_BAS, PAIRING_PAIRING_OFFSET_BASE, }; use crate::{ u64_to_address, PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress, @@ -10,16 +11,7 @@ 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(ADDRESS), pairing); -/// BLS12_PAIRING precompile address. -pub const ADDRESS: u64 = 0x0f; - -/// Multiplier gas fee for BLS12-381 pairing operation. -const PAIRING_MULTIPLIER_BASE: u64 = 32600; -/// Offset gas fee for BLS12-381 pairing operation. -const PAIRING_OFFSET_BASE: u64 = 37700; -/// Input length of pairing operation. -const INPUT_LENGTH: usize = 384; + PrecompileWithAddress(u64_to_address(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 @@ -35,15 +27,15 @@ const INPUT_LENGTH: usize = 384; /// See also: pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % INPUT_LENGTH != 0 { + if input_len == 0 || input_len % PAIRING_INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( - "Pairing input length should be multiple of {INPUT_LENGTH}, was {input_len}" + "Pairing input length should be multiple of {PAIRING_INPUT_LENGTH}, was {input_len}" )) .into()); } - let k = input_len / INPUT_LENGTH; - let required_gas: u64 = PAIRING_MULTIPLIER_BASE * k as u64 + PAIRING_OFFSET_BASE; + let k = input_len / PAIRING_INPUT_LENGTH; + let required_gas: u64 = PAIRING_PAIRING_MULTIPLIER_BAS * k as u64 + PAIRING_PAIRING_OFFSET_BASE; if required_gas > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -55,7 +47,7 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { // // So we set the subgroup_check flag to `true` let p1_aff = &extract_g1_input( - &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], + &input[i * PAIRING_INPUT_LENGTH..i * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], true, )?; @@ -63,8 +55,8 @@ pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { // // So we set the subgroup_check flag to `true` let p2_aff = &extract_g2_input( - &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH - ..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], + &input[i * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + ..i * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], true, )?; diff --git a/crates/precompile/src/bls12_381/utils.rs b/crates/precompile/src/bls12_381/utils.rs index 2487a2a2d8..b7d884ad54 100644 --- a/crates/precompile/src/bls12_381/utils.rs +++ b/crates/precompile/src/bls12_381/utils.rs @@ -1,28 +1,12 @@ +use crate::bls12_381_const::{ + FP_LENGTH, MODULUS_REPR, PADDED_FP_LENGTH, PADDING_LENGTH, SCALAR_LENGTH, +}; use crate::PrecompileError; use blst::{ blst_bendian_from_fp, blst_fp, blst_fp_from_bendian, blst_scalar, blst_scalar_from_bendian, }; use core::cmp::Ordering; -/// Number of bits used in the BLS12-381 curve finite field elements. -pub(super) const NBITS: usize = 256; -/// Finite field element input length. -pub(super) const FP_LENGTH: usize = 48; -/// Finite field element padded input length. -pub(super) const PADDED_FP_LENGTH: usize = 64; -/// Quadratic extension of finite field element input length. -pub(super) const PADDED_FP2_LENGTH: usize = 128; -/// Input elements padding length. -pub(super) const PADDING_LENGTH: usize = 16; -/// Scalar length. -pub(super) const SCALAR_LENGTH: usize = 32; -// Big-endian non-Montgomery form. -pub(super) const MODULUS_REPR: [u8; 48] = [ - 0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7, - 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0, 0xf6, 0xb0, 0xf6, 0x24, - 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab, -]; - /// Encodes a single finite field element into byte slice with padding. pub(super) fn fp_to_bytes(out: &mut [u8], input: *const blst_fp) { if out.len() != PADDED_FP_LENGTH { diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs new file mode 100644 index 0000000000..9ed067cb3f --- /dev/null +++ b/crates/precompile/src/bls12_381_const.rs @@ -0,0 +1,63 @@ +pub const G1_ADD_ADDRESS: u64 = 0x0b; +pub const G1_ADD_BASE_GAS_FEE: u64 = 375; +pub const G1_ADD_INPUT_LENGTH: usize = 256; +pub const G1_MSM_ADDRESS: u64 = 0x0c; +pub const G1_MSM_BASE_GAS_FEE: u64 = 1200; +pub const G1_MSM_INPUT_LENGTH: usize = 160; +pub const G1_OUTPUT_LENGTH: usize = 128; +pub const G1_INPUT_ITEM_LENGTH: usize = 128; +pub const G2_ADD_ADDRESS: u64 = 0x0d; +pub const G2_ADD_BASE_GAS_FEE: u64 = 600; +pub const G2_ADD_INPUT_LENGTH: usize = 512; +pub const G2_MSM_ADDRESS: u64 = 0x0e; +pub const G2_MSM_BASE_GAS_FEE: u64 = 22500; +pub const G2_MSM_INPUT_LENGTH: usize = 288; +pub const G2_OUTPUT_LENGTH: usize = 256; +pub const G2_INPUT_ITEM_LENGTH: usize = 256; +pub const PAIRING_ADDRESS: u64 = 0x0f; +pub const PAIRING_PAIRING_MULTIPLIER_BAS: u64 = 32600; +pub const PAIRING_PAIRING_OFFSET_BASE: u64 = 37700; +pub const PAIRING_INPUT_LENGTH: usize = 384; +pub const MAP_FP_TO_G1_ADDRESS: u64 = 0x10; +pub const MAP_FP_TO_G1_BASE_GAS_FEE: u64 = 5500; +pub const MAP_FP2_TO_G2_ADDRESS: u64 = 0x11; +pub const MAP_FP2_TO_G2_BASE_GAS_FEE: u64 = 0x23800; +pub const MSM_MULTIPLIER: u64 = 1000; +/// Number of bits used in the BLS12-381 curve finite field elements. +pub const NBITS: usize = 256; +/// Finite field element input length. +pub const FP_LENGTH: usize = 48; +/// Finite field element padded input length. +pub const PADDED_FP_LENGTH: usize = 64; +/// Quadratic extension of finite field element input length. +pub const PADDED_FP2_LENGTH: usize = 128; +/// Input elements padding length. +pub const PADDING_LENGTH: usize = 16; +/// Scalar length. +pub const SCALAR_LENGTH: usize = 32; +// Big-endian non-Montgomery form. +pub const MODULUS_REPR: [u8; 48] = [ + 0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7, + 0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0, 0xf6, 0xb0, 0xf6, 0x24, + 0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab, +]; +/// Discounts table for G1 MSM as a vector of pairs `[k, discount]`. +pub static DISCOUNT_TABLE_G1_MSM: [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, +]; +// Discounts table for G2 MSM as a vector of pairs `[k, discount]`: +pub static DISCOUNT_TABLE_G2_MSM: [u16; 128] = [ + 1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704, + 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632, + 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593, + 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568, + 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549, + 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534, + 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524, +]; diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 91053c921d..66faee445c 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -11,6 +11,7 @@ extern crate alloc as std; pub mod blake2; #[cfg(feature = "blst")] pub mod bls12_381; +pub mod bls12_381_const; pub mod bn128; pub mod hash; pub mod identity;