From 8111a8c397712a2abc7d5f04a4e97c22d600006d Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 15:27:27 +0200 Subject: [PATCH 1/7] first commit --- crates/evm/src/call_helpers.cairo | 2 +- crates/evm/src/precompiles.cairo | 9 +++ crates/evm/src/precompiles/p256verify.cairo | 64 +++++++++++++++++ crates/evm/src/tests/test_precompiles.cairo | 1 + .../test_precompiles/test_p256verify.cairo | 69 +++++++++++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 crates/evm/src/precompiles/p256verify.cairo create mode 100644 crates/evm/src/tests/test_precompiles/test_p256verify.cairo diff --git a/crates/evm/src/call_helpers.cairo b/crates/evm/src/call_helpers.cairo index 4ea732d09..b26b1b14d 100644 --- a/crates/evm/src/call_helpers.cairo +++ b/crates/evm/src/call_helpers.cairo @@ -121,5 +121,5 @@ impl CallHelpersImpl of CallHelpers { /// Check whether an address for a call-family opcode is a precompile. fn is_precompile(self: EthAddress) -> bool { let self: felt252 = self.into(); - return (self != 0 && self.into() < 10_u256); + return (self != 0 && self.into() < 12_u256); } diff --git a/crates/evm/src/precompiles.cairo b/crates/evm/src/precompiles.cairo index 81108f0a1..69feb7c4c 100644 --- a/crates/evm/src/precompiles.cairo +++ b/crates/evm/src/precompiles.cairo @@ -3,6 +3,7 @@ mod ec_recover; mod identity; mod modexp; mod sha256; +mod p256verify; use core::traits::Into; use evm::errors::EVMError; @@ -13,6 +14,7 @@ use evm::precompiles::ec_recover::EcRecover; use evm::precompiles::identity::Identity; use evm::precompiles::modexp::ModExp; use evm::precompiles::sha256::Sha256; +use evm::precompiles::p256verify::P256Verify; use starknet::EthAddress; @@ -61,6 +63,13 @@ impl PrecompilesImpl of Precompiles { ) }, 9 => { Blake2f::exec(input)? }, + 10 => { + // we should never reach this branch! + panic!( + "pre-compile at address {} isn't implemented yet", precompile_address.address + ) + }, + 11 => { P256Verify::exec(input)? }, _ => { // we should never reach this branch! panic!("address {} isn't a pre-compile", precompile_address.address) diff --git a/crates/evm/src/precompiles/p256verify.cairo b/crates/evm/src/precompiles/p256verify.cairo new file mode 100644 index 000000000..dbb74d660 --- /dev/null +++ b/crates/evm/src/precompiles/p256verify.cairo @@ -0,0 +1,64 @@ +use core::starknet::SyscallResultTrait; +use evm::errors::{EVMError, TYPE_CONVERSION_ERROR}; +use evm::precompiles::Precompile; +use starknet::{ + EthAddress, eth_signature::{recover_public_key, public_key_point_to_eth_address, Signature}, + secp256r1::{Secp256r1Point, secp256r1_new_syscall}, + secp256_trait::is_valid_signature +}; +use utils::helpers::{U256Trait, BoolIntoNumeric, ToBytes, FromBytes}; + +const P256VERIFY_PRECOMPILE_GAS_COST: u128 = 3450; + +impl P256Verify of Precompile { + #[inline(always)] + fn address() -> EthAddress { + EthAddress { address: 11 } + } + + fn exec(input: Span) -> Result<(u128, Span), EVMError> { + let gas: u128 = P256VERIFY_PRECOMPILE_GAS_COST; + + let message_hash = input.slice(0, 32); + let message_hash = match message_hash.from_be_bytes() { + Option::Some(message_hash) => message_hash, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + let r: Option = input.slice(32, 32).from_be_bytes(); + let r = match r { + Option::Some(r) => r, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + let s: Option = input.slice(64, 32).from_be_bytes(); + let s = match s { + Option::Some(s) => s, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + let x: Option = input.slice(96, 32).from_be_bytes(); + let x = match x { + Option::Some(x) => x, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + let y: Option = input.slice(128, 32).from_be_bytes(); + let y = match y { + Option::Some(y) => y, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + let public_key: Option = secp256r1_new_syscall(x, y).unwrap_syscall(); + let public_key = match public_key { + Option::Some(public_key) => public_key, + Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + }; + + if !is_valid_signature(message_hash, r, s, public_key) { + return Result::Ok((gas, array![0].span())); + } + + return Result::Ok((gas, array![1].span())); + } +} diff --git a/crates/evm/src/tests/test_precompiles.cairo b/crates/evm/src/tests/test_precompiles.cairo index d9bcc897b..ad479449f 100644 --- a/crates/evm/src/tests/test_precompiles.cairo +++ b/crates/evm/src/tests/test_precompiles.cairo @@ -4,3 +4,4 @@ mod test_ec_recover; mod test_identity; mod test_modexp; mod test_sha256; +mod test_p256verify; \ No newline at end of file diff --git a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo new file mode 100644 index 000000000..7e2052d19 --- /dev/null +++ b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo @@ -0,0 +1,69 @@ +use contracts::tests::test_utils::setup_contracts_for_testing; +use core::array::ArrayTrait; +use evm::instructions::system_operations::SystemOperationsTrait; +use evm::memory::InternalMemoryTrait; +use evm::memory::MemoryTrait; + +use evm::precompiles::p256verify::P256Verify; +use evm::stack::StackTrait; +use evm::tests::test_utils::{VMBuilderTrait, native_token, other_starknet_address}; +use utils::helpers::{U256Trait, ToBytes, FromBytes}; + + +// source: +#[test] +fn test_p256verify_precompile() { + let (_, _) = setup_contracts_for_testing(); + + let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 + .to_be_bytes_padded(); + let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 + .to_be_bytes_padded(); + let s = 0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60_u256 + .to_be_bytes_padded(); + let x = 0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3_u256 + .to_be_bytes_padded(); + let y = 0x7618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e_u256 + .to_be_bytes_padded(); + + let mut calldata = array![]; + calldata.append_span(msg_hash); + calldata.append_span(r); + calldata.append_span(s); + calldata.append_span(x); + calldata.append_span(y); + + let (gas, result) = P256Verify::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + assert_eq!(result, 0x01); + assert_eq!(gas, 3450); +} + +// source: +#[test] +fn test_p256verify_precompile_static_call() { + let (_, _) = setup_contracts_for_testing(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store(0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0); // msg_hash + vm.memory.store(0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, 0x20); // r + vm.memory.store(0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, 0x40); // s + vm.memory.store(0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, 0x60); // x + vm.memory.store(0x7618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e, 0x80); // y + + vm.stack.push(0x01).unwrap(); // retSize + vm.stack.push(0xa0).unwrap(); // retOffset + vm.stack.push(0xa0).unwrap(); // argsSize + vm.stack.push(0x0).unwrap(); // argsOffset + vm.stack.push(0x0b).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + vm.exec_staticcall().unwrap(); + + let mut result = Default::default(); + vm.memory.load_n(0x1, ref result, 0xa0); + + assert_eq!(result, array![0x01]); +} From ad1ad9732f7c403f7b9b1c90665f53dcc201399f Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 15:53:27 +0200 Subject: [PATCH 2/7] scarb fmt + corrected tests source --- crates/evm/src/precompiles.cairo | 4 +-- crates/evm/src/precompiles/p256verify.cairo | 29 +++++++++++++------ crates/evm/src/tests/test_precompiles.cairo | 2 +- .../test_precompiles/test_p256verify.cairo | 14 +++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/crates/evm/src/precompiles.cairo b/crates/evm/src/precompiles.cairo index 69feb7c4c..3950629af 100644 --- a/crates/evm/src/precompiles.cairo +++ b/crates/evm/src/precompiles.cairo @@ -2,8 +2,8 @@ mod blake2f; mod ec_recover; mod identity; mod modexp; -mod sha256; mod p256verify; +mod sha256; use core::traits::Into; use evm::errors::EVMError; @@ -13,8 +13,8 @@ use evm::precompiles::blake2f::Blake2f; use evm::precompiles::ec_recover::EcRecover; use evm::precompiles::identity::Identity; use evm::precompiles::modexp::ModExp; -use evm::precompiles::sha256::Sha256; use evm::precompiles::p256verify::P256Verify; +use evm::precompiles::sha256::Sha256; use starknet::EthAddress; diff --git a/crates/evm/src/precompiles/p256verify.cairo b/crates/evm/src/precompiles/p256verify.cairo index dbb74d660..28d4332af 100644 --- a/crates/evm/src/precompiles/p256verify.cairo +++ b/crates/evm/src/precompiles/p256verify.cairo @@ -3,8 +3,7 @@ use evm::errors::{EVMError, TYPE_CONVERSION_ERROR}; use evm::precompiles::Precompile; use starknet::{ EthAddress, eth_signature::{recover_public_key, public_key_point_to_eth_address, Signature}, - secp256r1::{Secp256r1Point, secp256r1_new_syscall}, - secp256_trait::is_valid_signature + secp256r1::{Secp256r1Point, secp256r1_new_syscall}, secp256_trait::is_valid_signature }; use utils::helpers::{U256Trait, BoolIntoNumeric, ToBytes, FromBytes}; @@ -22,37 +21,49 @@ impl P256Verify of Precompile { let message_hash = input.slice(0, 32); let message_hash = match message_hash.from_be_bytes() { Option::Some(message_hash) => message_hash, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; let r: Option = input.slice(32, 32).from_be_bytes(); let r = match r { Option::Some(r) => r, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; let s: Option = input.slice(64, 32).from_be_bytes(); let s = match s { Option::Some(s) => s, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; let x: Option = input.slice(96, 32).from_be_bytes(); let x = match x { Option::Some(x) => x, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; let y: Option = input.slice(128, 32).from_be_bytes(); let y = match y { Option::Some(y) => y, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; - + let public_key: Option = secp256r1_new_syscall(x, y).unwrap_syscall(); let public_key = match public_key { Option::Some(public_key) => public_key, - Option::None => { return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); } + Option::None => { + return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } }; if !is_valid_signature(message_hash, r, s, public_key) { diff --git a/crates/evm/src/tests/test_precompiles.cairo b/crates/evm/src/tests/test_precompiles.cairo index ad479449f..2e25cb16a 100644 --- a/crates/evm/src/tests/test_precompiles.cairo +++ b/crates/evm/src/tests/test_precompiles.cairo @@ -3,5 +3,5 @@ mod test_data; mod test_ec_recover; mod test_identity; mod test_modexp; +mod test_p256verify; mod test_sha256; -mod test_p256verify; \ No newline at end of file diff --git a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo index 7e2052d19..6ef63c1a7 100644 --- a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo +++ b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo @@ -10,11 +10,11 @@ use evm::tests::test_utils::{VMBuilderTrait, native_token, other_starknet_addres use utils::helpers::{U256Trait, ToBytes, FromBytes}; -// source: +// source: #[test] fn test_p256verify_precompile() { let (_, _) = setup_contracts_for_testing(); - + let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 .to_be_bytes_padded(); let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 @@ -40,14 +40,16 @@ fn test_p256verify_precompile() { assert_eq!(gas, 3450); } -// source: +// source: #[test] fn test_p256verify_precompile_static_call() { let (_, _) = setup_contracts_for_testing(); - + let mut vm = VMBuilderTrait::new_with_presets().build(); - vm.memory.store(0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0); // msg_hash + vm + .memory + .store(0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0); // msg_hash vm.memory.store(0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, 0x20); // r vm.memory.store(0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, 0x40); // s vm.memory.store(0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, 0x60); // x @@ -64,6 +66,6 @@ fn test_p256verify_precompile_static_call() { let mut result = Default::default(); vm.memory.load_n(0x1, ref result, 0xa0); - + assert_eq!(result, array![0x01]); } From 16fc6f633b97fa82a57b192eed1ee605c33f3695 Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 16:16:56 +0200 Subject: [PATCH 3/7] removed unnecessary imports --- crates/evm/src/precompiles/p256verify.cairo | 2 +- crates/evm/src/tests/test_precompiles/test_p256verify.cairo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/evm/src/precompiles/p256verify.cairo b/crates/evm/src/precompiles/p256verify.cairo index 28d4332af..2364de5e0 100644 --- a/crates/evm/src/precompiles/p256verify.cairo +++ b/crates/evm/src/precompiles/p256verify.cairo @@ -5,7 +5,7 @@ use starknet::{ EthAddress, eth_signature::{recover_public_key, public_key_point_to_eth_address, Signature}, secp256r1::{Secp256r1Point, secp256r1_new_syscall}, secp256_trait::is_valid_signature }; -use utils::helpers::{U256Trait, BoolIntoNumeric, ToBytes, FromBytes}; +use utils::helpers::{U256Trait, ToBytes, FromBytes}; const P256VERIFY_PRECOMPILE_GAS_COST: u128 = 3450; diff --git a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo index 6ef63c1a7..032042b02 100644 --- a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo +++ b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo @@ -6,7 +6,7 @@ use evm::memory::MemoryTrait; use evm::precompiles::p256verify::P256Verify; use evm::stack::StackTrait; -use evm::tests::test_utils::{VMBuilderTrait, native_token, other_starknet_address}; +use evm::tests::test_utils::{VMBuilderTrait}; use utils::helpers::{U256Trait, ToBytes, FromBytes}; From 759c8f76dd4f239e02c2242774cd5028922fe284 Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 17:23:03 +0200 Subject: [PATCH 4/7] review corrections --- crates/evm/src/call_helpers.cairo | 2 +- crates/evm/src/precompiles.cairo | 89 ++++++++++--------- crates/evm/src/precompiles/p256verify.cairo | 32 +++---- .../test_precompiles/test_p256verify.cairo | 56 +++++++++++- 4 files changed, 111 insertions(+), 68 deletions(-) diff --git a/crates/evm/src/call_helpers.cairo b/crates/evm/src/call_helpers.cairo index b26b1b14d..6acdc4bf9 100644 --- a/crates/evm/src/call_helpers.cairo +++ b/crates/evm/src/call_helpers.cairo @@ -121,5 +121,5 @@ impl CallHelpersImpl of CallHelpers { /// Check whether an address for a call-family opcode is a precompile. fn is_precompile(self: EthAddress) -> bool { let self: felt252 = self.into(); - return (self != 0 && self.into() < 12_u256); + return (self != 0 && self.into() < 257_u256); } diff --git a/crates/evm/src/precompiles.cairo b/crates/evm/src/precompiles.cairo index 3950629af..ef18d4ce9 100644 --- a/crates/evm/src/precompiles.cairo +++ b/crates/evm/src/precompiles.cairo @@ -29,50 +29,51 @@ impl PrecompilesImpl of Precompiles { let precompile_address = vm.message.target.evm; let input = vm.message().data; - let (gas, result) = match precompile_address.address { - 0 => { - // we should never reach this branch! - panic!("pre-compile address can't be 0") - }, - 1 => { EcRecover::exec(input)? }, - 2 => { Sha256::exec(input)? }, - 3 => { - // we should never reach this branch! - panic!( - "pre-compile at address {} isn't implemented yet", precompile_address.address - ) - }, - 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 - ) - }, - 8 => { - // we should never reach this branch! - panic!( - "pre-compile at address {} isn't implemented yet", precompile_address.address - ) - }, - 9 => { Blake2f::exec(input)? }, - 10 => { - // we should never reach this branch! - panic!( - "pre-compile at address {} isn't implemented yet", precompile_address.address - ) - }, - 11 => { P256Verify::exec(input)? }, - _ => { - // we should never reach this branch! - panic!("address {} isn't a pre-compile", precompile_address.address) + let (gas, result) = if precompile_address.address == 0x100 { + P256Verify::exec(input)? + } else { + match precompile_address.address { + 0 => { + // we should never reach this branch! + panic!("pre-compile address can't be 0") + }, + 1 => { EcRecover::exec(input)? }, + 2 => { Sha256::exec(input)? }, + 3 => { + // we should never reach this branch! + panic!( + "pre-compile at address {} isn't implemented yet", + precompile_address.address + ) + }, + 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 + ) + }, + 8 => { + // we should never reach this branch! + panic!( + "pre-compile at address {} isn't implemented yet", + precompile_address.address + ) + }, + 9 => { Blake2f::exec(input)? }, + _ => { + // we should never reach this branch! + panic!("address {} isn't a pre-compile", precompile_address.address) + } } }; diff --git a/crates/evm/src/precompiles/p256verify.cairo b/crates/evm/src/precompiles/p256verify.cairo index 2364de5e0..76cf12ff5 100644 --- a/crates/evm/src/precompiles/p256verify.cairo +++ b/crates/evm/src/precompiles/p256verify.cairo @@ -1,5 +1,5 @@ use core::starknet::SyscallResultTrait; -use evm::errors::{EVMError, TYPE_CONVERSION_ERROR}; +use evm::errors::{EVMError}; use evm::precompiles::Precompile; use starknet::{ EthAddress, eth_signature::{recover_public_key, public_key_point_to_eth_address, Signature}, @@ -12,58 +12,50 @@ const P256VERIFY_PRECOMPILE_GAS_COST: u128 = 3450; impl P256Verify of Precompile { #[inline(always)] fn address() -> EthAddress { - EthAddress { address: 11 } + EthAddress { address: 0x100 } } fn exec(input: Span) -> Result<(u128, Span), EVMError> { let gas: u128 = P256VERIFY_PRECOMPILE_GAS_COST; + if input.len() != 160 { + return Result::Ok((gas, array![0].span())); + } + let message_hash = input.slice(0, 32); let message_hash = match message_hash.from_be_bytes() { Option::Some(message_hash) => message_hash, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; let r: Option = input.slice(32, 32).from_be_bytes(); let r = match r { Option::Some(r) => r, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; let s: Option = input.slice(64, 32).from_be_bytes(); let s = match s { Option::Some(s) => s, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; let x: Option = input.slice(96, 32).from_be_bytes(); let x = match x { Option::Some(x) => x, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; let y: Option = input.slice(128, 32).from_be_bytes(); let y = match y { Option::Some(y) => y, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; let public_key: Option = secp256r1_new_syscall(x, y).unwrap_syscall(); let public_key = match public_key { Option::Some(public_key) => public_key, - Option::None => { - return Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); - } + Option::None => { return Result::Ok((gas, array![].span())); } }; if !is_valid_signature(message_hash, r, s, public_key) { diff --git a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo index 032042b02..eafb659c3 100644 --- a/crates/evm/src/tests/test_precompiles/test_p256verify.cairo +++ b/crates/evm/src/tests/test_precompiles/test_p256verify.cairo @@ -13,8 +13,6 @@ use utils::helpers::{U256Trait, ToBytes, FromBytes}; // source: #[test] fn test_p256verify_precompile() { - let (_, _) = setup_contracts_for_testing(); - let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 .to_be_bytes_padded(); let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 @@ -59,7 +57,7 @@ fn test_p256verify_precompile_static_call() { vm.stack.push(0xa0).unwrap(); // retOffset vm.stack.push(0xa0).unwrap(); // argsSize vm.stack.push(0x0).unwrap(); // argsOffset - vm.stack.push(0x0b).unwrap(); // address + vm.stack.push(0x100).unwrap(); // address vm.stack.push(0xFFFFFFFF).unwrap(); // gas vm.exec_staticcall().unwrap(); @@ -69,3 +67,55 @@ fn test_p256verify_precompile_static_call() { assert_eq!(result, array![0x01]); } + +#[test] +fn test_p256verify_precompile_input_too_short() { + let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 + .to_be_bytes_padded(); + let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 + .to_be_bytes_padded(); + let s = 0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60_u256 + .to_be_bytes_padded(); + let x = 0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3_u256 + .to_be_bytes_padded(); + + let mut calldata = array![]; + calldata.append_span(msg_hash); + calldata.append_span(r); + calldata.append_span(s); + calldata.append_span(x); + + let (gas, result) = P256Verify::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + assert_eq!(result, 0x00); + assert_eq!(gas, 3450); +} + +#[test] +fn test_p256verify_precompile_input_too_short_static_call() { + let (_, _) = setup_contracts_for_testing(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm + .memory + .store(0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0); // msg_hash + vm.memory.store(0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, 0x20); // r + vm.memory.store(0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, 0x40); // s + vm.memory.store(0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, 0x60); // x + + vm.stack.push(0x01).unwrap(); // retSize + vm.stack.push(0x80).unwrap(); // retOffset + vm.stack.push(0x80).unwrap(); // argsSize + vm.stack.push(0x0).unwrap(); // argsOffset + vm.stack.push(0x100).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + vm.exec_staticcall().unwrap(); + + let mut result = Default::default(); + vm.memory.load_n(0x1, ref result, 0x80); + + assert_eq!(result, array![0x00]); +} From 464fb013c12337647984e35d9a6fd9a58b901fc3 Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 17:53:35 +0200 Subject: [PATCH 5/7] corrected address range --- crates/evm/src/call_helpers.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/evm/src/call_helpers.cairo b/crates/evm/src/call_helpers.cairo index 6acdc4bf9..4f63d90e6 100644 --- a/crates/evm/src/call_helpers.cairo +++ b/crates/evm/src/call_helpers.cairo @@ -121,5 +121,5 @@ impl CallHelpersImpl of CallHelpers { /// Check whether an address for a call-family opcode is a precompile. fn is_precompile(self: EthAddress) -> bool { let self: felt252 = self.into(); - return (self != 0 && self.into() < 257_u256); + return (self != 0 && (self.into() < 10_u256 || self.into() == 256_u256)); } From b363027970bc410798b3d6ca77c86bd3f55d8313 Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 18:48:16 +0200 Subject: [PATCH 6/7] modified tests deploy address --- .../test_system_operations.cairo | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/crates/evm/src/tests/test_instructions/test_system_operations.cairo b/crates/evm/src/tests/test_instructions/test_system_operations.cairo index c66bf573d..ee600b161 100644 --- a/crates/evm/src/tests/test_instructions/test_system_operations.cairo +++ b/crates/evm/src/tests/test_instructions/test_system_operations.cairo @@ -95,7 +95,7 @@ fn test_exec_call() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x100 0 0 0 0 1) + // (call 0xffffff 0x101 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -109,7 +109,7 @@ fn test_exec_call() { 0x00, 0x61, 0x01, - 0x00, + 0x01, 0x62, 0xff, 0xff, @@ -122,13 +122,13 @@ fn test_exec_call() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x100 + // Deploy bytecode at 0x101 // ret (+ 0x1 0x1) let deployed_bytecode = array![ 0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x60, 0x20, 0x60, 0x00, 0xf3 ] .span(); - let eth_address: EthAddress = 0x100_u256.into(); + let eth_address: EthAddress = 0x101_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -150,7 +150,7 @@ fn test_exec_call_no_return() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x100 0 0 0 0 1) + // (call 0xffffff 0x101 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -164,7 +164,7 @@ fn test_exec_call_no_return() { 0x00, 0x61, 0x01, - 0x00, + 0x01, 0x62, 0xff, 0xff, @@ -177,10 +177,10 @@ fn test_exec_call_no_return() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x100 + // Deploy bytecode at 0x101 // (+ 0x1 0x1) let deployed_bytecode = array![0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x00].span(); - let eth_address: EthAddress = 0x100_u256.into(); + let eth_address: EthAddress = 0x101_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -202,7 +202,7 @@ fn test_exec_staticcall() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x100 0 0 0 0 1) + // (call 0xffffff 0x101 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -214,7 +214,7 @@ fn test_exec_staticcall() { 0x00, 0x61, 0x01, - 0x00, + 0x01, 0x62, 0xff, 0xff, @@ -226,13 +226,13 @@ fn test_exec_staticcall() { .span(); let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x100 + // Deploy bytecode at 0x101 // ret (+ 0x1 0x1) let deployed_bytecode = array![ 0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x60, 0x20, 0x60, 0x00, 0xf3 ] .span(); - let eth_address: EthAddress = 0x100_u256.into(); + let eth_address: EthAddress = 0x101_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -254,7 +254,7 @@ fn test_exec_staticcall_no_return() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x100 0 0 0 0 1) + // (call 0xffffff 0x101 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -268,7 +268,7 @@ fn test_exec_staticcall_no_return() { 0x00, 0x61, 0x01, - 0x00, + 0x01, 0x62, 0xff, 0xff, @@ -281,10 +281,10 @@ fn test_exec_staticcall_no_return() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x100 + // Deploy bytecode at 0x101 // (+ 0x1 0x1) let deployed_bytecode = array![0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x00].span(); - let eth_address: EthAddress = 0x100_u256.into(); + let eth_address: EthAddress = 0x101_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); From 71be913306d4255ce8edf936cffd0d652dd21c8e Mon Sep 17 00:00:00 2001 From: Quentash Date: Thu, 18 Apr 2024 23:44:05 +0200 Subject: [PATCH 7/7] changed contract address to random one --- .../test_system_operations.cairo | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/crates/evm/src/tests/test_instructions/test_system_operations.cairo b/crates/evm/src/tests/test_instructions/test_system_operations.cairo index ee600b161..00c5d0771 100644 --- a/crates/evm/src/tests/test_instructions/test_system_operations.cairo +++ b/crates/evm/src/tests/test_instructions/test_system_operations.cairo @@ -95,7 +95,7 @@ fn test_exec_call() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x101 0 0 0 0 1) + // (call 0xffffff 0xabfa740ccd 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -107,9 +107,12 @@ fn test_exec_call() { 0x00, 0x60, 0x00, - 0x61, - 0x01, - 0x01, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, 0x62, 0xff, 0xff, @@ -122,13 +125,13 @@ fn test_exec_call() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x101 + // Deploy bytecode at 0xabfa740ccd // ret (+ 0x1 0x1) let deployed_bytecode = array![ 0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x60, 0x20, 0x60, 0x00, 0xf3 ] .span(); - let eth_address: EthAddress = 0x101_u256.into(); + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -150,7 +153,7 @@ fn test_exec_call_no_return() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x101 0 0 0 0 1) + // (call 0xffffff 0xabfa740ccd 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -162,9 +165,12 @@ fn test_exec_call_no_return() { 0x00, 0x60, 0x00, - 0x61, - 0x01, - 0x01, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, 0x62, 0xff, 0xff, @@ -177,10 +183,10 @@ fn test_exec_call_no_return() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x101 + // Deploy bytecode at 0xabfa740ccd // (+ 0x1 0x1) let deployed_bytecode = array![0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x00].span(); - let eth_address: EthAddress = 0x101_u256.into(); + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -202,7 +208,7 @@ fn test_exec_staticcall() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x101 0 0 0 0 1) + // (call 0xffffff 0xabfa740ccd 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -212,9 +218,12 @@ fn test_exec_staticcall() { 0x00, 0x60, 0x00, - 0x61, - 0x01, - 0x01, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, 0x62, 0xff, 0xff, @@ -226,13 +235,13 @@ fn test_exec_staticcall() { .span(); let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x101 + // Deploy bytecode at 0xabfa740ccd // ret (+ 0x1 0x1) let deployed_bytecode = array![ 0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x60, 0x20, 0x60, 0x00, 0xf3 ] .span(); - let eth_address: EthAddress = 0x101_u256.into(); + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed'); @@ -254,7 +263,7 @@ fn test_exec_staticcall_no_return() { kakarot_core.deploy_externally_owned_account(evm_address); // Set vm bytecode - // (call 0xffffff 0x101 0 0 0 0 1) + // (call 0xffffff 0xabfa740ccd 0 0 0 0 1) let bytecode = array![ 0x60, 0x01, @@ -266,9 +275,12 @@ fn test_exec_staticcall_no_return() { 0x00, 0x60, 0x00, - 0x61, - 0x01, - 0x01, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, 0x62, 0xff, 0xff, @@ -281,10 +293,10 @@ fn test_exec_staticcall_no_return() { let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); - // Deploy bytecode at 0x101 + // Deploy bytecode at 0xabfa740ccd // (+ 0x1 0x1) let deployed_bytecode = array![0x60, 0x01, 0x60, 0x01, 0x01, 0x60, 0x00, 0x53, 0x00].span(); - let eth_address: EthAddress = 0x101_u256.into(); + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); initialize_contract_account(eth_address, deployed_bytecode, Default::default().span()) .expect('set code failed');