diff --git a/crates/precompile/src/bls12_381/g1.rs b/crates/precompile/src/bls12_381/g1.rs index 27d3db0bdf..912141f7e0 100644 --- a/crates/precompile/src/bls12_381/g1.rs +++ b/crates/precompile/src/bls12_381/g1.rs @@ -1,9 +1,14 @@ -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 super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, 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 8607fa66eb..eb5228743a 100644 --- a/crates/precompile/src/bls12_381/g1_add.rs +++ b/crates/precompile/src/bls12_381/g1_add.rs @@ -1,7 +1,4 @@ -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 super::g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; use blst::{ @@ -11,7 +8,14 @@ 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); + 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; /// G1 addition call expects `256` bytes as an input that is interpreted as byte /// concatenation of two G1 points (`128` bytes each). @@ -19,13 +23,13 @@ pub const PRECOMPILE: PrecompileWithAddress = /// bytes). /// See also: pub(super) fn g1_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if G1_ADD_BASE_GAS_FEE > gas_limit { + if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } - if input.len() != G1_ADD_INPUT_LENGTH { + if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G1ADD input should be {G1_ADD_INPUT_LENGTH} bytes, was {}", + "G1ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() )) .into()); @@ -50,5 +54,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(G1_ADD_BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(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 ed390d7f69..18cf51a123 100644 --- a/crates/precompile/src/bls12_381/g1_msm.rs +++ b/crates/precompile/src/bls12_381/g1_msm.rs @@ -1,11 +1,7 @@ use super::{ - g1::{encode_g1_point, extract_g1_input}, + g1::{encode_g1_point, extract_g1_input, G1_INPUT_ITEM_LENGTH}, msm::msm_required_gas, - 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, + utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, }; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -14,7 +10,27 @@ 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); + 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, +]; /// Implements EIP-2537 G1MSM precompile. /// G1 multi-scalar-multiplication call expects `160*k` bytes as an input that is interpreted @@ -26,16 +42,16 @@ pub const PRECOMPILE: PrecompileWithAddress = /// See also: pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % G1_MSM_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_MSM_INPUT_LENGTH, input_len + INPUT_LENGTH, input_len )) .into()); } - let k = input_len / G1_MSM_INPUT_LENGTH; - let required_gas = msm_required_gas(k, &DISCOUNT_TABLE_G1_MSM, G1_MSM_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()); } @@ -43,7 +59,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 * G1_MSM_INPUT_LENGTH..i * G1_MSM_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. @@ -63,8 +79,8 @@ pub(super) fn g1_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { scalars.extend_from_slice( &extract_scalar_input( - &input[i * G1_MSM_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH - ..i * G1_MSM_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, ); diff --git a/crates/precompile/src/bls12_381/g2.rs b/crates/precompile/src/bls12_381/g2.rs index 38159cf073..5a75808b28 100644 --- a/crates/precompile/src/bls12_381/g2.rs +++ b/crates/precompile/src/bls12_381/g2.rs @@ -1,9 +1,14 @@ -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 super::utils::{fp_from_bendian, fp_to_bytes, remove_padding, FP_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 70355579be..142eb7e95d 100644 --- a/crates/precompile/src/bls12_381/g2_add.rs +++ b/crates/precompile/src/bls12_381/g2_add.rs @@ -1,7 +1,4 @@ -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 super::g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; use blst::{ @@ -11,7 +8,14 @@ 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); + 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; /// G2 addition call expects `512` bytes as an input that is interpreted as byte /// concatenation of two G2 points (`256` bytes each). @@ -20,13 +24,13 @@ pub const PRECOMPILE: PrecompileWithAddress = /// bytes). /// See also pub(super) fn g2_add(input: &Bytes, gas_limit: u64) -> PrecompileResult { - if G2_ADD_BASE_GAS_FEE > gas_limit { + if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } - if input.len() != G2_ADD_INPUT_LENGTH { + if input.len() != INPUT_LENGTH { return Err(PrecompileError::Other(format!( - "G2ADD input should be {G2_ADD_INPUT_LENGTH} bytes, was {}", + "G2ADD input should be {INPUT_LENGTH} bytes, was {}", input.len() )) .into()); @@ -51,5 +55,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(G2_ADD_BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(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 de5848b1bf..9bc916f975 100644 --- a/crates/precompile/src/bls12_381/g2_msm.rs +++ b/crates/precompile/src/bls12_381/g2_msm.rs @@ -1,11 +1,7 @@ use super::{ - g2::{encode_g2_point, extract_g2_input}, + g2::{encode_g2_point, extract_g2_input, G2_INPUT_ITEM_LENGTH}, msm::msm_required_gas, - 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, + utils::{extract_scalar_input, NBITS, SCALAR_LENGTH}, }; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -14,7 +10,27 @@ 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_ADD_ADDRESS), g2_msm); + 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, +]; /// Implements EIP-2537 G2MSM precompile. /// G2 multi-scalar-multiplication call expects `288*k` bytes as an input that is interpreted @@ -26,16 +42,16 @@ pub const PRECOMPILE: PrecompileWithAddress = /// See also: pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % G2_ADD_INPUT_LENGTH != 0 { + if input_len == 0 || input_len % INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( "G2MSM input length should be multiple of {}, was {}", - G2_ADD_INPUT_LENGTH, input_len + INPUT_LENGTH, input_len )) .into()); } - let k = input_len / G2_ADD_INPUT_LENGTH; - let required_gas = msm_required_gas(k, &DISCOUNT_TABLE_G2_MSM, G2_ADD_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()); } @@ -43,7 +59,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 * G2_ADD_INPUT_LENGTH..i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH]; + let slice = &input[i * INPUT_LENGTH..i * 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) { @@ -63,8 +79,8 @@ pub(super) fn g2_msm(input: &Bytes, gas_limit: u64) -> PrecompileResult { scalars.extend_from_slice( &extract_scalar_input( - &input[i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH - ..i * G2_ADD_INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + SCALAR_LENGTH], + &input[i * INPUT_LENGTH + G2_INPUT_ITEM_LENGTH + ..i * 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 926400329e..57bf76f034 100644 --- a/crates/precompile/src/bls12_381/map_fp2_to_g2.rs +++ b/crates/precompile/src/bls12_381/map_fp2_to_g2.rs @@ -1,6 +1,7 @@ -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 super::{ + g2::check_canonical_fp2, + g2::encode_g2_point, + utils::{remove_padding, PADDED_FP2_LENGTH, PADDED_FP_LENGTH}, }; use crate::{u64_to_address, PrecompileWithAddress}; use crate::{PrecompileError, PrecompileOutput, PrecompileResult}; @@ -9,14 +10,20 @@ 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(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; /// 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 MAP_FP2_TO_G2_BASE_GAS_FEE > gas_limit { + if BASE_GAS_FEE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -42,5 +49,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(MAP_FP2_TO_G2_BASE_GAS_FEE, out)) + Ok(PrecompileOutput::new(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 90f6f12ca0..13179cd590 100644 --- a/crates/precompile/src/bls12_381/map_fp_to_g1.rs +++ b/crates/precompile/src/bls12_381/map_fp_to_g1.rs @@ -1,8 +1,7 @@ use super::{ g1::encode_g1_point, - utils::{fp_from_bendian, remove_padding}, + utils::{fp_from_bendian, remove_padding, PADDED_FP_LENGTH}, }; -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}; @@ -10,13 +9,19 @@ 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(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; /// 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_FEE > gas_limit { + if MAP_FP_TO_G1_BASE > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -41,7 +46,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_GAS_FEE, out)) + Ok(PrecompileOutput::new(MAP_FP_TO_G1_BASE, out)) } #[cfg(test)] @@ -52,7 +57,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_GAS_FEE); + let fail = map_fp_to_g1(&input, MAP_FP_TO_G1_BASE); 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 b72fd90dcd..674135cd16 100644 --- a/crates/precompile/src/bls12_381/msm.rs +++ b/crates/precompile/src/bls12_381/msm.rs @@ -1,4 +1,5 @@ -use crate::bls12_381_const::MSM_MULTIPLIER; +/// Amount used to calculate the multi-scalar-multiplication discount +const MSM_MULTIPLIER: u64 = 1000; /// 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 1fa1f19fd3..bb85f0414b 100644 --- a/crates/precompile/src/bls12_381/pairing.rs +++ b/crates/precompile/src/bls12_381/pairing.rs @@ -1,7 +1,6 @@ -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 super::{ + g1::{extract_g1_input, G1_INPUT_ITEM_LENGTH}, + g2::{extract_g2_input, G2_INPUT_ITEM_LENGTH}, }; use crate::{ u64_to_address, PrecompileError, PrecompileOutput, PrecompileResult, PrecompileWithAddress, @@ -11,7 +10,16 @@ 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); + 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; /// 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 @@ -27,15 +35,15 @@ pub const PRECOMPILE: PrecompileWithAddress = /// See also: pub(super) fn pairing(input: &Bytes, gas_limit: u64) -> PrecompileResult { let input_len = input.len(); - if input_len == 0 || input_len % PAIRING_INPUT_LENGTH != 0 { + if input_len == 0 || input_len % INPUT_LENGTH != 0 { return Err(PrecompileError::Other(format!( - "Pairing input length should be multiple of {PAIRING_INPUT_LENGTH}, was {input_len}" + "Pairing input length should be multiple of {INPUT_LENGTH}, was {input_len}" )) .into()); } - let k = input_len / PAIRING_INPUT_LENGTH; - let required_gas: u64 = PAIRING_PAIRING_MULTIPLIER_BAS * k as u64 + PAIRING_PAIRING_OFFSET_BASE; + let k = input_len / INPUT_LENGTH; + let required_gas: u64 = PAIRING_MULTIPLIER_BASE * k as u64 + PAIRING_OFFSET_BASE; if required_gas > gas_limit { return Err(PrecompileError::OutOfGas.into()); } @@ -47,7 +55,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 * PAIRING_INPUT_LENGTH..i * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], + &input[i * INPUT_LENGTH..i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH], true, )?; @@ -55,8 +63,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 * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH - ..i * PAIRING_INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + G2_INPUT_ITEM_LENGTH], + &input[i * INPUT_LENGTH + G1_INPUT_ITEM_LENGTH + ..i * 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 b7d884ad54..2487a2a2d8 100644 --- a/crates/precompile/src/bls12_381/utils.rs +++ b/crates/precompile/src/bls12_381/utils.rs @@ -1,12 +1,28 @@ -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 deleted file mode 100644 index 9ed067cb3f..0000000000 --- a/crates/precompile/src/bls12_381_const.rs +++ /dev/null @@ -1,63 +0,0 @@ -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 66faee445c..91053c921d 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -11,7 +11,6 @@ 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;