ethereum.forks.amsterdam.vm.precompiled_contracts.bls12_381.bls12_381_g1
Ethereum Virtual Machine (EVM) BLS12 381 CONTRACTS.
.. contents:: Table of Contents :backlinks: none :local:
Introduction
Implementation of pre-compiles in G1 (curve over base prime field).
LENGTH_PER_PAIR¶
| 36 | LENGTH_PER_PAIR = 160 |
|---|
bls12_g1_add ¶
The bls12_381 G1 point addition precompile.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid.
def bls12_g1_add(evm: Evm) -> None:
| 40 | <snip> |
|---|---|
| 54 | data = evm.call_data |
| 55 | if len(data) != 256: |
| 56 | raise InvalidParameter("Invalid Input Length") |
| 57 | |
| 58 | # GAS |
| 59 | charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1ADD) |
| 60 | |
| 61 | # OPERATION |
| 62 | p1 = unpad_g1(data[:128]) |
| 63 | p2 = unpad_g1(data[128:256]) |
| 64 | |
| 65 | try: |
| 66 | raw = g1_add(p1, p2) |
| 67 | except InvalidInputError as e: |
| 68 | raise InvalidParameter(str(e)) from e |
| 69 | |
| 70 | evm.output = pad_g1(raw) |
bls12_g1_msm ¶
The bls12_381 G1 multi-scalar multiplication precompile. Note: This uses the naive approach to multi-scalar multiplication which is not suitably optimized for production clients. Clients are required to implement a more efficient algorithm such as the Pippenger algorithm.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid.
def bls12_g1_msm(evm: Evm) -> None:
| 74 | <snip> |
|---|---|
| 92 | data = evm.call_data |
| 93 | if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0: |
| 94 | raise InvalidParameter("Invalid Input Length") |
| 95 | |
| 96 | # GAS |
| 97 | k = len(data) // LENGTH_PER_PAIR |
| 98 | if k <= 128: |
| 99 | discount = Uint(G1_K_DISCOUNT[k - 1]) |
| 100 | else: |
| 101 | discount = Uint(G1_MAX_DISCOUNT) |
| 102 | |
| 103 | gas_cost = ExecutionGas( |
| 104 | Uint(k) * GasCosts.PRECOMPILE_BLS_G1MUL * discount // MULTIPLIER |
| 105 | ) |
| 106 | charge_gas(evm, gas_cost) |
| 107 | |
| 108 | # OPERATION |
| 109 | points = [] |
| 110 | scalars = [] |
| 111 | for i in range(k): |
| 112 | start = i * LENGTH_PER_PAIR |
| 113 | points.append(unpad_g1(data[start : start + 128])) |
| 114 | scalars.append(data[start + 128 : start + LENGTH_PER_PAIR]) |
| 115 | |
| 116 | try: |
| 117 | raw = g1_msm(points, scalars) |
| 118 | except InvalidInputError as e: |
| 119 | raise InvalidParameter(str(e)) from e |
| 120 | |
| 121 | evm.output = pad_g1(raw) |
bls12_map_fp_to_g1 ¶
Precompile to map field element to G1.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid.
def bls12_map_fp_to_g1(evm: Evm) -> None:
| 125 | <snip> |
|---|---|
| 139 | data = evm.call_data |
| 140 | if len(data) != 64: |
| 141 | raise InvalidParameter("Invalid Input Length") |
| 142 | |
| 143 | # GAS |
| 144 | charge_gas(evm, GasCosts.PRECOMPILE_BLS_G1MAP) |
| 145 | |
| 146 | # OPERATION |
| 147 | fp = unpad_fp(data) |
| 148 | |
| 149 | try: |
| 150 | raw = map_fp_to_g1(fp) |
| 151 | except InvalidInputError as e: |
| 152 | raise InvalidParameter(str(e)) from e |
| 153 | |
| 154 | evm.output = pad_g1(raw) |