@@ -292,6 +292,63 @@ ExecutionResult blake2bf_execute(const uint8_t* input, [[maybe_unused]] size_t i
292
292
return {EVMC_SUCCESS, sizeof (h)};
293
293
}
294
294
295
+ ExecutionResult ecpairing_execute (const uint8_t * input, size_t input_size, uint8_t * output,
296
+ [[maybe_unused]] size_t output_size) noexcept
297
+ {
298
+ assert (output_size >= 32 );
299
+
300
+ const auto pair_size = 192 ;
301
+
302
+ if (input_size % pair_size != 0 )
303
+ return {EVMC_PRECOMPILE_FAILURE, 0 };
304
+
305
+ const auto pair_count = input_size / pair_size;
306
+
307
+ if (pair_count > 0 )
308
+ {
309
+ auto input_idx = input;
310
+
311
+ std::vector<evmmax::bn254::Point > vG1 (pair_count);
312
+ std::vector<evmmax::bn254::ExtPoint> vG2 (pair_count);
313
+
314
+ for (size_t i = 0 ; i < pair_count; ++i)
315
+ {
316
+ const evmmax::bn254::Point p = {
317
+ intx::be::unsafe::load<intx::uint256>(input_idx),
318
+ intx::be::unsafe::load<intx::uint256>(input_idx + 32 ),
319
+ };
320
+
321
+ const evmmax::bn254::ExtPoint q = {
322
+ {intx::be::unsafe::load<intx::uint256>(input_idx + 96 ),
323
+ intx::be::unsafe::load<intx::uint256>(input_idx + 64 )},
324
+ {intx::be::unsafe::load<intx::uint256>(input_idx + 160 ),
325
+ intx::be::unsafe::load<intx::uint256>(input_idx + 128 )},
326
+ };
327
+
328
+ vG1[i] = p;
329
+ vG2[i] = q;
330
+
331
+ input_idx += pair_size;
332
+ }
333
+
334
+ const auto res = evmmax::bn254::pairing (vG2, vG1);
335
+
336
+ if (res.has_value ())
337
+ {
338
+ intx::be::unsafe::store (output, res.value () ? intx::uint256{1 } : intx::uint256{0 });
339
+ return {EVMC_SUCCESS, 64 };
340
+ }
341
+ else
342
+ return {EVMC_PRECOMPILE_FAILURE, 0 };
343
+ }
344
+ else
345
+ {
346
+ intx::be::unsafe::store (output, intx::uint256{1 });
347
+ return {EVMC_SUCCESS, 32 };
348
+ }
349
+ }
350
+
351
+
295
352
namespace
296
353
{
297
354
struct PrecompileTraits
0 commit comments