Skip to content
This repository was archived by the owner on Feb 9, 2025. It is now read-only.

Commit 7f0d0e0

Browse files
pdobaczchfast
andcommitted
precompiles: plug-in EVMMAX ecrecover
Use EVMMAX-based secp256k1 ecrecovery implementation for the precompile. Co-authored-by: Paweł Bylica <pawel@ethereum.org>
1 parent 9d2764d commit 7f0d0e0

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

test/state/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
add_library(evmone-state STATIC)
66
add_library(evmone::state ALIAS evmone-state)
7-
target_link_libraries(evmone-state PUBLIC evmc::evmc_cpp PRIVATE evmone ethash::keccak)
7+
target_link_libraries(evmone-state PUBLIC evmc::evmc_cpp PRIVATE evmone evmone::precompiles ethash::keccak)
88
target_include_directories(evmone-state PRIVATE ${evmone_private_include_dir})
99
target_sources(
1010
evmone-state PRIVATE

test/state/precompiles.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "precompiles.hpp"
66
#include "precompiles_cache.hpp"
7+
#include <evmone_precompiles/secp256k1.hpp>
78
#include <intx/intx.hpp>
89
#include <bit>
910
#include <cassert>
@@ -142,6 +143,37 @@ PrecompileAnalysis expmod_analyze(bytes_view input, evmc_revision rev) noexcept
142143
static_cast<size_t>(mod_len)};
143144
}
144145

146+
ExecutionResult ecrecover_execute(const uint8_t* input, size_t input_size, uint8_t* output,
147+
[[maybe_unused]] size_t output_size) noexcept
148+
{
149+
assert(output_size >= 32);
150+
151+
uint8_t input_buffer[128]{};
152+
if (input_size != 0)
153+
std::memcpy(input_buffer, input, std::min(input_size, std::size(input_buffer)));
154+
155+
ethash::hash256 h{};
156+
std::memcpy(h.bytes, input_buffer, sizeof(h));
157+
158+
const auto v = intx::be::unsafe::load<intx::uint256>(input_buffer + 32);
159+
if (v != 27 && v != 28)
160+
return {EVMC_SUCCESS, 0};
161+
const bool parity = v == 28;
162+
163+
const auto r = intx::be::unsafe::load<intx::uint256>(input_buffer + 64);
164+
const auto s = intx::be::unsafe::load<intx::uint256>(input_buffer + 96);
165+
166+
const auto res = evmmax::secp256k1::ecrecover(h, r, s, parity);
167+
if (res)
168+
{
169+
std::memset(output, 0, 12);
170+
std::memcpy(output + 12, res->bytes, 20);
171+
return {EVMC_SUCCESS, 32};
172+
}
173+
else
174+
return {EVMC_SUCCESS, 0};
175+
}
176+
145177
ExecutionResult identity_execute(const uint8_t* input, size_t input_size, uint8_t* output,
146178
[[maybe_unused]] size_t output_size) noexcept
147179
{
@@ -166,7 +198,7 @@ ExecutionResult dummy_execute(const uint8_t*, size_t, uint8_t*, size_t) noexcept
166198
inline constexpr auto traits = []() noexcept {
167199
std::array<PrecompileTraits, NumPrecompiles> tbl{{
168200
{}, // undefined for 0
169-
{ecrecover_analyze, dummy_execute<PrecompileId::ecrecover>},
201+
{ecrecover_analyze, ecrecover_execute},
170202
{sha256_analyze, dummy_execute<PrecompileId::sha256>},
171203
{ripemd160_analyze, dummy_execute<PrecompileId::ripemd160>},
172204
{identity_analyze, identity_execute},
@@ -177,7 +209,7 @@ inline constexpr auto traits = []() noexcept {
177209
{blake2bf_analyze, dummy_execute<PrecompileId::blake2bf>},
178210
}};
179211
#ifdef EVMONE_PRECOMPILES_SILKPRE
180-
tbl[static_cast<size_t>(PrecompileId::ecrecover)].execute = silkpre_ecrecover_execute;
212+
// tbl[static_cast<size_t>(PrecompileId::ecrecover)].execute = silkpre_ecrecover_execute;
181213
tbl[static_cast<size_t>(PrecompileId::sha256)].execute = silkpre_sha256_execute;
182214
tbl[static_cast<size_t>(PrecompileId::ripemd160)].execute = silkpre_ripemd160_execute;
183215
tbl[static_cast<size_t>(PrecompileId::expmod)].execute = silkpre_expmod_execute;

0 commit comments

Comments
 (0)