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

feat: enable ec_add / ec_mul #1398

Merged
merged 15 commits into from
Sep 24, 2024
Merged
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
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ endif

.PHONY: build test coverage clean

# 154615699 corresponds to release v0.1.7 of Kakarot SSJ.
KKRT_SSJ_RELEASE_ID = 154615699
# 176384150 corresponds to release v0.1.13 of Kakarot SSJ.
KKRT_SSJ_RELEASE_ID = 176384150
# Kakarot SSJ artifacts for precompiles.
KKRT_SSJ_BUILD_ARTIFACT_URL = $(shell curl -L https://api.github.com/repos/kkrt-labs/kakarot-ssj/releases/${KKRT_SSJ_RELEASE_ID} | jq -r '.assets[0].browser_download_url')
KATANA_VERSION = v1.0.0-alpha.11
KATANA_VERSION = v1.0.0-alpha.12
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

BUILD_DIR = build
Expand All @@ -35,7 +35,7 @@ $(SSJ_ZIP):
fetch-ef-tests:
poetry run python ./kakarot_scripts/ef_tests/fetch.py

setup: fetch-ssj-artifacts
setup:
poetry install

test: deploy
Expand Down
11 changes: 7 additions & 4 deletions kakarot_scripts/utils/starknet.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ def get_deployments():

@cache
def get_artifact(contract_name):
# Cairo 0 artifacts
ClementWalter marked this conversation as resolved.
Show resolved Hide resolved
artifacts = list(BUILD_DIR.glob(f"*{contract_name}*.json"))
if artifacts:
return Artifact(sierra=None, casm=artifacts[0])

# Cairo 1 artifacts
artifacts = list(CAIRO_DIR.glob(f"**/*{contract_name}.*.json")) or list(
BUILD_DIR_SSJ.glob(f"**/*{contract_name}.*.json")
)
Expand All @@ -255,10 +261,7 @@ def get_artifact(contract_name):
)
return Artifact(sierra=sierra, casm=casm)

artifacts = list(BUILD_DIR.glob(f"**/*{contract_name}*.json"))
if not artifacts:
raise FileNotFoundError(f"No artifact found for {contract_name}")
return Artifact(sierra=None, casm=artifacts[0])
raise FileNotFoundError(f"No artifact found for {contract_name}")


@cache
Expand Down
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ packages = [{ include = "kakarot_scripts" }, { include = "tests" }]

[tool.poetry.dependencies]
python = ">=3.10,<3.11"
starknet-py = "^0.23.0"
cairo-lang = "0.13.1"
python-dotenv = "^0.21.0"
async-lru = "^2.0.4"
toml = "^0.10.2"
scikit-learn = "^1.5.1"
seaborn = "^0.13.2"
boto3 = "^1.35.12"
starknet-py = "0.23.0"

[tool.poetry.group.dev.dependencies]
pytest = "^8.1.1"
Expand Down
55 changes: 55 additions & 0 deletions solidity_contracts/src/EvmPrecompiles/EvmPrecompiles.sol
ClementWalter marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @title EVM Precompiles Integration
/// @notice Contract for integration testing of EVM precompiles.
/// @dev Implements functions for ECADD and ECMUL precompiles.
contract EvmPrecompiles {
/// @dev Address of the ECADD precompile
address private constant ECADD_PRECOMPILE = address(0x06);
/// @dev Address of the ECMUL precompile
address private constant ECMUL_PRECOMPILE = address(0x07);

/// @dev Gas cost for ECADD call is 150
uint256 private constant ECADD_GAS = 150;
/// @dev Gas cost for ECMUL call is 6000
uint256 private constant ECMUL_GAS = 6000;

/*//////////////////////////////////////////////////////////////
FUNCTIONS FOR PRECOMPILES
//////////////////////////////////////////////////////////////*/
/// @notice Performs elliptic curve addition
/// @param x1 X coordinate of the first point
/// @param y1 Y coordinate of the first point
/// @param x2 X coordinate of the second point
/// @param y2 Y coordinate of the second point
/// @return success True if the operation was successful, false otherwise
/// @return x X coordinate of the result point
/// @return y Y coordinate of the result point
function ecAdd(uint256 x1, uint256 y1, uint256 x2, uint256 y2) external view returns (bool, uint256 x, uint256 y) {
bytes memory input = abi.encodePacked(x1, y1, x2, y2);
(bool success, bytes memory result) = ECADD_PRECOMPILE.staticcall{gas: ECADD_GAS}(input);
if (!success) {
ClementWalter marked this conversation as resolved.
Show resolved Hide resolved
return (false, 0, 0);
}
(x, y) = abi.decode(result, (uint256, uint256));
return (true, x, y);
}

/// @notice Performs elliptic curve scalar multiplication
/// @param x1 X coordinate of the point
/// @param y1 Y coordinate of the point
/// @param s Scalar for multiplication
/// @return success True if the operation was successful, false otherwise
/// @return x X coordinate of the result point
/// @return y Y coordinate of the result point
function ecMul(uint256 x1, uint256 y1, uint256 s) external view returns (bool, uint256 x, uint256 y) {
bytes memory input = abi.encodePacked(x1, y1, s);
(bool success, bytes memory result) = ECMUL_PRECOMPILE.staticcall{gas: ECMUL_GAS}(input);
if (!success) {
return (false, 0, 0);
}
(x, y) = abi.decode(result, (uint256, uint256));
return (true, x, y);
}
}
25 changes: 18 additions & 7 deletions src/kakarot/interpreter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,30 @@
tempvar caller_code_address = parent_context.evm.message.code_address.evm;
}
tempvar caller_address = evm.message.caller;
let (
output_len, output, gas_used, precompile_reverted
) = Precompiles.exec_precompile(
let (output_len, output, gas_used, revert_code) = Precompiles.exec_precompile(

Check warning on line 79 in src/kakarot/interpreter.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/interpreter.cairo#L79

Added line #L79 was not covered by tests
evm.message.code_address.evm,
evm.message.calldata_len,
evm.message.calldata,
caller_code_address,
caller_address,
);
let evm = EVM.charge_gas(evm, gas_used);
let evm_reverted = is_not_zero(evm.reverted);
let success = (1 - precompile_reverted) * (1 - evm_reverted);
let evm = EVM.stop(evm, output_len, output, 1 - success);

let precompile_reverted = is_not_zero(revert_code);
if (precompile_reverted != FALSE) {

Check warning on line 88 in src/kakarot/interpreter.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/interpreter.cairo#L87-L88

Added lines #L87 - L88 were not covered by tests
// No need to charge gas as precompiles can only trigger EXCEPTIONAL_REVERT
// which will consume the entire gas of the context.
let evm = EVM.stop(evm, output_len, output, revert_code);
tempvar range_check_ptr = range_check_ptr;
tempvar evm = evm;

Check warning on line 93 in src/kakarot/interpreter.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/interpreter.cairo#L91-L93

Added lines #L91 - L93 were not covered by tests
} else {
// Charge gas before stopping
let evm = EVM.charge_gas(evm, gas_used);
let evm = EVM.stop(evm, output_len, output, evm.reverted);
tempvar range_check_ptr = range_check_ptr;
tempvar evm = evm;

Check warning on line 99 in src/kakarot/interpreter.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/interpreter.cairo#L96-L99

Added lines #L96 - L99 were not covered by tests
}
let range_check_ptr = [ap - 2];

Check warning on line 101 in src/kakarot/interpreter.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/interpreter.cairo#L101

Added line #L101 was not covered by tests
let evm = cast([ap - 1], model.EVM*);
let is_cairo_precompile_called = PrecompilesHelpers.is_kakarot_precompile(
evm.message.code_address.evm
);
Expand Down
58 changes: 0 additions & 58 deletions src/kakarot/precompiles/ecadd.cairo

This file was deleted.

55 changes: 0 additions & 55 deletions src/kakarot/precompiles/ecmul.cairo

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ from utils.utils import Helpers
from kakarot.memory import Memory
from kakarot.evm import EVM

// @title DataCopy precompile
// @title Identity precompile
// @custom:precompile
// @custom:address 0x04
// @notice This precompile serves as a cheaper way to copy data in memory
namespace PrecompileDataCopy {
namespace PrecompileIdentity {
const PRECOMPILE_ADDRESS = 0x04;
const GAS_COST_DATACOPY = 15;
const GAS_IDENTITY = 15;
const GAS_IDENTITY_WORD = 3;

// @notice Run the precompile.
// @param input_len The length of input array.
Expand All @@ -34,6 +35,6 @@ namespace PrecompileDataCopy {
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
let (minimum_word_size) = Helpers.minimum_word_count(input_len);
return (input_len, input, 3 * minimum_word_size + GAS_COST_DATACOPY, 0);
return (input_len, input, GAS_IDENTITY_WORD * minimum_word_size + GAS_IDENTITY, 0);
}
}
Loading
Loading