@@ -41,6 +41,25 @@ inline constexpr int64_t cost_per_input_word(size_t input_size) noexcept
4141{
4242 return BaseCost + WordCost * num_words (input_size);
4343}
44+
45+ int64_t bls_msm_cost (size_t k, int64_t multiplication_cost) noexcept
46+ {
47+ assert (k > 0 );
48+
49+ static constexpr int64_t MULTIPLIER = 1000 ;
50+ static constexpr int16_t DISCOUNT [128 ] = {1200 , 888 , 764 , 641 , 594 , 547 , 500 , 453 , 438 , 423 ,
51+ 408 , 394 , 379 , 364 , 349 , 334 , 330 , 326 , 322 , 318 , 314 , 310 , 306 , 302 , 298 , 294 , 289 , 285 ,
52+ 281 , 277 , 273 , 269 , 268 , 266 , 265 , 263 , 262 , 260 , 259 , 257 , 256 , 254 , 253 , 251 , 250 , 248 ,
53+ 247 , 245 , 244 , 242 , 241 , 239 , 238 , 236 , 235 , 233 , 232 , 231 , 229 , 228 , 226 , 225 , 223 , 222 ,
54+ 221 , 220 , 219 , 219 , 218 , 217 , 216 , 216 , 215 , 214 , 213 , 213 , 212 , 211 , 211 , 210 , 209 , 208 ,
55+ 208 , 207 , 206 , 205 , 205 , 204 , 203 , 202 , 202 , 201 , 200 , 199 , 199 , 198 , 197 , 196 , 196 , 195 ,
56+ 194 , 193 , 193 , 192 , 191 , 191 , 190 , 189 , 188 , 188 , 187 , 186 , 185 , 185 , 184 , 183 , 182 , 182 ,
57+ 181 , 180 , 179 , 179 , 178 , 177 , 176 , 176 , 175 , 174 };
58+
59+ const auto d = DISCOUNT [std::min (k, std::size (DISCOUNT )) - 1 ];
60+ return (static_cast <int64_t >(k) * multiplication_cost * d) / MULTIPLIER ;
61+ }
62+
4463} // namespace
4564
4665PrecompileAnalysis ecrecover_analyze (bytes_view /* input*/ , evmc_revision /* rev*/ ) noexcept
@@ -166,10 +185,13 @@ PrecompileAnalysis bls12_g1mul_analyze(bytes_view, evmc_revision) noexcept
166185 return {BLS12_G1MUL_PRECOMPILE_GAS , 128 };
167186}
168187
169- PrecompileAnalysis bls12_g1msm_analyze (bytes_view, evmc_revision) noexcept
188+ PrecompileAnalysis bls12_g1msm_analyze (bytes_view input , evmc_revision) noexcept
170189{
171- // TODO: Implement
172- return {GasCostMax, 0 };
190+ if (input.empty () || input.size () % 160 != 0 )
191+ return {GasCostMax, 0 };
192+
193+ static constexpr auto BLS12_G1MUL_PRECOMPILE_GAS = 12000 ;
194+ return {bls_msm_cost (input.size () / 160 , BLS12_G1MUL_PRECOMPILE_GAS ), 128 };
173195}
174196
175197PrecompileAnalysis bls12_g2add_analyze (bytes_view, evmc_revision) noexcept
@@ -184,10 +206,13 @@ PrecompileAnalysis bls12_g2mul_analyze(bytes_view, evmc_revision) noexcept
184206 return {BLS12_G2MUL_PRECOMPILE_GAS , 256 };
185207}
186208
187- PrecompileAnalysis bls12_g2msm_analyze (bytes_view, evmc_revision) noexcept
209+ PrecompileAnalysis bls12_g2msm_analyze (bytes_view input , evmc_revision) noexcept
188210{
189- // TODO: Implement
190- return {GasCostMax, 0 };
211+ if (input.empty () || input.size () % 288 != 0 )
212+ return {GasCostMax, 0 };
213+
214+ static constexpr auto BLS12_G2MUL_PRECOMPILE_GAS = 45000 ;
215+ return {bls_msm_cost (input.size () / 288 , BLS12_G2MUL_PRECOMPILE_GAS ), 256 };
191216}
192217
193218PrecompileAnalysis bls12_pairing_check_analyze (bytes_view, evmc_revision) noexcept
@@ -375,9 +400,18 @@ ExecutionResult bls12_g1mul_execute(const uint8_t* input, size_t input_size, uin
375400 return {EVMC_SUCCESS , 128 };
376401}
377402
378- ExecutionResult bls12_g1msm_execute (const uint8_t *, size_t , uint8_t *, size_t ) noexcept
403+ ExecutionResult bls12_g1msm_execute (const uint8_t * input, size_t input_size, uint8_t * output,
404+ [[maybe_unused]] size_t output_size) noexcept
379405{
380- return {EVMC_PRECOMPILE_FAILURE , 0 };
406+ if (input_size % 160 != 0 )
407+ return {EVMC_PRECOMPILE_FAILURE , 0 };
408+
409+ assert (output_size == 128 );
410+
411+ if (!crypto::bls::g1_msm (output, &output[64 ], input, input_size))
412+ return {EVMC_PRECOMPILE_FAILURE , 0 };
413+
414+ return {EVMC_SUCCESS , 128 };
381415}
382416
383417ExecutionResult bls12_g2add_execute (const uint8_t * input, size_t input_size, uint8_t * output,
@@ -408,9 +442,18 @@ ExecutionResult bls12_g2mul_execute(const uint8_t* input, size_t input_size, uin
408442 return {EVMC_SUCCESS , 256 };
409443}
410444
411- ExecutionResult bls12_g2msm_execute (const uint8_t *, size_t , uint8_t *, size_t ) noexcept
445+ ExecutionResult bls12_g2msm_execute (const uint8_t * input, size_t input_size, uint8_t * output,
446+ [[maybe_unused]] size_t output_size) noexcept
412447{
413- return {EVMC_PRECOMPILE_FAILURE , 0 };
448+ if (input_size % 288 != 0 )
449+ return {EVMC_PRECOMPILE_FAILURE , 0 };
450+
451+ assert (output_size == 256 );
452+
453+ if (!crypto::bls::g2_msm (output, &output[128 ], input, input_size))
454+ return {EVMC_PRECOMPILE_FAILURE , 0 };
455+
456+ return {EVMC_SUCCESS , 256 };
414457}
415458
416459ExecutionResult bls12_pairing_check_execute (const uint8_t *, size_t , uint8_t *, size_t ) noexcept
0 commit comments