Skip to content

Commit d3de72d

Browse files
rodiazetchfast
andauthored
precompiles: Implement BLS multi scalar multiplication (#1010)
Implementation of the `bls12_g1msm` and `bls12_g2msm` precompiles: multi scalar affine points' multiplication from BLS12-381 curve according to the EIP-2537 spec https://eips.ethereum.org/EIPS/eip-2537#abi-for-g1-msm and https://eips.ethereum.org/EIPS/eip-2537#abi-for-g2-msm. Co-authored-by: Paweł Bylica <pawel@ethereum.org>
1 parent 335d056 commit d3de72d

5 files changed

Lines changed: 320 additions & 10 deletions

File tree

circle.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ jobs:
377377
prague/eip2537_bls_12_381_precompiles/bls12_g1mul
378378
prague/eip2537_bls_12_381_precompiles/bls12_g2add
379379
prague/eip2537_bls_12_381_precompiles/bls12_g2mul
380+
prague/eip2537_bls_12_381_precompiles/bls12_g1msm
381+
prague/eip2537_bls_12_381_precompiles/bls12_g2msm
380382
- run:
381383
name: "Execution spec tests (develop, blockchain_tests)"
382384
# Tests for in-development EVM revision currently passing.

lib/evmone_precompiles/bls.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "bls.hpp"
22
#include <blst.h>
3+
#include <memory>
34
#include <optional>
5+
#include <vector>
46

57
namespace evmone::crypto::bls
68
{
@@ -183,4 +185,134 @@ void store(uint8_t _rx[128], const blst_fp2& _x) noexcept
183185
return true;
184186
}
185187

188+
[[nodiscard]] bool g1_msm(
189+
uint8_t _rx[64], uint8_t _ry[64], const uint8_t* _xycs, size_t size) noexcept
190+
{
191+
constexpr auto SINGLE_ENTRY_SIZE = (64 * 2 + 32);
192+
assert(size % SINGLE_ENTRY_SIZE == 0);
193+
auto npoints = size / SINGLE_ENTRY_SIZE;
194+
195+
std::vector<blst_p1_affine> p1_affines;
196+
std::vector<const blst_p1_affine*> p1_affine_ptrs;
197+
p1_affines.reserve(npoints);
198+
p1_affine_ptrs.reserve(npoints);
199+
200+
std::vector<blst_scalar> scalars;
201+
std::vector<const uint8_t*> scalars_ptrs;
202+
scalars.reserve(npoints);
203+
scalars_ptrs.reserve(npoints);
204+
205+
auto ptr = _xycs;
206+
for (size_t i = 0; i < npoints; ++i)
207+
{
208+
const auto p_affine = validate_p1(ptr, &ptr[64]);
209+
if (!p_affine.has_value())
210+
return false;
211+
212+
if (!blst_p1_affine_in_g1(&*p_affine))
213+
return false;
214+
215+
// Point at infinity must be filtered out for BLST library.
216+
if (blst_p1_affine_is_inf(&*p_affine))
217+
continue;
218+
219+
const auto& p = p1_affines.emplace_back(*p_affine);
220+
p1_affine_ptrs.emplace_back(&p);
221+
222+
blst_scalar scalar;
223+
blst_scalar_from_bendian(&scalar, &ptr[128]);
224+
const auto& s = scalars.emplace_back(scalar);
225+
scalars_ptrs.emplace_back(s.b);
226+
227+
ptr += SINGLE_ENTRY_SIZE;
228+
}
229+
230+
npoints = p1_affine_ptrs.size();
231+
232+
if (npoints == 0)
233+
{
234+
memset(_rx, 0, 64);
235+
memset(_ry, 0, 64);
236+
return true;
237+
}
238+
239+
const auto scratch_size = blst_p1s_mult_pippenger_scratch_sizeof(npoints) / sizeof(limb_t);
240+
const auto scratch_space = std::make_unique_for_overwrite<limb_t[]>(scratch_size);
241+
blst_p1 out;
242+
blst_p1s_mult_pippenger(
243+
&out, p1_affine_ptrs.data(), npoints, scalars_ptrs.data(), 256, scratch_space.get());
244+
245+
blst_p1_affine result;
246+
blst_p1_to_affine(&result, &out);
247+
store(_rx, result.x);
248+
store(_ry, result.y);
249+
250+
return true;
251+
}
252+
253+
[[nodiscard]] bool g2_msm(
254+
uint8_t _rx[128], uint8_t _ry[128], const uint8_t* _xycs, size_t size) noexcept
255+
{
256+
constexpr auto SINGLE_ENTRY_SIZE = (128 * 2 + 32);
257+
assert(size % SINGLE_ENTRY_SIZE == 0);
258+
auto npoints = size / SINGLE_ENTRY_SIZE;
259+
260+
std::vector<blst_p2_affine> p2_affines;
261+
std::vector<const blst_p2_affine*> p2_affine_ptrs;
262+
p2_affines.reserve(npoints);
263+
p2_affine_ptrs.reserve(npoints);
264+
265+
std::vector<blst_scalar> scalars;
266+
std::vector<const uint8_t*> scalars_ptrs;
267+
scalars.reserve(npoints);
268+
scalars_ptrs.reserve(npoints);
269+
270+
auto ptr = _xycs;
271+
for (size_t i = 0; i < npoints; ++i)
272+
{
273+
const auto p_affine = validate_p2(ptr, &ptr[128]);
274+
if (!p_affine.has_value())
275+
return false;
276+
277+
if (!blst_p2_affine_in_g2(&*p_affine))
278+
return false;
279+
280+
// Point at infinity must be filtered out for BLST library.
281+
if (blst_p2_affine_is_inf(&*p_affine))
282+
continue;
283+
284+
const auto& p = p2_affines.emplace_back(*p_affine);
285+
p2_affine_ptrs.emplace_back(&p);
286+
287+
blst_scalar scalar;
288+
blst_scalar_from_bendian(&scalar, &ptr[256]);
289+
const auto& s = scalars.emplace_back(scalar);
290+
scalars_ptrs.emplace_back(s.b);
291+
292+
ptr += SINGLE_ENTRY_SIZE;
293+
}
294+
295+
npoints = p2_affine_ptrs.size();
296+
297+
if (npoints == 0)
298+
{
299+
memset(_rx, 0, 128);
300+
memset(_ry, 0, 128);
301+
return true;
302+
}
303+
304+
const auto scratch_size = blst_p2s_mult_pippenger_scratch_sizeof(npoints) / sizeof(limb_t);
305+
const auto scratch_space = std::make_unique_for_overwrite<limb_t[]>(scratch_size);
306+
blst_p2 out;
307+
blst_p2s_mult_pippenger(
308+
&out, p2_affine_ptrs.data(), npoints, scalars_ptrs.data(), 256, scratch_space.get());
309+
310+
blst_p2_affine result;
311+
blst_p2_to_affine(&result, &out);
312+
store(_rx, result.x);
313+
store(_ry, result.y);
314+
315+
return true;
316+
}
317+
186318
} // namespace evmone::crypto::bls

lib/evmone_precompiles/bls.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,20 @@ inline constexpr auto BLS_FIELD_MODULUS =
3939
[[nodiscard]] bool g2_mul(uint8_t _rx[128], uint8_t _ry[128], const uint8_t _x[128],
4040
const uint8_t _y[128], const uint8_t _c[32]) noexcept;
4141

42+
/// Multi scalar multiplication in BLS12-381 curve G1 subgroup.
43+
///
44+
/// Computes ∑ⁿₖ₌₁cₖPₖ for points in affine coordinate on the BLS12-381 curve, performs
45+
/// subgroup check according to spec
46+
/// https://eips.ethereum.org/EIPS/eip-2537#abi-for-g1-msm
47+
[[nodiscard]] bool g1_msm(
48+
uint8_t _rx[64], uint8_t _ry[64], const uint8_t* _xycs, size_t size) noexcept;
49+
50+
/// Multi scalar multiplication in BLS12-381 curve G2 subgroup.
51+
///
52+
/// Computes ∑ⁿₖ₌₁cₖPₖ for points in affine coordinate on the BLS12-381 curve over G2 extension
53+
/// field, performs subgroup check according to spec
54+
/// https://eips.ethereum.org/EIPS/eip-2537#abi-for-g2-msm
55+
[[nodiscard]] bool g2_msm(
56+
uint8_t _rx[128], uint8_t _ry[128], const uint8_t* _xycs, size_t size) noexcept;
57+
4258
} // namespace evmone::crypto::bls

test/state/precompiles.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4665
PrecompileAnalysis 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

175197
PrecompileAnalysis 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

193218
PrecompileAnalysis 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

383417
ExecutionResult 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

416459
ExecutionResult bls12_pairing_check_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept

test/unittests/precompiles_bls_test.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,120 @@ TEST(bls, g2_mul)
139139
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
140140
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
141141
}
142+
143+
TEST(bls, g1_msm)
144+
{
145+
using namespace evmc::literals;
146+
auto input =
147+
"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f17"
148+
"1bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e"
149+
"30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000"
150+
"00000000000000000000000000000000000000000000000002"_hex;
151+
uint8_t rx[64];
152+
uint8_t ry[64];
153+
154+
EXPECT_TRUE(evmone::crypto::bls::g1_msm(rx, ry, input.data(), input.size()));
155+
156+
const auto expected_x =
157+
"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e"_hex;
158+
const auto expected_y =
159+
"00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"_hex;
160+
161+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
162+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
163+
}
164+
165+
TEST(bls, g1_msm_inf_0)
166+
{
167+
using namespace evmc::literals;
168+
auto input =
169+
"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000000"_hex;
170+
uint8_t rx[64];
171+
uint8_t ry[64];
172+
173+
EXPECT_TRUE(evmone::crypto::bls::g1_msm(rx, ry, input.data(), input.size()));
174+
175+
const auto expected_x =
176+
"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e"_hex;
177+
const auto expected_y =
178+
"00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"_hex;
179+
180+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
181+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
182+
}
183+
184+
TEST(bls, g1_msm_inf_2)
185+
{
186+
using namespace evmc::literals;
187+
auto input =
188+
"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"_hex;
189+
uint8_t rx[64];
190+
uint8_t ry[64];
191+
192+
EXPECT_TRUE(evmone::crypto::bls::g1_msm(rx, ry, input.data(), input.size()));
193+
194+
const auto expected_x =
195+
"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e"_hex;
196+
const auto expected_y =
197+
"00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"_hex;
198+
199+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
200+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
201+
}
202+
203+
TEST(bls, g2_msm)
204+
{
205+
using namespace evmc::literals;
206+
auto input =
207+
"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002"_hex;
208+
uint8_t rx[128];
209+
uint8_t ry[128];
210+
211+
EXPECT_TRUE(evmone::crypto::bls::g2_msm(rx, ry, input.data(), input.size()));
212+
213+
const auto expected_x =
214+
"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"_hex;
215+
const auto expected_y =
216+
"000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"_hex;
217+
218+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
219+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
220+
}
221+
222+
TEST(bls, g2_msm_inf_0)
223+
{
224+
using namespace evmc::literals;
225+
auto input =
226+
"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000000"_hex;
227+
uint8_t rx[128];
228+
uint8_t ry[128];
229+
230+
EXPECT_TRUE(evmone::crypto::bls::g2_msm(rx, ry, input.data(), input.size()));
231+
232+
const auto expected_x =
233+
"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"_hex;
234+
const auto expected_y =
235+
"000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"_hex;
236+
237+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
238+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
239+
}
240+
241+
TEST(bls, g2_msm_inf_2)
242+
{
243+
using namespace evmc::literals;
244+
auto input =
245+
"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"_hex;
246+
uint8_t rx[128];
247+
uint8_t ry[128];
248+
249+
EXPECT_TRUE(evmone::crypto::bls::g2_msm(rx, ry, input.data(), input.size()));
250+
251+
const auto expected_x =
252+
"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"_hex;
253+
const auto expected_y =
254+
"000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"_hex;
255+
256+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
257+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
258+
}

0 commit comments

Comments
 (0)