@@ -383,6 +383,63 @@ ExecutionResult blake2bf_execute(const uint8_t* input, [[maybe_unused]] size_t i
383
383
return {EVMC_SUCCESS, sizeof (h)};
384
384
}
385
385
386
+ ExecutionResult ecpairing_execute (const uint8_t * input, size_t input_size, uint8_t * output,
387
+ [[maybe_unused]] size_t output_size) noexcept
388
+ {
389
+ assert (output_size >= 32 );
390
+
391
+ const auto pair_size = 192 ;
392
+
393
+ if (input_size % pair_size != 0 )
394
+ return {EVMC_PRECOMPILE_FAILURE, 0 };
395
+
396
+ const auto pair_count = input_size / pair_size;
397
+
398
+ if (pair_count > 0 )
399
+ {
400
+ auto input_idx = input;
401
+
402
+ std::vector<evmmax::bn254::Point > vG1 (pair_count);
403
+ std::vector<evmmax::bn254::ExtPoint> vG2 (pair_count);
404
+
405
+ for (size_t i = 0 ; i < pair_count; ++i)
406
+ {
407
+ const evmmax::bn254::Point p = {
408
+ intx::be::unsafe::load<intx::uint256>(input_idx),
409
+ intx::be::unsafe::load<intx::uint256>(input_idx + 32 ),
410
+ };
411
+
412
+ const evmmax::bn254::ExtPoint q = {
413
+ {intx::be::unsafe::load<intx::uint256>(input_idx + 96 ),
414
+ intx::be::unsafe::load<intx::uint256>(input_idx + 64 )},
415
+ {intx::be::unsafe::load<intx::uint256>(input_idx + 160 ),
416
+ intx::be::unsafe::load<intx::uint256>(input_idx + 128 )},
417
+ };
418
+
419
+ vG1[i] = p;
420
+ vG2[i] = q;
421
+
422
+ input_idx += pair_size;
423
+ }
424
+
425
+ const auto res = evmmax::bn254::pairing (vG2, vG1);
426
+
427
+ if (res.has_value ())
428
+ {
429
+ intx::be::unsafe::store (output, res.value () ? intx::uint256{1 } : intx::uint256{0 });
430
+ return {EVMC_SUCCESS, 64 };
431
+ }
432
+ else
433
+ return {EVMC_PRECOMPILE_FAILURE, 0 };
434
+ }
435
+ else
436
+ {
437
+ intx::be::unsafe::store (output, intx::uint256{1 });
438
+ return {EVMC_SUCCESS, 32 };
439
+ }
440
+ }
441
+
442
+
386
443
ExecutionResult point_evaluation_execute (const uint8_t * input, size_t input_size, uint8_t * output,
387
444
[[maybe_unused]] size_t output_size) noexcept
388
445
{
0 commit comments