ethereum.forks.prague.vm.precompiled_contracts.bls12_381.bls12_381_g2ethereum.forks.osaka.vm.precompiled_contracts.bls12_381.bls12_381_g2
Ethereum Virtual Machine (EVM) BLS12 381 G2 CONTRACTS.
.. contents:: Table of Contents :backlinks: none :local:
Introduction
Implementation of pre-compiles in G2 (curve over base prime field).
LENGTH_PER_PAIR
41 | LENGTH_PER_PAIR = 288 |
---|
bls12_g2_add
The bls12_381 G2 point addition precompile.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid.
def bls12_g2_add(evm: Evm) -> None:
45 | """ |
---|---|
46 | The bls12_381 G2 point addition precompile. |
47 |
|
48 | Parameters |
49 | ---------- |
50 | evm : |
51 | The current EVM frame. |
52 |
|
53 | Raises |
54 | ------ |
55 | InvalidParameter |
56 | If the input length is invalid. |
57 |
|
58 | """ |
59 | data = evm.message.data |
60 | if len(data) != 512: |
61 | raise InvalidParameter("Invalid Input Length") |
62 | |
63 | # GAS |
64 | charge_gas(evm, Uint(GAS_BLS_G2_ADD)) |
65 | |
66 | # OPERATION |
67 | p1 = bytes_to_g2(buffer_read(data, U256(0), U256(256))) |
68 | p2 = bytes_to_g2(buffer_read(data, U256(256), U256(256))) |
69 | |
70 | result = bls12_add(p1, p2) |
71 | |
72 | evm.output = g2_to_bytes(result) |
bls12_g2_msm
The bls12_381 G2 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_g2_msm(evm: Evm) -> None:
76 | """ |
---|---|
77 | The bls12_381 G2 multi-scalar multiplication precompile. |
78 | Note: This uses the naive approach to multi-scalar multiplication |
79 | which is not suitably optimized for production clients. Clients are |
80 | required to implement a more efficient algorithm such as the Pippenger |
81 | algorithm. |
82 |
|
83 | Parameters |
84 | ---------- |
85 | evm : |
86 | The current EVM frame. |
87 |
|
88 | Raises |
89 | ------ |
90 | InvalidParameter |
91 | If the input length is invalid. |
92 |
|
93 | """ |
94 | data = evm.message.data |
95 | if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0: |
96 | raise InvalidParameter("Invalid Input Length") |
97 | |
98 | # GAS |
99 | k = len(data) // LENGTH_PER_PAIR |
100 | if k <= 128: |
101 | discount = Uint(G2_K_DISCOUNT[k - 1]) |
102 | else: |
103 | discount = Uint(G2_MAX_DISCOUNT) |
104 | |
105 | gas_cost = Uint(k) * GAS_BLS_G2_MUL * discount // MULTIPLIER |
106 | charge_gas(evm, gas_cost) |
107 | |
108 | # OPERATION |
109 | for i in range(k): |
110 | start_index = i * LENGTH_PER_PAIR |
111 | end_index = start_index + LENGTH_PER_PAIR |
112 |
|
113 | p, m = decode_g2_scalar_pair(data[start_index:end_index]) |
114 | product = bls12_multiply(p, m) |
115 |
|
116 | if i == 0: |
117 | result = product |
118 | else: |
119 | result = bls12_add(result, product) |
120 | |
121 | evm.output = g2_to_bytes(result) |
bls12_map_fp2_to_g2
Precompile to map field element to G2.
Parameters
evm : The current EVM frame.
Raises
InvalidParameter If the input length is invalid.
def bls12_map_fp2_to_g2(evm: Evm) -> None:
125 | """ |
---|---|
126 | Precompile to map field element to G2. |
127 |
|
128 | Parameters |
129 | ---------- |
130 | evm : |
131 | The current EVM frame. |
132 |
|
133 | Raises |
134 | ------ |
135 | InvalidParameter |
136 | If the input length is invalid. |
137 |
|
138 | """ |
139 | data = evm.message.data |
140 | if len(data) != 128: |
141 | raise InvalidParameter("Invalid Input Length") |
142 | |
143 | # GAS |
144 | charge_gas(evm, Uint(GAS_BLS_G2_MAP)) |
145 | |
146 | # OPERATION |
147 | field_element = bytes_to_fq2(data) |
148 | assert isinstance(field_element, FQ2) |
149 | |
150 | fp2 = bytes_to_fq2(data) |
151 | g2_3d = clear_cofactor_G2(map_to_curve_G2(fp2)) |
152 | |
153 | evm.output = g2_to_bytes(g2_3d) |