revm_precompile/bls12_381_const.rs
1use crate::u64_to_address;
2use primitives::Address;
3
4// Constants specifying the precompile addresses for each precompile
5// in EIP-2537
6pub const G1_ADD_ADDRESS: Address = u64_to_address(0x0b);
7pub const G1_MSM_ADDRESS: Address = u64_to_address(0x0c);
8pub const G2_ADD_ADDRESS: Address = u64_to_address(0x0d);
9pub const G2_MSM_ADDRESS: Address = u64_to_address(0x0e);
10pub const PAIRING_ADDRESS: Address = u64_to_address(0x0f);
11pub const MAP_FP_TO_G1_ADDRESS: Address = u64_to_address(0x10);
12pub const MAP_FP2_TO_G2_ADDRESS: Address = u64_to_address(0x11);
13
14/// G1_ADD_BASE_GAS_FEE specifies the amount of gas needed
15/// to perform the G1_ADD precompile.
16pub const G1_ADD_BASE_GAS_FEE: u64 = 375;
17/// G1_MSM_BASE_GAS_FEE specifies the base amount of gas needed to
18/// perform the G1_MSM precompile.
19///
20/// The cost to do an MSM is determined by the formula:
21/// (k * G1_MSM_BASE_GAS_FEE * DISCOUNT\[k\]) // MSM_MULTIPLIER
22/// where k is the number of point-scalar pairs.
23///
24/// Note: If one wants to do a G1 scalar multiplication, they would call
25/// this precompile with a single point and a scalar.
26pub const G1_MSM_BASE_GAS_FEE: u64 = 12000;
27/// MSM_MULTIPLIER specifies the division constant that is used to determine the
28/// gas needed to compute an MSM.
29///
30/// The cost to do an MSM is determined by the formula:
31/// (k * MSM_BASE_GAS_FEE * DISCOUNT\[k\]) // MSM_MULTIPLIER
32/// where k is the number of point-scalar pairs.
33///
34/// Note: If `k` is more than the size of the discount table, then
35/// the last value in the discount table is chosen.
36pub const MSM_MULTIPLIER: u64 = 1000;
37/// MAP_FP_TO_G1_BASE_GAS_FEE specifies the amount of gas needed
38/// to perform the MAP_FP_TO_G1 precompile.
39pub const MAP_FP_TO_G1_BASE_GAS_FEE: u64 = 5500;
40/// MAP_FP2_TO_G2_BASE_GAS_FEE specifies the amount of gas needed
41/// to perform the MAP_FP2_TO_G2 precompile.
42pub const MAP_FP2_TO_G2_BASE_GAS_FEE: u64 = 23800;
43/// G2_ADD_BASE_GAS_FEE specifies the amount of gas needed
44/// to perform the G2_ADD precompile.
45pub const G2_ADD_BASE_GAS_FEE: u64 = 600;
46/// G2_MSM_BASE_GAS_FEE specifies the base amount of gas needed to
47/// perform the G2_MSM precompile.
48///
49/// The cost to do an MSM is determined by the formula:
50/// (k * G2_MSM_BASE_GAS_FEE * DISCOUNT\[k\]) // MSM_MULTIPLIER
51/// where k is the number of point-scalar pairs.
52///
53/// Note: If one wants to do a G2 scalar multiplication, they would call
54/// this precompile with a single point and a scalar.
55pub const G2_MSM_BASE_GAS_FEE: u64 = 22500;
56/// PAIRING_OFFSET_BASE specifies the y-intercept for the linear expression to determine
57/// the amount of gas needed to perform a pairing.
58///
59/// The cost to do a pairing is determined by the formula:
60/// cost = PAIRING_MULTIPLIER_BASE * number_of_pairs + PAIRING_OFFSET_BASE
61pub const PAIRING_OFFSET_BASE: u64 = 37700;
62/// PAIRING_MULTIPLIER_BASE specifies the slope/gradient for the linear expression to determine
63/// the amount of gas needed to perform a pairing.
64///
65/// The cost to do a pairing is determined by the formula:
66/// PAIRING_MULTIPLIER_BASE * number_of_pairs + PAIRING_OFFSET_BASE
67pub const PAIRING_MULTIPLIER_BASE: u64 = 32600;
68
69/// Discounts table for G1 MSM as a vector of pairs `[k, discount]`.
70pub static DISCOUNT_TABLE_G1_MSM: [u16; 128] = [
71 1000, 949, 848, 797, 764, 750, 738, 728, 719, 712, 705, 698, 692, 687, 682, 677, 673, 669, 665,
72 661, 658, 654, 651, 648, 645, 642, 640, 637, 635, 632, 630, 627, 625, 623, 621, 619, 617, 615,
73 613, 611, 609, 608, 606, 604, 603, 601, 599, 598, 596, 595, 593, 592, 591, 589, 588, 586, 585,
74 584, 582, 581, 580, 579, 577, 576, 575, 574, 573, 572, 570, 569, 568, 567, 566, 565, 564, 563,
75 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 547, 546, 545,
76 544, 543, 542, 541, 540, 540, 539, 538, 537, 536, 536, 535, 534, 533, 532, 532, 531, 530, 529,
77 528, 528, 527, 526, 525, 525, 524, 523, 522, 522, 521, 520, 520, 519,
78];
79/// Discounts table for G2 MSM as a vector of pairs `[k, discount]`:
80pub static DISCOUNT_TABLE_G2_MSM: [u16; 128] = [
81 1000, 1000, 923, 884, 855, 832, 812, 796, 782, 770, 759, 749, 740, 732, 724, 717, 711, 704,
82 699, 693, 688, 683, 679, 674, 670, 666, 663, 659, 655, 652, 649, 646, 643, 640, 637, 634, 632,
83 629, 627, 624, 622, 620, 618, 615, 613, 611, 609, 607, 606, 604, 602, 600, 598, 597, 595, 593,
84 592, 590, 589, 587, 586, 584, 583, 582, 580, 579, 578, 576, 575, 574, 573, 571, 570, 569, 568,
85 567, 566, 565, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 552, 551, 550, 549,
86 548, 547, 546, 545, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 537, 536, 535, 535, 534,
87 533, 532, 532, 531, 530, 530, 529, 528, 528, 527, 526, 526, 525, 524, 524,
88];
89
90// Constants related to the bls12-381 precompile inputs and outputs
91
92/// FP_LENGTH specifies the number of bytes needed to represent an
93/// Fp element. This is an element in the base field of BLS12-381.
94///
95/// Note: The base field is used to define G1 and G2 elements.
96pub const FP_LENGTH: usize = 48;
97/// PADDED_FP_LENGTH specifies the number of bytes that the EVM will use
98/// to represent an Fp element according to EIP-2537.
99///
100/// Note: We only need FP_LENGTH number of bytes to represent it,
101/// but we pad the byte representation to be 32 byte aligned as specified in EIP 2537.
102pub const PADDED_FP_LENGTH: usize = 64;
103
104/// G1_LENGTH specifies the number of bytes needed to represent a G1 element.
105///
106/// Note: A G1 element contains 2 Fp elements.
107pub const G1_LENGTH: usize = 2 * FP_LENGTH;
108/// PADDED_G1_LENGTH specifies the number of bytes that the EVM will use to represent
109/// a G1 element according to padding rules specified in EIP-2537.
110pub const PADDED_G1_LENGTH: usize = 2 * PADDED_FP_LENGTH;
111
112/// PADDED_FP2_LENGTH specifies the number of bytes that the EVM will use to represent
113/// a Fp^2 element according to the padding rules specified in EIP-2537.
114///
115/// Note: This is the quadratic extension of Fp, and by definition
116/// means we need 2 Fp elements.
117pub const PADDED_FP2_LENGTH: usize = 2 * PADDED_FP_LENGTH;
118
119/// SCALAR_LENGTH specifies the number of bytes needed to represent an Fr element.
120/// This is an element in the scalar field of BLS12-381.
121///
122/// Note: Since it is already 32 byte aligned, there is no padded version of this constant.
123pub const SCALAR_LENGTH: usize = 32;
124/// SCALAR_LENGTH_BITS specifies the number of bits needed to represent an Fr element.
125/// This is an element in the scalar field of BLS12-381.
126pub const SCALAR_LENGTH_BITS: usize = SCALAR_LENGTH * 8;
127
128/// G1_ADD_INPUT_LENGTH specifies the number of bytes that the input to G1ADD
129/// must use.
130///
131/// Note: The input to the G1 addition precompile is 2 G1 elements.
132pub const G1_ADD_INPUT_LENGTH: usize = 2 * PADDED_G1_LENGTH;
133/// G1_MSM_INPUT_LENGTH specifies the number of bytes that each MSM input pair should have.
134///
135/// Note: An MSM pair is a G1 element and a scalar. The input to the MSM precompile will have `n`
136/// of these pairs.
137pub const G1_MSM_INPUT_LENGTH: usize = PADDED_G1_LENGTH + SCALAR_LENGTH;
138
139/// PADDED_G2_LENGTH specifies the number of bytes that the EVM will use to represent
140/// a G2 element.
141///
142/// Note: A G2 element can be represented using 2 Fp^2 elements.
143pub const PADDED_G2_LENGTH: usize = 2 * PADDED_FP2_LENGTH;
144
145/// G2_ADD_INPUT_LENGTH specifies the number of bytes that the input to G2ADD
146/// must occupy.
147///
148/// Note: The input to the G2 addition precompile is 2 G2 elements.
149pub const G2_ADD_INPUT_LENGTH: usize = 2 * PADDED_G2_LENGTH;
150/// G2_MSM_INPUT_LENGTH specifies the number of bytes that each MSM input pair should have.
151///
152/// Note: An MSM pair is a G2 element and a scalar. The input to the MSM will have `n`
153/// of these pairs.
154pub const G2_MSM_INPUT_LENGTH: usize = PADDED_G2_LENGTH + SCALAR_LENGTH;
155
156/// PAIRING_INPUT_LENGTH specifies the number of bytes that each Pairing input pair should have.
157///
158/// Note: An Pairing input-pair is a G2 element and a G1 element. The input to the Pairing will have `n`
159/// of these pairs.
160pub const PAIRING_INPUT_LENGTH: usize = PADDED_G1_LENGTH + PADDED_G2_LENGTH;
161
162/// FP_PAD_BY specifies the number of bytes that an FP_ELEMENT is padded by to make it 32 byte aligned.
163///
164/// Note: This should be equal to PADDED_FP_LENGTH - FP_LENGTH.
165pub const FP_PAD_BY: usize = 16;
166
167#[test]
168fn check_discount_table_invariant_holds() {
169 // Currently EIP-2537 specifies the cost for a G1/G2 scalar multiplication in two places
170 // in two different ways.
171 //
172 // First it explicitly says that G1 Multiplication costs 12000 Gas and G2 Multiplication costs 22500.
173 //
174 // Then it implies the above constants for G1_MSM and G2_MSM via the MSM formula:
175 // MSM_COST = k * MSM_BASE_GAS_FEE * DISCOUNT[k-1] // MSM_MULTIPLIER
176 //
177 // Note that when the MSM has only one point-scalar pair (scalar multiplication), we get:
178 // MSM_COST = MSM_BASE_GAS_FEE * DISCOUNT[0] // MSM_MULTIPLIER
179 // (This is because k==1)
180 //
181 // The 0th entry in the discount table for G1_MSM and G2_MSM is equal to MSM_MULTIPLIER
182 // so for k==1, MSM_COST = MSM_BASE_GAS_FEE
183 //
184 // For G1, MSM_BASE_GAS_FEE matches 12000 and for G2 MSM_BASE_GAS_FEE matches 22500.
185 //
186 // In this test, we check that this invariant does not change by asserting that the first value
187 // in the discount table is equal to the MULTIPLIER.
188 assert_eq!(DISCOUNT_TABLE_G1_MSM[0], MSM_MULTIPLIER as u16);
189 assert_eq!(DISCOUNT_TABLE_G2_MSM[0], MSM_MULTIPLIER as u16);
190 // Note: We could also more robustly check this by defining the G1/G2 Scalar multiplication constants
191 // from the EIP and checking that they equal to the value computed by `msm_required_gas` when k==1
192}