Skip to content

Commit

Permalink
precompiles: Implement bls g1 mul
Browse files Browse the repository at this point in the history
  • Loading branch information
rodiazet committed Sep 10, 2024
1 parent 60dd68d commit 8223283
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
30 changes: 30 additions & 0 deletions lib/evmone_precompiles/bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ namespace evmone::crypto::bls
{
namespace
{
using namespace intx::literals;

constexpr auto FP_BYTES_OFFSET = 64 - 48;
constexpr size_t BLS_MODULUS_BITS = 255;
constexpr auto MAIN_SUBGROUP_ORDER =
0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001_u256;

[[nodiscard]] std::optional<blst_p1_affine> validate_point(
const uint8_t _x[64], const uint8_t _y[64]) noexcept
Expand Down Expand Up @@ -63,4 +68,29 @@ void store_result(uint8_t _rx[64], uint8_t _ry[64], const blst_p1* out) noexcept

return true;
}

[[nodiscard]] bool g1_mul(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x[64],
const uint8_t _y[64], const uint8_t _c[32]) noexcept
{
const auto c = intx::be::unsafe::load<intx::uint256>(_c) % MAIN_SUBGROUP_ORDER;
blst_scalar scalar;
blst_scalar_from_uint64(&scalar, as_words(c));

const auto p_affine = validate_point(_x, _y);
if (!p_affine.has_value())
return false;

blst_p1 p;
blst_p1_from_affine(&p, &p_affine.value());

if (!blst_p1_in_g1(&p))
return false;

blst_p1 out;
blst_p1_mult(&out, &p, scalar.b, BLS_MODULUS_BITS);

store_result(_rx, _ry, &out);

return true;
}
} // namespace evmone::crypto::bls
6 changes: 6 additions & 0 deletions lib/evmone_precompiles/bls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ inline constexpr auto BLS_FIELD_MODULUS =
[[nodiscard]] bool g1_add(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x0[64],
const uint8_t _y0[64], const uint8_t _x1[64], const uint8_t _y1[64]) noexcept;

/// Scalar multiplication in bls12-381 curve group.
///
/// Computes [c]P for a point in affine coordinate on the bls12-381 curve,
[[nodiscard]] bool g1_mul(uint8_t _rx[64], uint8_t _ry[64], const uint8_t _x[64],
const uint8_t _y[64], const uint8_t _c[32]) noexcept;

} // namespace evmone::crypto::bls
17 changes: 13 additions & 4 deletions test/state/precompiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ PrecompileAnalysis bls12_g1add_analyze(bytes_view, evmc_revision) noexcept

PrecompileAnalysis bls12_g1mul_analyze(bytes_view, evmc_revision) noexcept
{
// TODO: Implement
return {GasCostMax, 0};
static constexpr auto BLS12_G1MUL_PRECOMPILE_GAS = 12000;
return {BLS12_G1MUL_PRECOMPILE_GAS, 128};
}

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

ExecutionResult bls12_g1mul_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept
ExecutionResult bls12_g1mul_execute(const uint8_t* input, size_t input_size, uint8_t* output,
[[maybe_unused]] size_t output_size) noexcept
{
return {EVMC_PRECOMPILE_FAILURE, 0};
if (input_size != 160)
return {EVMC_PRECOMPILE_FAILURE, 0};

assert(output_size == 128);

if (!crypto::bls::g1_mul(output, &output[64], input, &input[64], &input[128]))
return {EVMC_PRECOMPILE_FAILURE, 0};

return {EVMC_SUCCESS, 128};
}

ExecutionResult bls12_g1msm_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept
Expand Down
22 changes: 22 additions & 0 deletions test/unittests/precompiles_bls_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,25 @@ TEST(bls, g1_add_not_on_curve)
evmone::crypto::bls::g1_add(rx, ry, x0.data(), y0.data(), x1.data(), y1.data()));
}
}

TEST(bls, g1_mul)
{
const auto x =
"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"_hex;
const auto y =
"0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"_hex;
const auto c = "0000000000000000000000000000000000000000000000000000000000000002"_hex;

uint8_t rx[64];
uint8_t ry[64];

EXPECT_TRUE(evmone::crypto::bls::g1_mul(rx, ry, x.data(), y.data(), c.data()));

const auto expected_x =
"000000000000000000000000000000000572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e"_hex;
const auto expected_y =
"00000000000000000000000000000000166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"_hex;

EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
}

0 comments on commit 8223283

Please sign in to comment.