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 |