Skip to content

Commit 525eb35

Browse files
committed
precompiles: Implement bls g1 mul
1 parent 12766de commit 525eb35

File tree

5 files changed

+72
-4
lines changed

5 files changed

+72
-4
lines changed

circle.yml

+1
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ jobs:
374374
~/build/bin/evmone-statetest
375375
prague/eip2537_bls_12_381_precompiles/bls12_precompiles_before_fork
376376
prague/eip2537_bls_12_381_precompiles/bls12_g1add
377+
prague/eip2537_bls_12_381_precompiles/bls12_g1mul
377378
- collect_coverage_gcc
378379
- upload_coverage:
379380
flags: execution_spec_tests

lib/evmone_precompiles/bls.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ namespace evmone::crypto::bls
66
{
77
namespace
88
{
9+
using namespace intx::literals;
10+
911
/// Offset of the beginning of field element. First 16 bytes must be zero according to spec
1012
/// https://eips.ethereum.org/EIPS/eip-2537#field-elements-encoding
1113
constexpr auto FP_BYTES_OFFSET = 64 - 48;
14+
constexpr size_t BLS_MODULUS_BITS = 255;
15+
constexpr auto MAIN_SUBGROUP_ORDER =
16+
0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001_u256;
1217

1318
/// Validates p1 affine point. Checks that point coordinates are from the BLS12-381 field and
1419
/// that the point is on curve. https://eips.ethereum.org/EIPS/eip-2537#abi-for-g1-addition
@@ -68,4 +73,29 @@ void store_result(uint8_t _rx[64], uint8_t _ry[64], const blst_p1* out) noexcept
6873

6974
return true;
7075
}
76+
77+
[[nodiscard]] bool g1_mul(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x[64],
78+
const uint8_t _y[64], const uint8_t _c[32]) noexcept
79+
{
80+
const auto c = intx::be::unsafe::load<intx::uint256>(_c) % MAIN_SUBGROUP_ORDER;
81+
blst_scalar scalar;
82+
blst_scalar_from_uint64(&scalar, as_words(c));
83+
84+
const auto p_affine = validate_point(_x, _y);
85+
if (!p_affine.has_value())
86+
return false;
87+
88+
blst_p1 p;
89+
blst_p1_from_affine(&p, &*p_affine);
90+
91+
if (!blst_p1_in_g1(&p))
92+
return false;
93+
94+
blst_p1 out;
95+
blst_p1_mult(&out, &p, scalar.b, BLS_MODULUS_BITS);
96+
97+
store_result(_rx, _ry, &out);
98+
99+
return true;
100+
}
71101
} // namespace evmone::crypto::bls

lib/evmone_precompiles/bls.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@ inline constexpr auto BLS_FIELD_MODULUS =
1616
[[nodiscard]] bool g1_add(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x0[64],
1717
const uint8_t _y0[64], const uint8_t _x1[64], const uint8_t _y1[64]) noexcept;
1818

19+
/// Scalar multiplication in BLS12-381 curve group.
20+
///
21+
/// Computes [c]P for a point in affine coordinate on the BLS12-381 curve,
22+
[[nodiscard]] bool g1_mul(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x[64],
23+
const uint8_t _y[64], const uint8_t _c[32]) noexcept;
24+
1925
} // namespace evmone::crypto::bls

test/state/precompiles.cpp

+13-4
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ PrecompileAnalysis bls12_g1add_analyze(bytes_view, evmc_revision) noexcept
162162

163163
PrecompileAnalysis bls12_g1mul_analyze(bytes_view, evmc_revision) noexcept
164164
{
165-
// TODO: Implement
166-
return {GasCostMax, 0};
165+
static constexpr auto BLS12_G1MUL_PRECOMPILE_GAS = 12000;
166+
return {BLS12_G1MUL_PRECOMPILE_GAS, 128};
167167
}
168168

169169
PrecompileAnalysis bls12_g1msm_analyze(bytes_view, evmc_revision) noexcept
@@ -361,9 +361,18 @@ ExecutionResult bls12_g1add_execute(const uint8_t* input, size_t input_size, uin
361361
return {EVMC_SUCCESS, 128};
362362
}
363363

364-
ExecutionResult bls12_g1mul_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept
364+
ExecutionResult bls12_g1mul_execute(const uint8_t* input, size_t input_size, uint8_t* output,
365+
[[maybe_unused]] size_t output_size) noexcept
365366
{
366-
return {EVMC_PRECOMPILE_FAILURE, 0};
367+
if (input_size != 160)
368+
return {EVMC_PRECOMPILE_FAILURE, 0};
369+
370+
assert(output_size == 128);
371+
372+
if (!crypto::bls::g1_mul(output, &output[64], input, &input[64], &input[128]))
373+
return {EVMC_PRECOMPILE_FAILURE, 0};
374+
375+
return {EVMC_SUCCESS, 128};
367376
}
368377

369378
ExecutionResult bls12_g1msm_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept

test/unittests/precompiles_bls_test.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,25 @@ TEST(bls, g1_add_not_on_curve)
7070
evmone::crypto::bls::g1_add(rx, ry, x0.data(), y0.data(), x1.data(), y1.data()));
7171
}
7272
}
73+
74+
TEST(bls, g1_mul)
75+
{
76+
const auto x =
77+
"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"_hex;
78+
const auto y =
79+
"0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"_hex;
80+
const auto c = "0000000000000000000000000000000000000000000000000000000000000002"_hex;
81+
82+
uint8_t rx[64];
83+
uint8_t ry[64];
84+
85+
EXPECT_TRUE(evmone::crypto::bls::g1_mul(rx, ry, x.data(), y.data(), c.data()));
86+
87+
const auto expected_x =
88+
"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e"_hex;
89+
const auto expected_y =
90+
"00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"_hex;
91+
92+
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
93+
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
94+
}

0 commit comments

Comments
 (0)