ethereum.prague.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
42 | 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:
46 | """ |
---|---|
47 | The bls12_381 G2 point addition precompile. |
48 |
|
49 | Parameters |
50 | ---------- |
51 | evm : |
52 | The current EVM frame. |
53 |
|
54 | Raises |
55 | ------ |
56 | InvalidParameter |
57 | If the input length is invalid. |
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 | data = evm.message.data |
94 | if len(data) == 0 or len(data) % LENGTH_PER_PAIR != 0: |
95 | raise InvalidParameter("Invalid Input Length") |
96 | |
97 | # GAS |
98 | k = len(data) // LENGTH_PER_PAIR |
99 | if k <= 128: |
100 | discount = Uint(G2_K_DISCOUNT[k - 1]) |
101 | else: |
102 | discount = Uint(G2_MAX_DISCOUNT) |
103 | |
104 | gas_cost = Uint(k) * GAS_BLS_G2_MUL * discount // MULTIPLIER |
105 | charge_gas(evm, gas_cost) |
106 | |
107 | # OPERATION |
108 | for i in range(k): |
109 | start_index = i * LENGTH_PER_PAIR |
110 | end_index = start_index + LENGTH_PER_PAIR |
111 |
|
112 | p, m = decode_g2_scalar_pair(data[start_index:end_index]) |
113 | product = bls12_multiply(p, m) |
114 |
|
115 | if i == 0: |
116 | result = product |
117 | else: |
118 | result = bls12_add(result, product) |
119 | |
120 | 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:
124 | """ |
---|---|
125 | Precompile to map field element to G2. |
126 |
|
127 | Parameters |
128 | ---------- |
129 | evm : |
130 | The current EVM frame. |
131 |
|
132 | Raises |
133 | ------ |
134 | InvalidParameter |
135 | If the input length is invalid. |
136 | """ |
137 | data = evm.message.data |
138 | if len(data) != 128: |
139 | raise InvalidParameter("Invalid Input Length") |
140 | |
141 | # GAS |
142 | charge_gas(evm, Uint(GAS_BLS_G2_MAP)) |
143 | |
144 | # OPERATION |
145 | field_element = bytes_to_fq2(data) |
146 | assert isinstance(field_element, FQ2) |
147 | |
148 | fp2 = bytes_to_fq2(data) |
149 | g2_3d = clear_cofactor_G2(map_to_curve_G2(fp2)) |
150 | |
151 | evm.output = g2_to_bytes(g2_3d) |