ethereum.forks.prague.vm.precompiled_contracts.bls12_381.bls12_381_pairing
Ethereum Virtual Machine (EVM) BLS12 381 PAIRING PRE-COMPILE.
.. contents:: Table of Contents :backlinks: none :local:
Introduction
Implementation of the BLS12 381 pairing pre-compile.
bls12_pairing
The bls12_381 pairing precompile.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid or if sub-group check fails.
def bls12_pairing(evm: Evm) -> None:
| 25 | """ |
|---|---|
| 26 | The bls12_381 pairing precompile. |
| 27 | |
| 28 | Parameters |
| 29 | ---------- |
| 30 | evm : |
| 31 | The current EVM frame. |
| 32 | |
| 33 | Raises |
| 34 | ------ |
| 35 | InvalidParameter |
| 36 | If the input length is invalid or if sub-group check fails. |
| 37 | |
| 38 | """ |
| 39 | data = evm.message.data |
| 40 | if len(data) == 0 or len(data) % 384 != 0: |
| 41 | raise InvalidParameter("Invalid Input Length") |
| 42 | |
| 43 | # GAS |
| 44 | k = len(data) // 384 |
| 45 | gas_cost = Uint(32600 * k + 37700) |
| 46 | charge_gas(evm, gas_cost) |
| 47 | |
| 48 | # OPERATION |
| 49 | result = FQ12.one() |
| 50 | for i in range(k): |
| 51 | g1_start = Uint(384 * i) |
| 52 | g2_start = Uint(384 * i + 128) |
| 53 | |
| 54 | g1_slice = data[g1_start : g1_start + Uint(128)] |
| 55 | g1_point = bytes_to_g1(bytes(g1_slice)) |
| 56 | if not is_inf(bls12_multiply(g1_point, curve_order)): |
| 57 | raise InvalidParameter("Sub-group check failed for G1 point.") |
| 58 | |
| 59 | g2_slice = data[g2_start : g2_start + Uint(256)] |
| 60 | g2_point = bytes_to_g2(bytes(g2_slice)) |
| 61 | if not is_inf(bls12_multiply(g2_point, curve_order)): |
| 62 | raise InvalidParameter("Sub-group check failed for G2 point.") |
| 63 | |
| 64 | result *= pairing(g2_point, g1_point) |
| 65 | |
| 66 | if result == FQ12.one(): |
| 67 | evm.output = b"\x00" * 31 + b"\x01" |
| 68 | else: |
| 69 | evm.output = b"\x00" * 32 |