Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

add secp to selectors #1259

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
28 changes: 28 additions & 0 deletions secp_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use starknet::{secp256k1, secp256r1};

#[starknet::interface]
trait ISecp256k1MulTest<TContractState> {
fn secp256k1_mul_test(self: @TContractState, n: u256) -> (u256, u256);
}

#[starknet::contract]
mod Secp256k1MulTest {
use core::starknet::secp256_trait::Secp256PointTrait;
use core::result::ResultTrait;
use starknet::{secp256k1, secp256r1};
use starknet::secp256k1::Secp256k1Impl;

#[storage]
struct Storage {}

#[abi(embed_v0)]
impl Secp256k1MulTest of super::ISecp256k1MulTest<ContractState> {

fn secp256k1_mul_test(self: @ContractState, n: u256) -> (u256, u256) {
let point: secp256k1::Secp256k1Point = Secp256k1Impl::get_generator_point();
let scalar: u256 = u256 { high: 0, low: 1 };
let result = secp256k1::secp256k1_mul_syscall(point, scalar);
result.unwrap().get_coordinates().unwrap()
}
}
}
90 changes: 61 additions & 29 deletions src/syscalls/business_logic_syscall_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use super::{
syscall_request::{
CallContractRequest, DeployRequest, EmitEventRequest, FromPtr, GetBlockHashRequest,
GetBlockTimestampRequest, KeccakRequest, LibraryCallRequest, ReplaceClassRequest,
SendMessageToL1Request, StorageReadRequest, StorageWriteRequest, SyscallRequest,
SecpAddRequest, SendMessageToL1Request, StorageReadRequest, StorageWriteRequest,
SyscallRequest,
},
syscall_response::{
CallContractResponse, DeployResponse, FailureReason, GetBlockHashResponse,
Expand Down Expand Up @@ -40,7 +41,7 @@ use crate::{
BlockInfo, ExecutionResourcesManager,
},
transaction::{error::TransactionError, Address, ClassHash},
utils::{calculate_sn_keccak, felt_to_hash, get_big_int, get_felt_range},
utils::{felt_to_hash, get_big_int, get_felt_range},
};
use cairo_vm::Felt252;
use cairo_vm::{
Expand All @@ -63,11 +64,19 @@ use {
std::{cell::RefCell, rc::Rc},
};

pub(crate) const STEP: u128 = 100;
pub(crate) const SYSCALL_BASE: u128 = 100 * STEP;
pub(crate) const KECCAK_ROUND_COST: u128 = 180000;

lazy_static! {
static ref SYSCALLS: Vec<String> = Vec::from([
"emit_event".to_string(),
"deploy".to_string(),
"get_tx_info".to_string(),
"send_message_to_l1".to_string(),
"library_call".to_string(),
"get_caller_address".to_string(),
"get_contract_address".to_string(),
"get_sequencer_address".to_string(),
"get_block_timestamp".to_string(),
]);

/// Felt->syscall map that was extracted from new_syscalls.json (Cairo 1.0 syscalls)
static ref SELECTOR_TO_SYSCALL: HashMap<Felt252, &'static str> = {
let mut map: HashMap<Felt252, &'static str> = HashMap::with_capacity(9);
Expand All @@ -88,10 +97,27 @@ lazy_static! {
map.insert(75202468540281_u128.into(), "deploy");
map.insert(1280709301550335749748_u128.into(), "emit_event");
map.insert(25828017502874050592466629733_u128.into(), "storage_write");
map.insert(Felt252::from_bytes_be(&calculate_sn_keccak("get_block_timestamp".as_bytes())), "get_block_timestamp");
map.insert(Felt252::from_bytes_be(&calculate_sn_keccak("get_block_number".as_bytes())), "get_block_number");
map.insert(Felt252::from_bytes_be_slice("get_block_timestamp".as_bytes()), "get_block_timestamp");
map.insert(Felt252::from_bytes_be_slice("get_block_number".as_bytes()), "get_block_number");
map.insert(Felt252::from_bytes_be_slice("Keccak".as_bytes()), "keccak");

// SECP256k1 syscalls
let secp_syscalls = [
("Secp256k1New", "secp256k1_new"),
("Secp256k1Add", "secp256k1_add"),
("Secp256k1Mul", "secp256k1_mul"),
("Secp256k1GetPointFromX", "secp256k1_get_point_from_x"),
("Secp256k1GetXy", "secp256k1_get_xy"),
("Secp256r1New", "secp256r1_new"),
("Secp256r1Add", "secp256r1_add"),
("Secp256r1Mul", "secp256r1_mul"),
("Secp256r1GetPointFromX", "secp256r1_get_point_from_x"),
("Secp256r1GetXy", "secp256r1_get_xy")
];

for (syscall, syscall_name) in secp_syscalls {
map.insert(Felt252::from_bytes_be_slice(syscall.as_bytes()), syscall_name);
}
map
};

Expand Down Expand Up @@ -122,6 +148,20 @@ lazy_static! {
map.insert("keccak", 0);
map.insert("get_block_hash", SYSCALL_BASE + 50 * STEP);

// Secp256k1
map.insert("secp256k1_add", 406 * STEP + 29 * RANGE_CHECK);
map.insert("secp256k1_get_point_from_x", 391 * STEP + 30 * RANGE_CHECK + 20 * MEMORY_HOLE);
map.insert("secp256k1_get_xy", 239 * STEP + 11 * RANGE_CHECK + 40 * MEMORY_HOLE);
map.insert("secp256k1_mul", 76501 * STEP + 7045 * RANGE_CHECK + 2 * MEMORY_HOLE);
map.insert("secp256k1_new", 475 * STEP + 35 * RANGE_CHECK + 40 * MEMORY_HOLE);

// Secp256r1
map.insert("secp256r1_add", 589 * STEP + 57 * RANGE_CHECK);
map.insert("secp256r1_get_point_from_x", 510 * STEP + 44 * RANGE_CHECK + 20 * MEMORY_HOLE);
map.insert("secp256r1_get_xy", 241 * STEP + 11 * RANGE_CHECK + 40 * MEMORY_HOLE);
map.insert("secp256r1_mul", 125340 * STEP + 13961 * RANGE_CHECK + 2 * MEMORY_HOLE);
map.insert("secp256r1_new", 594 * STEP + 49 * RANGE_CHECK + 40 * MEMORY_HOLE);

map
};
}
Expand Down Expand Up @@ -218,30 +258,11 @@ impl<'a, S: StateReader, C: ContractClassCache> BusinessLogicSyscallHandler<'a,
_contract_address: Address,
state: &'a mut CachedState<S, C>,
) -> Self {
let syscalls = Vec::from([
// Emits an event with a given set of keys and data.
"emit_event".to_string(),
// Deploys a new instance of a previously declared class.
"deploy".to_string(),
// Gets information about the original transaction.
"get_tx_info".to_string(),
// Sends a message to L1.
"send_message_to_l1".to_string(),
// Calls the requested function in any previously declared class.
"library_call".to_string(),
// Returns the address of the calling contract, or 0 if the call was not initiated by another contract.
"get_caller_address".to_string(),
// Gets the address of the contract who raised the system call.
"get_contract_address".to_string(),
// Returns the address of the sequencer that generated the current block.
"get_sequencer_address".to_string(),
// Gets the timestamp of the block in which the transaction is executed.
"get_block_timestamp".to_string(),
]);
let events = Vec::new();
let tx_execution_context = Default::default();
let read_only_segments = Vec::new();
let resources_manager = ExecutionResourcesManager::new(syscalls, Default::default());
let resources_manager =
ExecutionResourcesManager::new(SYSCALLS.clone(), Default::default());
let contract_address = Address(1.into());
let caller_address = Address(0.into());
let l2_to_l1_messages = Vec::new();
Expand Down Expand Up @@ -1079,6 +1100,17 @@ impl<'a, S: StateReader, C: ContractClassCache> BusinessLogicSyscallHandler<'a,
"send_message_to_l1" => SendMessageToL1Request::from_ptr(vm, syscall_ptr),
"replace_class" => ReplaceClassRequest::from_ptr(vm, syscall_ptr),
"keccak" => KeccakRequest::from_ptr(vm, syscall_ptr),
"secp256k1_add" => SecpAddRequest::from_ptr(vm, syscall_ptr),
"secp256r1_add" => SecpAddRequest::from_ptr(vm, syscall_ptr),
// "secp256k1_get_point_from_x" => Secp256,
// "secp256k1_get_xy".to_string(),
// "secp256k1_get_xy".to_string(),
// "secp256k1_mul".to_string(),
// "secp256k1_new".to_string(),
// "secp256r1_get_point_from_x".to_string(),
// "secp256r1_get_xy".to_string(),
// "secp256r1_mul".to_string(),
// "secp256r1_new".to_string(),
_ => Err(SyscallHandlerError::UnknownSyscall(
syscall_name.to_string(),
)),
Expand Down
1 change: 1 addition & 0 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod hint_code;
#[cfg(feature = "cairo-native")]
pub mod native_syscall_handler;
pub mod other_syscalls;
pub mod secp_syscall_handler;
pub mod syscall_handler;
pub mod syscall_handler_errors;
pub mod syscall_info;
Expand Down
33 changes: 33 additions & 0 deletions src/syscalls/secp_syscall_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use cairo_vm::Felt252;
use lazy_static::lazy_static;

lazy_static! {
static ref SECP_SYSCALLS: Vec<String> = vec![
"secp256k1_add".to_string(),
"secp256r1_add".to_string(),
"secp256k1_get_xy".to_string(),
"secp256r1_get_xy".to_string(),
"secp256k1_mul".to_string(),
"secp256r1_mul".to_string(),
"secp256k1_new".to_string(),
"secp256r1_new".to_string(),
"secp256r1_get_point_from_x".to_string(),
"secp256k1_get_point_from_x".to_string()
];
}

pub(crate) const SECP_STEP: u128 = 100;
pub(crate) const SYSCALL_BASE: u128 = 100 * STEP;
pub(crate) const KECCAK_ROUND_COST: u128 = 180000;
pub(crate) const RANGE_CHECK: u128 = 70;
pub(crate) const MEMORY_HOLE: u128 = 10;

pub struct Secp256SyscallHandler {
points: Vec<Felt252>,
}

impl Secp256SyscallHandler {
pub fn secp_add(&self) -> Felt252 {
unimplemented!()
}
}
37 changes: 37 additions & 0 deletions src/syscalls/syscall_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,34 @@ pub(crate) enum SyscallRequest {
ReplaceClass(ReplaceClassRequest),
/// Computes the Keccak256 hash of the given data.
Keccak(KeccakRequest),
/// secp256 operations
Secp256k1New(Secp256k1NewRequest),
Secp256Add(SecpAddRequest),
Secp256k1Mul(Secp256k1MulRequest),
Secp256k1GetPointFromX(Secp256k1GetPointFromXRequest),
Secp256k1GetXy(Secp256k1GetXyRequest),
///
Secp256r1New(Secp256r1NewRequest),
Secp256r1Mul(Secp256r1MulRequest),
Secp256r1GetPointFromX(Secp256r1GetPointFromXRequest),
Secp256r1GetXy(Secp256r1GetXyRequest),
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~
// SyscallRequest variants
// ~~~~~~~~~~~~~~~~~~~~~~~~~

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct SecpAddRequest {
pub lhs_id: Felt252,
pub rhs_id: Felt252,
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct SecpOpResponse {
pub ec_point_id: usize,
}

/// Gets the timestamp of the block in which the transaction is executed.
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct GetBlockTimestampRequest {}
Expand Down Expand Up @@ -263,6 +285,21 @@ pub(crate) trait FromPtr {
) -> Result<SyscallRequest, SyscallHandlerError>;
}

impl FromPtr for SecpAddRequest {
fn from_ptr(
vm: &VirtualMachine,
syscall_ptr: Relocatable,
) -> Result<SyscallRequest, SyscallHandlerError> {
let lhs = vm.get_integer(syscall_ptr)?;
let rhs = vm.get_integer(syscall_ptr)?;
let operation = SecpAddRequest {
lhs_id: *lhs,
rhs_id: *rhs,
};
Ok(SyscallRequest::Secp256Add(operation))
}
}

impl FromPtr for ReplaceClassRequest {
fn from_ptr(
vm: &VirtualMachine,
Expand Down
28 changes: 28 additions & 0 deletions starknet_programs/cairo2/secp_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use starknet::{secp256k1, secp256r1};

#[starknet::interface]
trait ISecp256k1MulTest<TContractState> {
fn secp256k1_mul_test(self: @TContractState, n: u256) -> (u256, u256);
}

#[starknet::contract]
mod Secp256k1MulTest {
use core::starknet::secp256_trait::Secp256PointTrait;
use core::result::ResultTrait;
use starknet::{secp256k1, secp256r1};
use starknet::secp256k1::Secp256k1Impl;

#[storage]
struct Storage {}

#[abi(embed_v0)]
impl Secp256k1MulTest of super::ISecp256k1MulTest<ContractState> {

fn secp256k1_mul_test(self: @ContractState, n: u256) -> (u256, u256) {
let point: secp256k1::Secp256k1Point = Secp256k1Impl::get_generator_point();
let scalar: u256 = u256 { high: 0, low: 1 };
let result = secp256k1::secp256k1_mul_syscall(point, scalar);
result.unwrap().get_coordinates().unwrap()
}
}
}
1 change: 1 addition & 0 deletions tests/integration_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod increase_balance;
pub mod internal_calls;
pub mod internals;
pub mod multi_syscall_test;
pub mod secp;
pub mod storage;
pub mod syscalls;
pub mod syscalls_errors;
Expand Down
Loading
Loading