Skip to content

Commit

Permalink
feat: ecAdd / ecMul
Browse files Browse the repository at this point in the history
  • Loading branch information
obatirou committed Aug 28, 2024
1 parent 5191cc8 commit 3c45cb8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 17 deletions.
19 changes: 4 additions & 15 deletions crates/evm/src/precompiles.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ 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;
use evm::precompiles::p256verify::P256Verify;
use evm::precompiles::sha256::Sha256;


trait Precompile {
fn address() -> EthAddress;
fn exec(input: Span<u8>) -> Result<(u128, Span<u8>), EVMError>;
Expand Down Expand Up @@ -50,20 +51,8 @@ impl PrecompilesImpl of Precompiles {
},
4 => { Identity::exec(input)? },
5 => { ModExp::exec(input)? },
6 => {
// we should never reach this branch!
panic!(
"pre-compile at address {} isn't implemented yet",
precompile_address.address
)
},
7 => {
// we should never reach this branch!
panic!(
"pre-compile at address {} isn't implemented yet",
precompile_address.address
)
},
6 => { EcAdd::exec(input)? },
7 => { EcMul::exec(input)? },
8 => {
// we should never reach this branch!
panic!(
Expand Down
44 changes: 44 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,50 @@ 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;

// Load x1
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let x1: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());
// Load y1
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let y1: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());
// Load x2
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let x2: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());
// Load y2
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let y2: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());

let (x, y) = match ec_add(x1, y1, x2, y2) {
Option::Some((x, y)) => { (x, y) },
Option::None => (0, 0),
};

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
42 changes: 40 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,49 @@ 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 = 150;
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;

// from_be_bytes should be used

// Load x
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let x: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());
// Load y
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let y: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());
// Load s
let bytes_32 = *(input.multi_pop_front::<32>().unwrap());
let s: u256 = load_word(U256_BYTES_LEN, bytes_32.unbox().span());

let (x, y) = match ec_mul(x, y, s) {
Option::Some((x, y)) => { (x, y) },
Option::None => (0, 0),
};

// 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 +139,3 @@ fn ec_mul_inner(pt: (u384, u384), mut bits: Array<felt252>) -> Option<(u384, u38

pt
}

0 comments on commit 3c45cb8

Please sign in to comment.