Skip to content

Commit

Permalink
precompiles: Implement EIP-2537's bls12_g2mul (#999)
Browse files Browse the repository at this point in the history
Implementation of the `bls12_g2mul` precompile: E2 affine point's
multiplication from BLS12-381 curve according to the EIP-2537 spec
https://eips.ethereum.org/EIPS/eip-2537#abi-for-g2-multiplication.

Depends on #995
  • Loading branch information
rodiazet authored Sep 13, 2024
1 parent 39aec66 commit 1358b17
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 4 deletions.
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ jobs:
prague/eip2537_bls_12_381_precompiles/bls12_g1add
prague/eip2537_bls_12_381_precompiles/bls12_g1mul
prague/eip2537_bls_12_381_precompiles/bls12_g2add
prague/eip2537_bls_12_381_precompiles/bls12_g2mul
- run:
name: "Execution spec tests (develop, blockchain_tests)"
# Tests for in-development EVM revision currently passing.
Expand Down
27 changes: 27 additions & 0 deletions lib/evmone_precompiles/bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,31 @@ void store(uint8_t _rx[128], const blst_fp2& _x) noexcept
return true;
}

[[nodiscard]] bool g2_mul(uint8_t _rx[128], uint8_t _ry[128], const uint8_t _x[128],
const uint8_t _y[128], const uint8_t _c[32]) noexcept
{
blst_scalar scalar;
blst_scalar_from_bendian(&scalar, _c);

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

blst_p2 p;
blst_p2_from_affine(&p, &*p_affine);

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

blst_p2 out;
blst_p2_mult(&out, &p, scalar.b, 256);

blst_p2_affine result;
blst_p2_to_affine(&result, &out);
store(_rx, result.x);
store(_ry, result.y);

return true;
}

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

/// Scalar multiplication in BLS12-381 curve group over G2 extension field
///
/// Computes [c]P for a point in affine coordinate on the BLS12-381 curve over G2 extension
/// field, performs subgroup check according to spec
/// https://eips.ethereum.org/EIPS/eip-2537#abi-for-g2-multiplication
[[nodiscard]] bool g2_mul(uint8_t _rx[128], uint8_t _ry[128], const uint8_t _x[128],
const uint8_t _y[128], 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 @@ -180,8 +180,8 @@ PrecompileAnalysis bls12_g2add_analyze(bytes_view, evmc_revision) noexcept

PrecompileAnalysis bls12_g2mul_analyze(bytes_view, evmc_revision) noexcept
{
// TODO: Implement
return {GasCostMax, 0};
static constexpr auto BLS12_G2MUL_PRECOMPILE_GAS = 45000;
return {BLS12_G2MUL_PRECOMPILE_GAS, 256};
}

PrecompileAnalysis bls12_g2msm_analyze(bytes_view, evmc_revision) noexcept
Expand Down Expand Up @@ -394,9 +394,18 @@ ExecutionResult bls12_g2add_execute(const uint8_t* input, size_t input_size, uin
return {EVMC_SUCCESS, 256};
}

ExecutionResult bls12_g2mul_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept
ExecutionResult bls12_g2mul_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 != 288)
return {EVMC_PRECOMPILE_FAILURE, 0};

assert(output_size == 256);

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

return {EVMC_SUCCESS, 256};
}

ExecutionResult bls12_g2msm_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 @@ -117,3 +117,25 @@ TEST(bls, g2_add)
EXPECT_EQ(evmc::bytes_view(rx, sizeof rx), expected_x);
EXPECT_EQ(evmc::bytes_view(ry, sizeof ry), expected_y);
}

TEST(bls, g2_mul)
{
const auto x =
"00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e"_hex;
const auto y =
"000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"_hex;
const auto c = "0000000000000000000000000000000000000000000000000000000000000002"_hex;

uint8_t rx[128];
uint8_t ry[128];

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

const auto expected_x =
"000000000000000000000000000000001638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053000000000000000000000000000000000a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"_hex;
const auto expected_y =
"000000000000000000000000000000000468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899000000000000000000000000000000000f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"_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 1358b17

Please sign in to comment.