-
Notifications
You must be signed in to change notification settings - Fork 324
/
Copy pathprecompiles_expmod_test.cpp
89 lines (81 loc) · 5.17 KB
/
precompiles_expmod_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2025 The evmone Authors.
// SPDX-License-Identifier: Apache-2.0
#include <evmc/hex.hpp>
#include <gtest/gtest.h>
#include <intx/intx.hpp>
#include <test/state/precompiles_internal.hpp>
#include <test/utils/utils.hpp>
struct TestCase
{
std::string base;
std::string exp;
std::string mod;
std::string expected_result;
};
/// Test vectors for expmod precompile.
/// TODO: Currently limited to what expmod_stub can handle, but more can be added along the proper
/// implementation, e.g. {"03", "1c93", "61", "5f"}.
static const std::vector<TestCase> test_cases{
{"", "", "", ""},
{"", "", "00", "00"},
{"02", "01", "03", "02"},
{
"03",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
"0000000000000000000000000000000000000000000000000000000000000001",
},
};
TEST(expmod, test_vectors)
{
for (const auto& [base, exp, mod, expected_result] : test_cases)
{
const auto base_bytes = *evmc::from_hex(base);
const auto exp_bytes = *evmc::from_hex(exp);
const auto mod_bytes = *evmc::from_hex(mod);
const auto expected_result_bytes = *evmc::from_hex(expected_result);
evmc::bytes input(3 * 32, 0);
input[31] = static_cast<uint8_t>(base_bytes.size());
input[32 + 31] = static_cast<uint8_t>(exp_bytes.size());
input[64 + 31] = static_cast<uint8_t>(mod_bytes.size());
input += base_bytes;
input += exp_bytes;
input += mod_bytes;
evmc::bytes result(expected_result_bytes.size(), 0xfe);
const auto r =
evmone::state::expmod_execute(input.data(), input.size(), result.data(), result.size());
EXPECT_EQ(r.status_code, EVMC_SUCCESS);
EXPECT_EQ(r.output_size, expected_result_bytes.size());
EXPECT_EQ(hex(result), expected_result);
}
}
TEST(expmod, analysis_oog)
{
// Tests the gas cost calculation of the expmod precompile.
// The result cost is expected to prohibit execution.
static constexpr auto GAS_LIMIT = 1'000'000'000;
static constexpr std::array inputs{
// clang-format off
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 80000000 00000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 40000000 00000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 20000000 00000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 10000000 00000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 00000000 80000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 00000000 40000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000 00000000 20000020 0000000000000000000000000000000000000000000000000000000000000001 80",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001",
"0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000040 00000000000000000000000000000000000000000000000000000000ffffffff 80"
"0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000040 00000000000000000000000000000000000000000000000000000000ffffffff 80",
"00000000000000000000000000000000000000000000000000000000ffffffff 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000000000000000000000000000ffffffff 0000000000000000000000000000000000000000000000000000000000000001 80",
"0000000000000000000000000000000000000000000000000000000080000000 0000000000000000000000000000000000000000000000000000000080000000 0000000000000000000000000000000000000000000000000000000000000001 80",
// clang-format on
};
for (const auto& input_hex : inputs)
{
const auto input = evmc::from_spaced_hex(input_hex).value();
const auto [gas_cost, max_output_size] = evmone::state::expmod_analyze(input, EVMC_PRAGUE);
EXPECT_GT(gas_cost, GAS_LIMIT);
}
}