From 2bb48d812f5bfe71a1a7169a7578769e826e4a6d Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Sun, 16 Mar 2025 18:33:52 +0000 Subject: [PATCH 1/5] initial commit --- crates/precompile/src/bls12_381_const.rs | 149 ++++++++++++++++++----- 1 file changed, 117 insertions(+), 32 deletions(-) diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs index 4ac094a02c..015c9d86f8 100644 --- a/crates/precompile/src/bls12_381_const.rs +++ b/crates/precompile/src/bls12_381_const.rs @@ -1,46 +1,23 @@ +// Constants related to the bls12-381 gas schedule and precompile address 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 = 12000; -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 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 = 23800; 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_BASE: u64 = 32600; +// TODO: Why does this have PAIRING twice? 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 = 23800; 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, -]; +// TODO: Why does this have PAIRING twice? +pub const PAIRING_PAIRING_MULTIPLIER_BASE: u64 = 32600; + /// 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, @@ -61,3 +38,111 @@ pub static DISCOUNT_TABLE_G2_MSM: [u16; 128] = [ 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, ]; + +// Constants related to the bls12-381 precompile inputs and outputs + +/// FP_LENGTH specifies the number of bytes needed to represent an +/// Fp element. This is an element in the base field of BLS12-381. +/// +/// Note: The base field is used to define G1 and G2 elements. +pub const FP_LENGTH: usize = 48; +/// PADDED_FP_LENGTH specifies the number of bytes that the EVM will use +/// to represent an Fp element according to EIP-2537. +/// +/// Note: We only need FP_LENGTH number of bytes to represent it, +/// but we pad the byte representation to be 32 byte aligned as specified in EIP 2537. +pub const PADDED_FP_LENGTH: usize = 64; + +/// G1_LENGTH specifies the number of bytes needed to represent a G1 element. +/// +/// Note: A G1 element contains 2 Fp elements. +pub const G1_LENGTH: usize = 2 * FP_LENGTH; +/// PADDED_G1_LENGTH specifies the number of bytes that the EVM will use to represent +/// a G1 element according to padding rules specified in EIP-2537. +const PADDED_G1_LENGTH: usize = 2 * PADDED_FP_LENGTH; + +/// FP2_LENGTH specifies the number of bytes needed to represent a +/// Fp^2 element. +/// +/// Note: This is the quadratic extension of Fp, and by definition +/// means we need 2 Fp elements. +const FP2_LENGTH: usize = 2 * FP_LENGTH; +/// PADDED_FP2_LENGTH specifies the number of bytes that the EVM will use to represent +/// a Fp^2 element according to the padding rules specified in EIP-2537. +pub const PADDED_FP2_LENGTH: usize = 2 * PADDED_FP_LENGTH; + +/// SCALAR_LENGTH specifies the number of bytes needed to represent an Fr element. +/// This is an element in the scalar field of BLS12-381. +/// +/// Note: Since it is already 32 byte aligned, there is no padded version of this constant. +/// TODO: Maybe change all _LENGTH to _LENGTH_BYTES and then NBITS to _LENGTH_BITS +pub const SCALAR_LENGTH: usize = 32; +/// NBITS specifies the number of bits needed to represent an Fr element. +/// This is an element in the scalar field of BLS12-381. +/// TODO: We can likely remove this and just check what the min(scalar.length()) is before doing an MSM +pub const NBITS: usize = 256; + +/// G1_ADD_INPUT_LENGTH specifies the number of bytes that the input to G1ADD +/// must use. +/// +/// Note: The input to the G1 addition precompile is 2 G1 elements. +pub const G1_ADD_INPUT_LENGTH: usize = 2 * PADDED_G1_LENGTH; +/// G1_OUTPUT_LENGTH specifies the number of bytes that the EVM will use +/// to represent a G1 element. +// TODO: can we remove this since it is just `PADDED_G1_LENGTH`? +pub const G1_OUTPUT_LENGTH: usize = PADDED_G1_LENGTH; +/// G1_MSM_INPUT_LENGTH specifies the number of bytes that each MSM input pair should have. +/// +/// Note: An MSM pair is a G1 element and a scalar. The input to the MSM precompile will have `n` +/// of these pairs. +pub const G1_MSM_INPUT_LENGTH: usize = PADDED_G1_LENGTH + SCALAR_LENGTH; +/// G1_INPUT_ITEM_LENGTH specifies the number of bytes that the EVM will use to represent +/// a G1 element. +// TODO: can we remove this since it is just `PADDED_G1_LENGTH`? +pub const G1_INPUT_ITEM_LENGTH: usize = PADDED_G1_LENGTH; + +/// G2_LENGTH specifies the number of bytes needed to represent a G2 element. +/// +/// Note: A G2 element can be represented using 2 Fp^2 elements. +const G2_LENGTH: usize = 2 * FP2_LENGTH; +/// PADDED_G2_LENGTH specifies the number of bytes that the EVM will use to represent +/// a G2 element. +const PADDED_G2_LENGTH: usize = 2 * PADDED_FP2_LENGTH; + +/// G2_ADD_INPUT_LENGTH specifies the number of bytes that the input to G2ADD +/// must occupy. +/// +/// Note: The input to the G2 addition precompile is 2 G2 elements. +pub const G2_ADD_INPUT_LENGTH: usize = 2 * PADDED_G2_LENGTH; +/// G2_MSM_INPUT_LENGTH specifies the number of bytes that each MSM input pair should have. +/// +/// Note: An MSM pair is a G2 element and a scalar. The input to the MSM will have `n` +/// of these pairs. +pub const G2_MSM_INPUT_LENGTH: usize = PADDED_G2_LENGTH + SCALAR_LENGTH; +/// G2_OUTPUT_LENGTH specifies the number of bytes that the EVM will use +/// to represent a G2 element. +// TODO: can we remove this since it is just `PADDED_G2_LENGTH` +pub const G2_OUTPUT_LENGTH: usize = PADDED_G2_LENGTH; +/// G2_INPUT_ITEM_LENGTH specifies the number of bytes that the EVM will use to represent +/// a G2 element. +// TODO: can we remove this since it is just `PADDED_G2_LENGTH` +pub const G2_INPUT_ITEM_LENGTH: usize = 256; + +/// PAIRING_INPUT_LENGTH specifies the number of bytes that each Pairing input pair should have. +/// +/// Note: An Pairing input-pair is a G2 element and a G1 element. The input to the Pairing will have `n` +/// of these pairs. +pub const PAIRING_INPUT_LENGTH: usize = PADDED_G1_LENGTH + PADDED_G2_LENGTH; + +/// PADDING_LENGTH specifies the number of bytes that an FP_ELEMENT is padded by. +/// +/// Note: This should be equal to PADDED_FP_LENGTH - FP_LENGTH. +/// TODO: Should likely rename this to FP_PADDING_LENGTH, since other objects are also padded +pub const PADDING_LENGTH: usize = 16; + +// 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, +]; From 796613c868ba5440e7d2c7c3c5e43afd1376ca00 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Sun, 16 Mar 2025 18:40:49 +0000 Subject: [PATCH 2/5] remove orthogonal TODO --- crates/precompile/src/bls12_381_const.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs index 015c9d86f8..fbde4d73f0 100644 --- a/crates/precompile/src/bls12_381_const.rs +++ b/crates/precompile/src/bls12_381_const.rs @@ -79,7 +79,6 @@ pub const PADDED_FP2_LENGTH: usize = 2 * PADDED_FP_LENGTH; pub const SCALAR_LENGTH: usize = 32; /// NBITS specifies the number of bits needed to represent an Fr element. /// This is an element in the scalar field of BLS12-381. -/// TODO: We can likely remove this and just check what the min(scalar.length()) is before doing an MSM pub const NBITS: usize = 256; /// G1_ADD_INPUT_LENGTH specifies the number of bytes that the input to G1ADD From 7694f83712a96d2c74a165b5a966d898c622f7e0 Mon Sep 17 00:00:00 2001 From: Kevaundray Wedderburn Date: Sun, 16 Mar 2025 18:49:23 +0000 Subject: [PATCH 3/5] remove unused constants --- crates/precompile/src/bls12_381_const.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs index fbde4d73f0..d82e24db72 100644 --- a/crates/precompile/src/bls12_381_const.rs +++ b/crates/precompile/src/bls12_381_const.rs @@ -61,14 +61,11 @@ pub const G1_LENGTH: usize = 2 * FP_LENGTH; /// a G1 element according to padding rules specified in EIP-2537. const PADDED_G1_LENGTH: usize = 2 * PADDED_FP_LENGTH; -/// FP2_LENGTH specifies the number of bytes needed to represent a -/// Fp^2 element. +/// PADDED_FP2_LENGTH specifies the number of bytes that the EVM will use to represent +/// a Fp^2 element according to the padding rules specified in EIP-2537. /// /// Note: This is the quadratic extension of Fp, and by definition /// means we need 2 Fp elements. -const FP2_LENGTH: usize = 2 * FP_LENGTH; -/// PADDED_FP2_LENGTH specifies the number of bytes that the EVM will use to represent -/// a Fp^2 element according to the padding rules specified in EIP-2537. pub const PADDED_FP2_LENGTH: usize = 2 * PADDED_FP_LENGTH; /// SCALAR_LENGTH specifies the number of bytes needed to represent an Fr element. @@ -100,12 +97,10 @@ pub const G1_MSM_INPUT_LENGTH: usize = PADDED_G1_LENGTH + SCALAR_LENGTH; // TODO: can we remove this since it is just `PADDED_G1_LENGTH`? pub const G1_INPUT_ITEM_LENGTH: usize = PADDED_G1_LENGTH; -/// G2_LENGTH specifies the number of bytes needed to represent a G2 element. -/// -/// Note: A G2 element can be represented using 2 Fp^2 elements. -const G2_LENGTH: usize = 2 * FP2_LENGTH; /// PADDED_G2_LENGTH specifies the number of bytes that the EVM will use to represent /// a G2 element. +/// +/// Note: A G2 element can be represented using 2 Fp^2 elements. const PADDED_G2_LENGTH: usize = 2 * PADDED_FP2_LENGTH; /// G2_ADD_INPUT_LENGTH specifies the number of bytes that the input to G2ADD From 035ff36dd2c81003afd5936b9a9a733c7022b94f Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 17 Mar 2025 11:48:22 +0000 Subject: [PATCH 4/5] Update crates/precompile/src/bls12_381_const.rs Co-authored-by: rakita --- crates/precompile/src/bls12_381_const.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs index d82e24db72..d12d7336c9 100644 --- a/crates/precompile/src/bls12_381_const.rs +++ b/crates/precompile/src/bls12_381_const.rs @@ -101,7 +101,7 @@ pub const G1_INPUT_ITEM_LENGTH: usize = PADDED_G1_LENGTH; /// a G2 element. /// /// Note: A G2 element can be represented using 2 Fp^2 elements. -const PADDED_G2_LENGTH: usize = 2 * PADDED_FP2_LENGTH; +pub const PADDED_G2_LENGTH: usize = 2 * PADDED_FP2_LENGTH; /// G2_ADD_INPUT_LENGTH specifies the number of bytes that the input to G2ADD /// must occupy. From 16660167ae9a5f45b739e3a75ffc533699a6200a Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 17 Mar 2025 11:48:42 +0000 Subject: [PATCH 5/5] Update crates/precompile/src/bls12_381_const.rs Co-authored-by: rakita --- crates/precompile/src/bls12_381_const.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/precompile/src/bls12_381_const.rs b/crates/precompile/src/bls12_381_const.rs index d12d7336c9..c15412a9b2 100644 --- a/crates/precompile/src/bls12_381_const.rs +++ b/crates/precompile/src/bls12_381_const.rs @@ -59,7 +59,7 @@ pub const PADDED_FP_LENGTH: usize = 64; pub const G1_LENGTH: usize = 2 * FP_LENGTH; /// PADDED_G1_LENGTH specifies the number of bytes that the EVM will use to represent /// a G1 element according to padding rules specified in EIP-2537. -const PADDED_G1_LENGTH: usize = 2 * PADDED_FP_LENGTH; +pub const PADDED_G1_LENGTH: usize = 2 * PADDED_FP_LENGTH; /// PADDED_FP2_LENGTH specifies the number of bytes that the EVM will use to represent /// a Fp^2 element according to the padding rules specified in EIP-2537.