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

Feature: Implement SECP related missing hints #299

Merged
merged 6 commits into from
Aug 29, 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
29 changes: 29 additions & 0 deletions crates/starknet-os/src/cairo_types/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,32 @@ pub struct GetTxSignature {
#[allow(unused)]
pub response: GetTxSignatureResponse,
}

#[allow(unused)]
#[derive(FieldOffsetGetters)]
pub struct SecpNewResponse {
#[allow(unused)]
pub not_on_curve: Felt252,
#[allow(unused)]
pub ec_point: Relocatable,
}

#[allow(unused)]
#[derive(FieldOffsetGetters)]
pub struct EcPoint {
#[allow(unused)]
pub d0: Felt252,
#[allow(unused)]
pub d1: Felt252,
#[allow(unused)]
pub d3: Felt252,
}

#[allow(unused)]
#[derive(FieldOffsetGetters)]
pub struct EcCoordinate {
#[allow(unused)]
pub x: EcPoint,
#[allow(unused)]
pub y: EcPoint,
}
14 changes: 3 additions & 11 deletions crates/starknet-os/src/execution/helper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::cell::OnceCell;
use std::collections::HashMap;
use std::ops::Deref;
use std::rc::Rc;
Expand All @@ -7,14 +6,14 @@ use std::vec::IntoIter;
use blockifier::context::BlockContext;
use blockifier::execution::call_info::CallInfo;
use blockifier::execution::entry_point_execution::CallResult;
use blockifier::execution::syscalls::secp::SecpHintProcessor;
use blockifier::transaction::objects::TransactionExecutionInfo;
use cairo_vm::types::relocatable::Relocatable;
use cairo_vm::vm::errors::hint_errors::HintError;
use cairo_vm::Felt252;
use starknet_api::deprecated_contract_class::EntryPointType;
use tokio::sync::RwLock;

use super::secp_handler::SecpSyscallProcessor;
use crate::config::STORED_BLOCK_HASH_BUFFER;
use crate::starknet::starknet_storage::{CommitmentInfo, CommitmentInfoError, PerContractStorage};
use crate::storage::storage::StorageError;
Expand Down Expand Up @@ -56,16 +55,9 @@ where
pub storage_by_address: ContractStorageMap<PCS>,

// Secp syscall processors.
pub secp256k1_syscall_processor: SecpSyscallProcessor<SecpHintProcessor<ark_secp256k1::Config>>,
pub secp256r1_syscall_processor: SecpSyscallProcessor<SecpHintProcessor<ark_secp256r1::Config>>,
pub secp256k1_syscall_processor: SecpSyscallProcessor<ark_secp256k1::Config>,
pub secp256r1_syscall_processor: SecpSyscallProcessor<ark_secp256r1::Config>,
}

#[derive(Debug, Default)]
pub struct SecpSyscallProcessor<P> {
pub processor: P,
pub segment: OnceCell<Relocatable>,
}

/// ExecutionHelper is wrapped in Rc<RefCell<_>> in order
/// to clone the refrence when entering and exiting vm scopes
#[derive(Debug)]
Expand Down
48 changes: 29 additions & 19 deletions crates/starknet-os/src/execution/secp_handler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cell::OnceCell;
use std::marker::PhantomData;

use ark_ec::short_weierstrass::SWCurveConfig;
Expand All @@ -9,24 +10,31 @@ use cairo_vm::vm::vm_core::VirtualMachine;
use cairo_vm::Felt252;
use num_bigint::BigUint;

use super::helper::{ExecutionHelperWrapper, SecpSyscallProcessor};
use super::helper::ExecutionHelperWrapper;
use super::syscall_handler_utils::{
felt_from_ptr, write_maybe_relocatable, SyscallHandler, SyscallResult, WriteResponseResult,
};
use crate::cairo_types::syscalls::EcCoordinate;
use crate::execution::helper::ExecutionHelper;
use crate::execution::syscall_handler_utils::{write_felt, SyscallExecutionError};
use crate::starknet::starknet_storage::PerContractStorage;

#[derive(Debug, Default)]
pub struct SecpSyscallProcessor<C: SWCurveConfig> {
processor: SecpHintProcessor<C>,
segment: OnceCell<Relocatable>,
}

/// This trait is private and not callable outside this module.
trait GetSecpSyscallHandler<C: SWCurveConfig> {
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<SecpHintProcessor<C>>;
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<C>;
}

impl<PCS> GetSecpSyscallHandler<ark_secp256k1::Config> for ExecutionHelper<PCS>
where
PCS: PerContractStorage,
{
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<SecpHintProcessor<ark_secp256k1::Config>> {
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<ark_secp256k1::Config> {
&mut self.secp256k1_syscall_processor
}
}
Expand All @@ -35,7 +43,7 @@ impl<PCS> GetSecpSyscallHandler<ark_secp256r1::Config> for ExecutionHelper<PCS>
where
PCS: PerContractStorage,
{
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<SecpHintProcessor<ark_secp256r1::Config>> {
fn get_secp_handler(&mut self) -> &mut SecpSyscallProcessor<ark_secp256r1::Config> {
&mut self.secp256r1_syscall_processor
}
}
Expand Down Expand Up @@ -92,7 +100,9 @@ where
let res = secp_handler.processor.secp_new(request)?;
if let Some(ec_point) = res.optional_ec_point_id {
let segment = secp_handler.segment.get_or_init(|| vm.add_memory_segment());
return Ok(SecpOptionalEcPointResponse { optional_ec_point_id: Some((*segment + ec_point * 6)?) });
return Ok(SecpOptionalEcPointResponse {
optional_ec_point_id: Some((*segment + ec_point * EcCoordinate::cairo_size())?),
});
}

Ok(SecpOptionalEcPointResponse { optional_ec_point_id: None })
Expand Down Expand Up @@ -155,7 +165,7 @@ where
if let Some(ec_point) = res.optional_ec_point_id {
let segment = secp_handler.segment.get_or_init(|| vm.add_memory_segment());
return Ok(SecpOptionalEcPointResponse {
optional_ec_point_id: Some((*segment + ec_point * 6)?), // multiply with size of EcPOINT?
optional_ec_point_id: Some((*segment + ec_point * EcCoordinate::cairo_size())?),
});
}

Expand Down Expand Up @@ -188,7 +198,7 @@ pub struct SecpMulRequest {
}

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

Expand All @@ -199,7 +209,7 @@ where
{
type Request = SecpMulRequest;

type Response = SecpOpRespone;
type Response = SecpOpResponse;

fn read_request(vm: &VirtualMachine, ptr: &mut Relocatable) -> SyscallResult<Self::Request> {
let ec_point_id = vm.get_relocatable(*ptr)?;
Expand All @@ -226,12 +236,12 @@ where
let offset = request.ec_point_id;
let segment = secp_handler.segment.get().unwrap();
let request = blockifier::execution::syscalls::secp::SecpMulRequest {
ec_point_id: (offset.offset / 6).into(),
ec_point_id: (offset.offset / EcCoordinate::cairo_size()).into(),
multiplier: request.multiplier,
};
let res = secp_handler.processor.secp_mul(request)?;

Ok(SecpOpRespone { ec_point_id: (*segment + res.ec_point_id * 6)? })
Ok(SecpOpResponse { ec_point_id: (*segment + res.ec_point_id * EcCoordinate::cairo_size())? })
}

fn write_response(response: Self::Response, vm: &mut VirtualMachine, ptr: &mut Relocatable) -> WriteResponseResult {
Expand All @@ -257,7 +267,7 @@ where
{
type Request = SecpAddRequest;

type Response = SecpOpRespone;
type Response = SecpOpResponse;

fn read_request(vm: &VirtualMachine, ptr: &mut Relocatable) -> SyscallResult<Self::Request> {
let lhs_id = vm.get_relocatable(*ptr)?;
Expand All @@ -279,13 +289,13 @@ where
let mut eh_ref = exec_wrapper.execution_helper.write().await;
let secp_handler = &mut <ExecutionHelper<PCS> as GetSecpSyscallHandler<C>>::get_secp_handler(&mut eh_ref);
let request = blockifier::execution::syscalls::secp::SecpAddRequest {
lhs_id: (request.lhs_id.offset / 6).into(),
rhs_id: (request.rhs_id.offset / 6).into(),
lhs_id: (request.lhs_id.offset / EcCoordinate::cairo_size()).into(),
rhs_id: (request.rhs_id.offset / EcCoordinate::cairo_size()).into(),
};
let res = secp_handler.processor.secp_add(request)?;
let segment = secp_handler.segment.get().unwrap();

Ok(SecpOpRespone { ec_point_id: (*segment + res.ec_point_id * 6)? })
Ok(SecpOpResponse { ec_point_id: (*segment + res.ec_point_id * EcCoordinate::cairo_size())? })
}

fn write_response(response: Self::Response, vm: &mut VirtualMachine, ptr: &mut Relocatable) -> WriteResponseResult {
Expand Down Expand Up @@ -328,9 +338,11 @@ where
let mut eh_ref = exec_wrapper.execution_helper.write().await;
let secp_handler = &mut <ExecutionHelper<PCS> as GetSecpSyscallHandler<C>>::get_secp_handler(&mut eh_ref);
let offset = request.ec_point_id;
// let segment = secp_handler.segment.get().unwrap();
let request =
blockifier::execution::syscalls::secp::SecpGetXyRequest { ec_point_id: (offset.offset / 6).into() };
let _ = secp_handler.segment.get().unwrap();
let request = blockifier::execution::syscalls::secp::SecpGetXyRequest {
ec_point_id: (offset.offset / EcCoordinate::cairo_size()).into(),
};

let res = secp_handler.processor.secp_get_xy(request)?;
Ok(res)
}
Expand Down Expand Up @@ -360,8 +372,6 @@ mod tests {
use num_traits::{FromPrimitive, Num};
use rstest::rstest;

// use super::*;

fn parse_hex(hex_str: &str) -> BigUint {
let trimmed_hex_str = hex_str.trim_start_matches("0x");
BigUint::from_str_radix(trimmed_hex_str, 16).unwrap()
Expand Down
3 changes: 2 additions & 1 deletion crates/starknet-os/src/hints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ mod execute_transactions;
pub mod execution;
mod output;
mod patricia;
mod secp;
pub mod state;
pub mod syscalls;
#[cfg(test)]
Expand Down Expand Up @@ -235,7 +236,7 @@ fn hints<PCS>() -> HashMap<String, HintImpl> where
hints.insert(transaction_hash::DATA_TO_HASH_NEW_SEGMENT.into(), transaction_hash::data_to_hash_new_segment);
hints.insert(block_context::WRITE_USE_ZKG_DA_TO_MEM.into(), block_context::write_use_zkg_da_to_mem);
hints.insert(compiled_class::SET_AP_TO_SEGMENT_HASH.into(), compiled_class::set_ap_to_segment_hash);

hints.insert(secp::READ_EC_POINT_ADDRESS.into(), secp::read_ec_point_from_address);
hints
}

Expand Down
34 changes: 34 additions & 0 deletions crates/starknet-os/src/hints/secp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::collections::HashMap;

use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_integer_from_var_name, get_ptr_from_var_name, insert_value_into_ap,
};
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
use cairo_vm::serde::deserialize_program::ApTracking;
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::vm::errors::hint_errors::HintError;
use cairo_vm::vm::vm_core::VirtualMachine;
use cairo_vm::Felt252;

use crate::cairo_types::syscalls::SecpNewResponse;
use crate::hints::vars;

pub const READ_EC_POINT_ADDRESS: &str = r#"memory[ap] = to_felt_or_relocatable(ids.response.ec_point.address_ if ids.not_on_curve == 0 else segments.add())"#;
pub fn read_ec_point_from_address(
vm: &mut VirtualMachine,
_exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
_ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let not_on_curve = get_integer_from_var_name(vars::ids::NOT_ON_CURVE, vm, ids_data, _ap_tracking)?;
if not_on_curve == Felt252::ZERO {
let response = get_ptr_from_var_name(vars::ids::RESPONSE, vm, ids_data, _ap_tracking)?;
let ec_point = vm.get_relocatable((response + SecpNewResponse::ec_point_offset())?)?;
insert_value_into_ap(vm, ec_point)?;
} else {
let segment = vm.add_memory_segment();
insert_value_into_ap(vm, segment)?;
}
Ok(())
}
Loading
Loading