ethereum.prague.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
41 | 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:
45 | """ |
---|---|
46 | The bls12_381 G1 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 | data = evm.message.data |
59 | if len(data) != 256: |
60 | raise InvalidParameter("Invalid Input Length") |
61 | |
62 | # GAS |
63 | charge_gas(evm, Uint(GAS_BLS_G1_ADD)) |
64 | |
65 | # OPERATION |
66 | p1 = bytes_to_g1(buffer_read(data, U256(0), U256(128))) |
67 | p2 = bytes_to_g1(buffer_read(data, U256(128), U256(128))) |
68 | |
69 | result = bls12_add(p1, p2) |
70 | |
71 | evm.output = g1_to_bytes(result) |
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:
75 | """ |
---|---|
76 | The bls12_381 G1 multi-scalar multiplication precompile. |
77 | Note: This uses the naive approach to multi-scalar multiplication |
78 | which is not suitably optimized for production clients. Clients are |
79 | required to implement a more efficient algorithm such as the Pippenger |
80 | algorithm. |
81 |
|
82 | Parameters |
83 | ---------- |
84 | evm : |
85 | The current EVM frame. |
86 |
|
87 | Raises |
88 | ------ |
89 | InvalidParameter |
90 | If the input length is invalid. |
91 | """ |
92 | data = evm.message.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 = Uint(k) * GAS_BLS_G1_MUL * discount // MULTIPLIER |
104 | charge_gas(evm, gas_cost) |
105 | |
106 | # OPERATION |
107 | for i in range(k): |
108 | start_index = i * LENGTH_PER_PAIR |
109 | end_index = start_index + LENGTH_PER_PAIR |
110 |
|
111 | p, m = decode_g1_scalar_pair(data[start_index:end_index]) |
112 | product = bls12_multiply(p, m) |
113 |
|
114 | if i == 0: |
115 | result = product |
116 | else: |
117 | result = bls12_add(result, product) |
118 | |
119 | evm.output = g1_to_bytes(result) |
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:
123 | """ |
---|---|
124 | Precompile to map field element to G1. |
125 |
|
126 | Parameters |
127 | ---------- |
128 | evm : |
129 | The current EVM frame. |
130 |
|
131 | Raises |
132 | ------ |
133 | InvalidParameter |
134 | If the input length is invalid. |
135 | """ |
136 | data = evm.message.data |
137 | if len(data) != 64: |
138 | raise InvalidParameter("Invalid Input Length") |
139 | |
140 | # GAS |
141 | charge_gas(evm, Uint(GAS_BLS_G1_MAP)) |
142 | |
143 | # OPERATION |
144 | fp = int.from_bytes(data, "big") |
145 | if fp >= FQ.field_modulus: |
146 | raise InvalidParameter("coordinate >= field modulus") |
147 | |
148 | g1_optimized_3d = clear_cofactor_G1(map_to_curve_G1(FQ(fp))) |
149 | evm.output = g1_to_bytes(g1_optimized_3d) |