Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evmmax: Initial implementation of EVMMAX instructions (EIP-6690) #742

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions include/evmmax/evmmax.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,91 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once

#include <evmc/evmc.hpp>
#include <intx/intx.hpp>
#include <memory>

namespace evmmax
{

using intx::uint256;

struct EXMMAXModStateInterface;

/// Ephemeral EVMMAX (EVM Modular Arithmetic Extensions) state
class EVMMAXState
{
struct OpcodesGasCost
{
int64_t addmodx = 0;
int64_t mulmodx = 0;
};

OpcodesGasCost current_gas_cost;

std::unique_ptr<EXMMAXModStateInterface> active_mod; ///< Current active modulus

public:
/// Create new modulus and activates it. In case the modulus already exists, activates it.
/// Deducts gas accordingly.
///
/// \param gas_left Amount of gas before calling. Is modified by `setupx`
/// \param mod_ptr Modulus big endian value memory pointer
/// \param mod_size Modulus size in bytes
/// \param vals_used Number of needed value slots
/// \return Status code.
[[nodiscard]] evmc_status_code setupx(
int64_t& gas_left, const uint8_t* mod_ptr, size_t mod_size, size_t vals_used) noexcept;

/// Loads EVMMAX values into EVM memory. Deducts gas accordingly.
/// Converts to the Montgomery form
[[nodiscard]] evmc_status_code loadx(
int64_t& gas_left, uint8_t* out_ptr, size_t val_idx, size_t num_vals) noexcept;

/// Stores EVM memory into EVMMAX value slots. Deducts gas accordingly.
/// Converts from the Montgomery form
[[nodiscard]] evmc_status_code storex(
int64_t& gas_left, const uint8_t* in_ptr, size_t dst_val_idx, size_t num_vals) noexcept;

/// Computes modular addition. Deducts gas accordingly. Operates on active modulus.
///
/// (x + y) % active_modulus.
/// Gets inputs from values slots under indexes `x_idx` and `y_idx`.
/// Saves result in value slot under index `dst_idx`
[[nodiscard]] evmc_status_code addmodx(
int64_t& gas_left, size_t dst_idx, size_t x_idx, size_t y_idx) noexcept;

/// Computes modular subtraction. Deducts gas accordingly. Operates on active modulus.
///
/// (x - y) % active_modulus.
/// Gets inputs from values slots under indexes `x_idx` and `y_idx`.
/// Saves result in value slot under index `dst_idx`
[[nodiscard]] evmc_status_code submodx(
int64_t& gas_left, size_t dst_idx, size_t x_idx, size_t y_idx) noexcept;

/// Computes modular multiplication. Deducts gas accordingly. Operates on active modulus.
///
/// (x * y) % active_modulus.
/// Gets inputs from values slots under indexes `x_idx` and `y_idx`.
/// Saves result in value slot under index `dst_idx`
[[nodiscard]] evmc_status_code mulmodx(
int64_t& gas_left, size_t dst_idx, size_t x_idx, size_t y_idx) noexcept;

/// Checks that there exists an active modulus
[[nodiscard]] bool is_activated() const noexcept;

/// Returns active modulus size multiplier.
/// Size (expressed in multiples of 8 bytes) needed to represent modulus.
[[nodiscard]] size_t active_mod_value_size_multiplier() const noexcept;

void clear() noexcept;

EVMMAXState& operator=(EVMMAXState&&) noexcept;
explicit EVMMAXState() noexcept;
explicit EVMMAXState(EVMMAXState&&) noexcept;
virtual ~EVMMAXState();
};

/// The modular arithmetic operations for EVMMAX (EVM Modular Arithmetic Extensions).
template <typename UintT>
class ModArith
Expand Down
9 changes: 5 additions & 4 deletions lib/evmmax/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
# Copyright 2023 The evmone Authors.
# SPDX-License-Identifier: Apache-2.0

add_library(evmmax INTERFACE)
add_library(evmmax STATIC)
add_library(evmone::evmmax ALIAS evmmax)
target_compile_features(evmmax INTERFACE cxx_std_20)
target_include_directories(evmmax INTERFACE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(evmmax INTERFACE intx::intx)
target_compile_features(evmmax PUBLIC cxx_std_20)
target_include_directories(evmmax PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(evmmax PUBLIC intx::intx PRIVATE evmc::evmc_cpp)

if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
# We want to add the header file to the library for IDEs.
# However, cmake 3.18 does not support PRIVATE scope for INTERFACE libraries.
target_sources(
evmmax PRIVATE
${PROJECT_SOURCE_DIR}/include/evmmax/evmmax.hpp
evmmax.cpp
)
endif()
Loading