Skip to content
This repository has been archived by the owner on Jan 8, 2025. It is now read-only.

feat: ecAdd / ecMul #880

Merged
merged 5 commits into from
Sep 5, 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
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scarb 2.7.1
starknet-foundry 0.28.0
starknet-foundry 0.30.0
6 changes: 3 additions & 3 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ dependencies = [
[[package]]
name = "snforge_scarb_plugin"
version = "0.1.0"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.28.0#4dfe39d96690ed6b3d56971512700de3f58288ea"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496"

[[package]]
name = "snforge_std"
version = "0.28.0"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.28.0#4dfe39d96690ed6b3d56971512700de3f58288ea"
version = "0.30.0"
source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.30.0#196f06b251926697c3d66800f2a93ae595e76496"
dependencies = [
"snforge_scarb_plugin",
]
Expand Down
2 changes: 1 addition & 1 deletion crates/alexandria_data_structures/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ version = "0.1.0"
[dependencies]

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" }

[scripts]
test = "snforge test --max-n-steps 4294967295"
Expand Down
2 changes: 1 addition & 1 deletion crates/contracts/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build-external-contracts = ["openzeppelin::token::erc20::erc20::ERC20"]
name = "contracts"

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" }
assert_macros = "0.1.0"
snforge_utils = { path = "../snforge_utils" }

Expand Down
2 changes: 1 addition & 1 deletion crates/evm/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ openzeppelin = { path = "../openzeppelin" }
garaga = { git = "https://github.com/keep-starknet-strange/garaga.git" }

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" }
snforge_utils = { path = "../snforge_utils" }
assert_macros = "0.1.0"

Expand Down
18 changes: 4 additions & 14 deletions crates/evm/src/precompiles.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use evm::errors::EVMError;
use evm::model::vm::VM;
use evm::model::vm::VMTrait;
use evm::precompiles::blake2f::Blake2f;
use evm::precompiles::ec_add::EcAdd;
use evm::precompiles::ec_mul::EcMul;
use evm::precompiles::ec_recover::EcRecover;
use evm::precompiles::identity::Identity;
use evm::precompiles::modexp::ModExp;
Expand Down Expand Up @@ -67,20 +69,8 @@ impl PrecompilesImpl of Precompiles {
},
0x04 => { Identity::exec(input)? },
0x05 => { ModExp::exec(input)? },
0x06 => {
// we should never reach this branch!
panic!(
"pre-compile at address {} isn't implemented yet",
precompile_address.address
)
},
0x07 => {
// we should never reach this branch!
panic!(
"pre-compile at address {} isn't implemented yet",
precompile_address.address
)
},
0x06 => { EcAdd::exec(input)? },
0x07 => { EcMul::exec(input)? },
0x08 => {
// we should never reach this branch!
panic!(
Expand Down
45 changes: 45 additions & 0 deletions crates/evm/src/precompiles/ec_add.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,51 @@ use evm::precompiles::Precompile;
use garaga::core::circuit::AddInputResultTrait2;
use garaga::utils::u384_eq_zero;
use utils::helpers::{U256Trait, ToBytes, FromBytes};
use utils::helpers::{load_word, u256_to_bytes_array};


const BASE_COST: u128 = 150;
const U256_BYTES_LEN: usize = 32;

impl EcAdd of Precompile {
#[inline(always)]
fn address() -> EthAddress {
EthAddress { address: 0x6 }
}

fn exec(mut input: Span<u8>) -> Result<(u128, Span<u8>), EVMError> {
let gas = BASE_COST;

let x1_bytes = *(input.multi_pop_front::<32>().unwrap());
let x1: u256 = load_word(U256_BYTES_LEN, x1_bytes.unbox().span());

let y1_bytes = *(input.multi_pop_front::<32>().unwrap());
let y1: u256 = load_word(U256_BYTES_LEN, y1_bytes.unbox().span());

let x2_bytes = *(input.multi_pop_front::<32>().unwrap());
let x2: u256 = load_word(U256_BYTES_LEN, x2_bytes.unbox().span());

let y2_bytes = *(input.multi_pop_front::<32>().unwrap());
let y2: u256 = load_word(U256_BYTES_LEN, y2_bytes.unbox().span());

let (x, y) = match ec_add(x1, y1, x2, y2) {
Option::Some((x, y)) => { (x, y) },
Option::None => {
return Result::Err(EVMError::InvalidParameter('invalid ec_add parameters'));
},
};

let mut result_bytes = array![];
// Append x to the result bytes.
let x_bytes = x.to_be_bytes_padded();
result_bytes.append_span(x_bytes);
// Append y to the result bytes.
let y_bytes = y.to_be_bytes_padded();
result_bytes.append_span(y_bytes);

return Result::Ok((gas, result_bytes.span()));
}
}


fn ec_add(x1: u256, y1: u256, x2: u256, y2: u256) -> Option<(u256, u256)> {
Expand Down
41 changes: 39 additions & 2 deletions crates/evm/src/precompiles/ec_mul.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,48 @@ use evm::precompiles::ec_add::{
};
use garaga::core::circuit::AddInputResultTrait2;
use garaga::utils::u384_eq_zero;
use utils::helpers::{U256Trait, ToBytes, FromBytes};
use utils::helpers::{load_word, u256_to_bytes_array, U256Trait, ToBytes, FromBytes};

// const BN254_ORDER: u256 = 0x30644E72E131A029B85045B68181585D2833E84879B9709143E1F593F0000001;

const BASE_COST: u128 = 6000;
const U256_BYTES_LEN: usize = 32;

impl EcMul of Precompile {
fn address() -> EthAddress {
EthAddress { address: 0x7 }
}

fn exec(mut input: Span<u8>) -> Result<(u128, Span<u8>), EVMError> {
let gas = BASE_COST;

let x1_bytes = *(input.multi_pop_front::<32>().unwrap());
let x1: u256 = load_word(U256_BYTES_LEN, x1_bytes.unbox().span());

let y1_bytes = *(input.multi_pop_front::<32>().unwrap());
let y1: u256 = load_word(U256_BYTES_LEN, y1_bytes.unbox().span());

let s_bytes = *(input.multi_pop_front::<32>().unwrap());
let s: u256 = load_word(U256_BYTES_LEN, s_bytes.unbox().span());

let (x, y) = match ec_mul(x1, y1, s) {
Option::Some((x, y)) => { (x, y) },
Option::None => {
return Result::Err(EVMError::InvalidParameter('invalid ec_mul parameters'));
},
};

// Append x and y to the result bytes.
let mut result_bytes = array![];
let x_bytes = x.to_be_bytes_padded();
result_bytes.append_span(x_bytes);
let y_bytes = y.to_be_bytes_padded();
result_bytes.append_span(y_bytes);

return Result::Ok((gas, result_bytes.span()));
}
}

// Returns Option::None in case of error.
fn ec_mul(x1: u256, y1: u256, s: u256) -> Option<(u256, u256)> {
if x1 == 0 && y1 == 0 {
Expand Down Expand Up @@ -100,4 +138,3 @@ fn ec_mul_inner(pt: (u384, u384), mut bits: Array<felt252>) -> Option<(u384, u38

pt
}

2 changes: 1 addition & 1 deletion crates/openzeppelin/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ starknet.workspace = true
fmt.workspace = true

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" }

[scripts]
test = "snforge test --max-n-steps 4294967295"
Expand Down
2 changes: 1 addition & 1 deletion crates/snforge_utils/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ starknet = "2.7.1"
evm = { path = "../evm" }

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.30.0" }

[[target.starknet-contract]]
sierra = true
Expand Down
61 changes: 0 additions & 61 deletions crates/snforge_utils/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,6 @@ pub mod snforge_utils {
get_call_trace, CallTrace, CallEntryPoint, CallResult, EntryPointType, CallType, CallFailure
};

impl CloneEntryPointType of Clone<EntryPointType> {
fn clone(self: @EntryPointType) -> EntryPointType {
match self {
EntryPointType::Constructor => EntryPointType::Constructor,
EntryPointType::External => EntryPointType::External,
EntryPointType::L1Handler => EntryPointType::L1Handler,
}
}
}

impl CloneCallEntryPoint of Clone<CallEntryPoint> {
fn clone(self: @CallEntryPoint) -> CallEntryPoint {
CallEntryPoint {
entry_point_type: self.entry_point_type.clone(),
entry_point_selector: self.entry_point_selector.clone(),
calldata: self.calldata.clone(),
contract_address: self.contract_address.clone(),
caller_address: self.caller_address.clone(),
call_type: self.call_type.clone(),
}
}
}

impl CloneCallType of Clone<CallType> {
fn clone(self: @CallType) -> CallType {
match self {
CallType::Call => CallType::Call,
CallType::Delegate => CallType::Delegate,
}
}
}

impl CloneCallResult of Clone<CallResult> {
fn clone(self: @CallResult) -> CallResult {
match self {
CallResult::Success(val) => CallResult::Success(val.clone()),
CallResult::Failure(val) => CallResult::Failure(val.clone()),
}
}
}

impl CloneCallFailure of Clone<CallFailure> {
fn clone(self: @CallFailure) -> CallFailure {
match self {
CallFailure::Panic(val) => CallFailure::Panic(val.clone()),
CallFailure::Error(val) => CallFailure::Error(val.clone()),
}
}
}


impl CloneCallTrace of Clone<CallTrace> {
fn clone(self: @CallTrace) -> CallTrace {
CallTrace {
entry_point: self.entry_point.clone(),
nested_calls: self.nested_calls.clone(),
result: self.result.clone(),
}
}
}

pub fn is_called(contract_address: ContractAddress, selector: felt252) -> bool {
let call_trace = get_call_trace();

Expand Down
2 changes: 1 addition & 1 deletion crates/utils/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ alexandria_data_structures = { path = "../alexandria_data_structures" }
fmt.workspace = true

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.28.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.30.0" }

[scripts]
test = "snforge test --max-n-steps 4294967295"
Expand Down
Loading