1717#include < bit>
1818#include < cassert>
1919#include < limits>
20+ #include < span>
2021
2122#ifdef EVMONE_PRECOMPILES_SILKPRE
2223#include " precompiles_silkpre.hpp"
@@ -32,6 +33,13 @@ namespace
3233{
3334constexpr auto GasCostMax = std::numeric_limits<int64_t >::max();
3435
36+ constexpr auto BLS12_SCALAR_SIZE = 32 ;
37+ constexpr auto BLS12_FIELD_ELEMENT_SIZE = 64 ;
38+ constexpr auto BLS12_G1_POINT_SIZE = 2 * BLS12_FIELD_ELEMENT_SIZE;
39+ constexpr auto BLS12_G2_POINT_SIZE = 4 * BLS12_FIELD_ELEMENT_SIZE;
40+ constexpr auto BLS12_G1_MUL_INPUT_SIZE = BLS12_G1_POINT_SIZE + BLS12_SCALAR_SIZE;
41+ constexpr auto BLS12_G2_MUL_INPUT_SIZE = BLS12_G2_POINT_SIZE + BLS12_SCALAR_SIZE;
42+
3543constexpr int64_t num_words (size_t size_in_bytes) noexcept
3644{
3745 return static_cast <int64_t >((size_in_bytes + 31 ) / 32 );
@@ -42,25 +50,6 @@ constexpr int64_t cost_per_input_word(size_t input_size) noexcept
4250{
4351 return BaseCost + WordCost * num_words (input_size);
4452}
45-
46- int64_t bls_msm_cost (size_t k, int64_t multiplication_cost) noexcept
47- {
48- assert (k > 0 );
49-
50- static constexpr int64_t MULTIPLIER = 1000 ;
51- static constexpr int16_t DISCOUNT[128 ] = {1200 , 888 , 764 , 641 , 594 , 547 , 500 , 453 , 438 , 423 ,
52- 408 , 394 , 379 , 364 , 349 , 334 , 330 , 326 , 322 , 318 , 314 , 310 , 306 , 302 , 298 , 294 , 289 , 285 ,
53- 281 , 277 , 273 , 269 , 268 , 266 , 265 , 263 , 262 , 260 , 259 , 257 , 256 , 254 , 253 , 251 , 250 , 248 ,
54- 247 , 245 , 244 , 242 , 241 , 239 , 238 , 236 , 235 , 233 , 232 , 231 , 229 , 228 , 226 , 225 , 223 , 222 ,
55- 221 , 220 , 219 , 219 , 218 , 217 , 216 , 216 , 215 , 214 , 213 , 213 , 212 , 211 , 211 , 210 , 209 , 208 ,
56- 208 , 207 , 206 , 205 , 205 , 204 , 203 , 202 , 202 , 201 , 200 , 199 , 199 , 198 , 197 , 196 , 196 , 195 ,
57- 194 , 193 , 193 , 192 , 191 , 191 , 190 , 189 , 188 , 188 , 187 , 186 , 185 , 185 , 184 , 183 , 182 , 182 ,
58- 181 , 180 , 179 , 179 , 178 , 177 , 176 , 176 , 175 , 174 };
59-
60- const auto d = DISCOUNT[std::min (k, std::size (DISCOUNT)) - 1 ];
61- return (static_cast <int64_t >(k) * multiplication_cost * d) / MULTIPLIER;
62- }
63-
6453} // namespace
6554
6655PrecompileAnalysis ecrecover_analyze (bytes_view /* input*/ , evmc_revision /* rev*/ ) noexcept
@@ -176,57 +165,71 @@ PrecompileAnalysis point_evaluation_analyze(bytes_view, evmc_revision) noexcept
176165
177166PrecompileAnalysis bls12_g1add_analyze (bytes_view, evmc_revision) noexcept
178167{
179- static constexpr auto BLS12_G1ADD_PRECOMPILE_GAS = 500 ;
180- return {BLS12_G1ADD_PRECOMPILE_GAS, 128 };
181- }
182-
183- PrecompileAnalysis bls12_g1mul_analyze (bytes_view, evmc_revision) noexcept
184- {
185- static constexpr auto BLS12_G1MUL_PRECOMPILE_GAS = 12000 ;
186- return {BLS12_G1MUL_PRECOMPILE_GAS, 128 };
168+ static constexpr auto BLS12_G1ADD_PRECOMPILE_GAS = 375 ;
169+ return {BLS12_G1ADD_PRECOMPILE_GAS, BLS12_G1_POINT_SIZE};
187170}
188171
189172PrecompileAnalysis bls12_g1msm_analyze (bytes_view input, evmc_revision) noexcept
190173{
191- if (input.empty () || input.size () % 160 != 0 )
174+ static constexpr auto G1MUL_GAS_COST = 12000 ;
175+ static constexpr uint16_t DISCOUNTS[] = {1000 , 949 , 848 , 797 , 764 , 750 , 738 , 728 , 719 , 712 , 705 ,
176+ 698 , 692 , 687 , 682 , 677 , 673 , 669 , 665 , 661 , 658 , 654 , 651 , 648 , 645 , 642 , 640 , 637 , 635 ,
177+ 632 , 630 , 627 , 625 , 623 , 621 , 619 , 617 , 615 , 613 , 611 , 609 , 608 , 606 , 604 , 603 , 601 , 599 ,
178+ 598 , 596 , 595 , 593 , 592 , 591 , 589 , 588 , 586 , 585 , 584 , 582 , 581 , 580 , 579 , 577 , 576 , 575 ,
179+ 574 , 573 , 572 , 570 , 569 , 568 , 567 , 566 , 565 , 564 , 563 , 562 , 561 , 560 , 559 , 558 , 557 , 556 ,
180+ 555 , 554 , 553 , 552 , 551 , 550 , 549 , 548 , 547 , 547 , 546 , 545 , 544 , 543 , 542 , 541 , 540 , 540 ,
181+ 539 , 538 , 537 , 536 , 536 , 535 , 534 , 533 , 532 , 532 , 531 , 530 , 529 , 528 , 528 , 527 , 526 , 525 ,
182+ 525 , 524 , 523 , 522 , 522 , 521 , 520 , 520 , 519 };
183+
184+ if (input.empty () || input.size () % BLS12_G1_MUL_INPUT_SIZE != 0 )
192185 return {GasCostMax, 0 };
193186
194- static constexpr auto BLS12_G1MUL_PRECOMPILE_GAS = 12000 ;
195- return {bls_msm_cost (input.size () / 160 , BLS12_G1MUL_PRECOMPILE_GAS), 128 };
187+ const auto k = input.size () / BLS12_G1_MUL_INPUT_SIZE;
188+ assert (k > 0 );
189+ const auto discount = DISCOUNTS[std::min (k, std::size (DISCOUNTS)) - 1 ];
190+ const auto cost = (G1MUL_GAS_COST * discount * static_cast <int64_t >(k)) / 1000 ;
191+ return {cost, BLS12_G1_POINT_SIZE};
196192}
197193
198194PrecompileAnalysis bls12_g2add_analyze (bytes_view, evmc_revision) noexcept
199195{
200- static constexpr auto BLS12_G2ADD_PRECOMPILE_GAS = 800 ;
201- return {BLS12_G2ADD_PRECOMPILE_GAS, 256 };
202- }
203-
204- PrecompileAnalysis bls12_g2mul_analyze (bytes_view, evmc_revision) noexcept
205- {
206- static constexpr auto BLS12_G2MUL_PRECOMPILE_GAS = 45000 ;
207- return {BLS12_G2MUL_PRECOMPILE_GAS, 256 };
196+ static constexpr auto BLS12_G2ADD_PRECOMPILE_GAS = 600 ;
197+ return {BLS12_G2ADD_PRECOMPILE_GAS, BLS12_G2_POINT_SIZE};
208198}
209199
210200PrecompileAnalysis bls12_g2msm_analyze (bytes_view input, evmc_revision) noexcept
211201{
212- if (input.empty () || input.size () % 288 != 0 )
202+ static constexpr auto G2MUL_GAS_COST = 22500 ;
203+ static constexpr uint16_t DISCOUNTS[] = {1000 , 1000 , 923 , 884 , 855 , 832 , 812 , 796 , 782 , 770 ,
204+ 759 , 749 , 740 , 732 , 724 , 717 , 711 , 704 , 699 , 693 , 688 , 683 , 679 , 674 , 670 , 666 , 663 , 659 ,
205+ 655 , 652 , 649 , 646 , 643 , 640 , 637 , 634 , 632 , 629 , 627 , 624 , 622 , 620 , 618 , 615 , 613 , 611 ,
206+ 609 , 607 , 606 , 604 , 602 , 600 , 598 , 597 , 595 , 593 , 592 , 590 , 589 , 587 , 586 , 584 , 583 , 582 ,
207+ 580 , 579 , 578 , 576 , 575 , 574 , 573 , 571 , 570 , 569 , 568 , 567 , 566 , 565 , 563 , 562 , 561 , 560 ,
208+ 559 , 558 , 557 , 556 , 555 , 554 , 553 , 552 , 552 , 551 , 550 , 549 , 548 , 547 , 546 , 545 , 545 , 544 ,
209+ 543 , 542 , 541 , 541 , 540 , 539 , 538 , 537 , 537 , 536 , 535 , 535 , 534 , 533 , 532 , 532 , 531 , 530 ,
210+ 530 , 529 , 528 , 528 , 527 , 526 , 526 , 525 , 524 , 524 };
211+
212+ if (input.empty () || input.size () % BLS12_G2_MUL_INPUT_SIZE != 0 )
213213 return {GasCostMax, 0 };
214214
215- static constexpr auto BLS12_G2MUL_PRECOMPILE_GAS = 45000 ;
216- return {bls_msm_cost (input.size () / 288 , BLS12_G2MUL_PRECOMPILE_GAS), 256 };
215+ const auto k = input.size () / BLS12_G2_MUL_INPUT_SIZE;
216+ assert (k > 0 );
217+ const auto discount = DISCOUNTS[std::min (k, std::size (DISCOUNTS)) - 1 ];
218+ const auto cost = (G2MUL_GAS_COST * discount * static_cast <int64_t >(k)) / 1000 ;
219+ return {cost, BLS12_G2_POINT_SIZE};
217220}
218221
219222PrecompileAnalysis bls12_pairing_check_analyze (bytes_view input, evmc_revision) noexcept
220223{
221- static constexpr auto PAIR_SIZE = 384 ;
224+ static constexpr auto PAIR_SIZE = BLS12_G1_POINT_SIZE + BLS12_G2_POINT_SIZE ;
222225
223226 if (input.empty () || input.size () % PAIR_SIZE != 0 )
224227 return {GasCostMax, 0 };
225228
226229 const auto npairs = static_cast <int64_t >(input.size ()) / PAIR_SIZE;
227230
228- static constexpr auto BLS12_PAIRING_CHECK_BASE_FEE_PRECOMPILE_GAS = 65000 ;
229- static constexpr auto BLS12_PAIRING_CHECK_FEE_PRECOMPILE_GAS = 43000 ;
231+ static constexpr auto BLS12_PAIRING_CHECK_BASE_FEE_PRECOMPILE_GAS = 37700 ;
232+ static constexpr auto BLS12_PAIRING_CHECK_FEE_PRECOMPILE_GAS = 32600 ;
230233 return {BLS12_PAIRING_CHECK_BASE_FEE_PRECOMPILE_GAS +
231234 BLS12_PAIRING_CHECK_FEE_PRECOMPILE_GAS * npairs,
232235 32 };
@@ -235,13 +238,13 @@ PrecompileAnalysis bls12_pairing_check_analyze(bytes_view input, evmc_revision)
235238PrecompileAnalysis bls12_map_fp_to_g1_analyze (bytes_view, evmc_revision) noexcept
236239{
237240 static constexpr auto BLS12_MAP_FP_TO_G1_PRECOMPILE_GAS = 5500 ;
238- return {BLS12_MAP_FP_TO_G1_PRECOMPILE_GAS, 128 };
241+ return {BLS12_MAP_FP_TO_G1_PRECOMPILE_GAS, BLS12_G1_POINT_SIZE };
239242}
240243
241244PrecompileAnalysis bls12_map_fp2_to_g2_analyze (bytes_view, evmc_revision) noexcept
242245{
243- static constexpr auto BLS12_MAP_FP2_TO_G2_PRECOMPILE_GAS = 75000 ;
244- return {BLS12_MAP_FP2_TO_G2_PRECOMPILE_GAS, 256 };
246+ static constexpr auto BLS12_MAP_FP2_TO_G2_PRECOMPILE_GAS = 23800 ;
247+ return {BLS12_MAP_FP2_TO_G2_PRECOMPILE_GAS, BLS12_G2_POINT_SIZE };
245248}
246249
247250ExecutionResult ecrecover_execute (const uint8_t * input, size_t input_size, uint8_t * output,
@@ -409,91 +412,63 @@ ExecutionResult point_evaluation_execute(const uint8_t* input, size_t input_size
409412ExecutionResult bls12_g1add_execute (const uint8_t * input, size_t input_size, uint8_t * output,
410413 [[maybe_unused]] size_t output_size) noexcept
411414{
412- if (input_size != 256 )
415+ if (input_size != 2 * BLS12_G1_POINT_SIZE )
413416 return {EVMC_PRECOMPILE_FAILURE, 0 };
414417
415- assert (output_size == 128 );
418+ assert (output_size == BLS12_G1_POINT_SIZE );
416419
417420 if (!crypto::bls::g1_add (output, &output[64 ], input, &input[64 ], &input[128 ], &input[192 ]))
418421 return {EVMC_PRECOMPILE_FAILURE, 0 };
419422
420- return {EVMC_SUCCESS, 128 };
421- }
422-
423- ExecutionResult bls12_g1mul_execute (const uint8_t * input, size_t input_size, uint8_t * output,
424- [[maybe_unused]] size_t output_size) noexcept
425- {
426- if (input_size != 160 )
427- return {EVMC_PRECOMPILE_FAILURE, 0 };
428-
429- assert (output_size == 128 );
430-
431- if (!crypto::bls::g1_mul (output, &output[64 ], input, &input[64 ], &input[128 ]))
432- return {EVMC_PRECOMPILE_FAILURE, 0 };
433-
434- return {EVMC_SUCCESS, 128 };
423+ return {EVMC_SUCCESS, BLS12_G1_POINT_SIZE};
435424}
436425
437426ExecutionResult bls12_g1msm_execute (const uint8_t * input, size_t input_size, uint8_t * output,
438427 [[maybe_unused]] size_t output_size) noexcept
439428{
440- if (input_size % 160 != 0 )
429+ if (input_size % BLS12_G1_MUL_INPUT_SIZE != 0 )
441430 return {EVMC_PRECOMPILE_FAILURE, 0 };
442431
443- assert (output_size == 128 );
432+ assert (output_size == BLS12_G1_POINT_SIZE );
444433
445434 if (!crypto::bls::g1_msm (output, &output[64 ], input, input_size))
446435 return {EVMC_PRECOMPILE_FAILURE, 0 };
447436
448- return {EVMC_SUCCESS, 128 };
437+ return {EVMC_SUCCESS, BLS12_G1_POINT_SIZE };
449438}
450439
451440ExecutionResult bls12_g2add_execute (const uint8_t * input, size_t input_size, uint8_t * output,
452441 [[maybe_unused]] size_t output_size) noexcept
453442{
454- if (input_size != 512 )
443+ if (input_size != 2 * BLS12_G2_POINT_SIZE )
455444 return {EVMC_PRECOMPILE_FAILURE, 0 };
456445
457- assert (output_size == 256 );
446+ assert (output_size == BLS12_G2_POINT_SIZE );
458447
459448 if (!crypto::bls::g2_add (output, &output[128 ], input, &input[128 ], &input[256 ], &input[384 ]))
460449 return {EVMC_PRECOMPILE_FAILURE, 0 };
461450
462- return {EVMC_SUCCESS, 256 };
463- }
464-
465- ExecutionResult bls12_g2mul_execute (const uint8_t * input, size_t input_size, uint8_t * output,
466- [[maybe_unused]] size_t output_size) noexcept
467- {
468- if (input_size != 288 )
469- return {EVMC_PRECOMPILE_FAILURE, 0 };
470-
471- assert (output_size == 256 );
472-
473- if (!crypto::bls::g2_mul (output, &output[128 ], input, &input[128 ], &input[256 ]))
474- return {EVMC_PRECOMPILE_FAILURE, 0 };
475-
476- return {EVMC_SUCCESS, 256 };
451+ return {EVMC_SUCCESS, BLS12_G2_POINT_SIZE};
477452}
478453
479454ExecutionResult bls12_g2msm_execute (const uint8_t * input, size_t input_size, uint8_t * output,
480455 [[maybe_unused]] size_t output_size) noexcept
481456{
482- if (input_size % 288 != 0 )
457+ if (input_size % BLS12_G2_MUL_INPUT_SIZE != 0 )
483458 return {EVMC_PRECOMPILE_FAILURE, 0 };
484459
485- assert (output_size == 256 );
460+ assert (output_size == BLS12_G2_POINT_SIZE );
486461
487462 if (!crypto::bls::g2_msm (output, &output[128 ], input, input_size))
488463 return {EVMC_PRECOMPILE_FAILURE, 0 };
489464
490- return {EVMC_SUCCESS, 256 };
465+ return {EVMC_SUCCESS, BLS12_G2_POINT_SIZE };
491466}
492467
493468ExecutionResult bls12_pairing_check_execute (const uint8_t * input, size_t input_size,
494469 uint8_t * output, [[maybe_unused]] size_t output_size) noexcept
495470{
496- if (input_size % 384 != 0 )
471+ if (input_size % (BLS12_G1_POINT_SIZE + BLS12_G2_POINT_SIZE) != 0 )
497472 return {EVMC_PRECOMPILE_FAILURE, 0 };
498473
499474 assert (output_size == 32 );
@@ -507,29 +482,29 @@ ExecutionResult bls12_pairing_check_execute(const uint8_t* input, size_t input_s
507482ExecutionResult bls12_map_fp_to_g1_execute (const uint8_t * input, size_t input_size, uint8_t * output,
508483 [[maybe_unused]] size_t output_size) noexcept
509484{
510- if (input_size != 64 )
485+ if (input_size != BLS12_FIELD_ELEMENT_SIZE )
511486 return {EVMC_PRECOMPILE_FAILURE, 0 };
512487
513- assert (output_size == 128 );
488+ assert (output_size == BLS12_G1_POINT_SIZE );
514489
515490 if (!crypto::bls::map_fp_to_g1 (output, &output[64 ], input))
516491 return {EVMC_PRECOMPILE_FAILURE, 0 };
517492
518- return {EVMC_SUCCESS, 128 };
493+ return {EVMC_SUCCESS, BLS12_G1_POINT_SIZE };
519494}
520495
521496ExecutionResult bls12_map_fp2_to_g2_execute (const uint8_t * input, size_t input_size,
522497 uint8_t * output, [[maybe_unused]] size_t output_size) noexcept
523498{
524- if (input_size != 128 )
499+ if (input_size != 2 * BLS12_FIELD_ELEMENT_SIZE )
525500 return {EVMC_PRECOMPILE_FAILURE, 0 };
526501
527- assert (output_size == 256 );
502+ assert (output_size == BLS12_G2_POINT_SIZE );
528503
529504 if (!crypto::bls::map_fp2_to_g2 (output, &output[128 ], input))
530505 return {EVMC_PRECOMPILE_FAILURE, 0 };
531506
532- return {EVMC_SUCCESS, 256 };
507+ return {EVMC_SUCCESS, BLS12_G2_POINT_SIZE };
533508}
534509
535510namespace
@@ -554,10 +529,8 @@ inline constexpr auto traits = []() noexcept {
554529 {blake2bf_analyze, blake2bf_execute},
555530 {point_evaluation_analyze, point_evaluation_execute},
556531 {bls12_g1add_analyze, bls12_g1add_execute},
557- {bls12_g1mul_analyze, bls12_g1mul_execute},
558532 {bls12_g1msm_analyze, bls12_g1msm_execute},
559533 {bls12_g2add_analyze, bls12_g2add_execute},
560- {bls12_g2mul_analyze, bls12_g2mul_execute},
561534 {bls12_g2msm_analyze, bls12_g2msm_execute},
562535 {bls12_pairing_check_analyze, bls12_pairing_check_execute},
563536 {bls12_map_fp_to_g1_analyze, bls12_map_fp_to_g1_execute},
0 commit comments