From 824119cd2a717175c6465dc5b80d0867450c52c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 14:50:24 -0300 Subject: [PATCH 01/26] Make pub --- src/starknet/secp256k1_point.rs | 2 +- src/starknet/secp256r1_point.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/starknet/secp256k1_point.rs b/src/starknet/secp256k1_point.rs index 767b5f1..4e3a8a8 100644 --- a/src/starknet/secp256k1_point.rs +++ b/src/starknet/secp256k1_point.rs @@ -9,7 +9,7 @@ pub struct Secp256k1Point { impl Secp256k1Point { #[allow(unused)] - pub(crate) fn into_value(self) -> Value { + pub fn into_value(self) -> Value { Value::Struct(vec![ Value::Struct(vec![Value::U128(self.x.lo), Value::U128(self.x.hi)]), Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]), diff --git a/src/starknet/secp256r1_point.rs b/src/starknet/secp256r1_point.rs index b3137ac..a51ecde 100644 --- a/src/starknet/secp256r1_point.rs +++ b/src/starknet/secp256r1_point.rs @@ -9,7 +9,7 @@ pub struct Secp256r1Point { impl Secp256r1Point { #[allow(unused)] - pub(crate) fn into_value(self) -> Value { + pub fn into_value(self) -> Value { Value::Struct(vec![ Value::Struct(vec![Value::U128(self.x.lo), Value::U128(self.x.hi)]), Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]), From 692af954435348cfaa5c2dfd1485937c6f091fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 17:42:32 -0300 Subject: [PATCH 02/26] Add aux function --- src/lib.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index de8ec91..48068ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,9 @@ -use cairo_lang_sierra::program::{GenFunction, Program, StatementIdx}; +use cairo_lang_sierra::{ + extensions::core::{CoreLibfunc, CoreType}, + ids::ConcreteTypeId, + program::{GenFunction, Program, StatementIdx}, + program_registry::ProgramRegistry, +}; pub use self::{dump::*, value::*, vm::VirtualMachine}; @@ -29,3 +34,26 @@ pub fn find_entry_point_by_name<'a>( .iter() .find(|x| x.id.debug_name.as_ref().map(|x| x.as_str()) == Some(name)) } + +// If type is a single element container, finds it's inner type +// If not, returns the current type +pub fn find_inner_type( + registry: &ProgramRegistry, + ty: &ConcreteTypeId, +) -> ConcreteTypeId { + match registry.get_type(ty).unwrap() { + cairo_lang_sierra::extensions::core::CoreTypeConcrete::Box(info) => { + find_inner_type(registry, &info.ty) + } + cairo_lang_sierra::extensions::core::CoreTypeConcrete::Uninitialized(info) => { + find_inner_type(registry, &info.ty) + } + cairo_lang_sierra::extensions::core::CoreTypeConcrete::Span(info) => { + find_inner_type(registry, &info.ty) + } + cairo_lang_sierra::extensions::core::CoreTypeConcrete::Snapshot(info) => { + find_inner_type(registry, &info.ty) + } + _ => ty.clone(), + } +} From f76d264af59531bc60930eeda961417be64bdcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 17:42:46 -0300 Subject: [PATCH 03/26] Add secp support in `is` function --- src/value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/value.rs b/src/value.rs index 6b76db8..f0b51a8 100644 --- a/src/value.rs +++ b/src/value.rs @@ -172,7 +172,7 @@ impl Value { | StarkNetTypeConcrete::StorageBaseAddress(_) | StarkNetTypeConcrete::StorageAddress(_) => matches!(self, Self::Felt(_)), StarkNetTypeConcrete::System(_) => matches!(self, Self::Unit), - StarkNetTypeConcrete::Secp256Point(_) => todo!(), + StarkNetTypeConcrete::Secp256Point(_) => matches!(self, Self::Struct(_)), StarkNetTypeConcrete::Sha256StateHandle(_) => matches!(self, Self::Struct { .. }), }, }; From b98ed8a69c08b4e3c4ef7ebdf0dad3cbe2612983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 17:42:55 -0300 Subject: [PATCH 04/26] Add span_from_tuple --- src/vm/array.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/vm/array.rs b/src/vm/array.rs index e4814e1..0c9d092 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -1,10 +1,11 @@ use super::EvalAction; -use crate::Value; +use crate::{find_inner_type, Value}; use cairo_lang_sierra::{ extensions::{ array::ArrayConcreteLibfunc, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, + ConcreteLibfunc, }, program_registry::ProgramRegistry, }; @@ -17,7 +18,7 @@ pub fn eval( ) -> EvalAction { match selector { ArrayConcreteLibfunc::New(info) => eval_new(registry, info, args), - ArrayConcreteLibfunc::SpanFromTuple(_) => todo!(), + ArrayConcreteLibfunc::SpanFromTuple(info) => eval_span_from_tuple(registry, info, args), ArrayConcreteLibfunc::TupleFromSpan(_) => todo!(), ArrayConcreteLibfunc::Append(info) => eval_append(registry, info, args), ArrayConcreteLibfunc::PopFront(info) => eval_pop_front(registry, info, args), @@ -36,6 +37,30 @@ pub fn eval( } } +fn eval_span_from_tuple( + registry: &ProgramRegistry, + info: &SignatureAndTypeConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [Value::Struct(data)]: [Value; 1] = args.try_into().unwrap() else { + panic!() + }; + + let ty = &info.branch_signatures()[0].vars[0].ty; + let ty = find_inner_type(registry, ty); + + let CoreTypeConcrete::Array(info) = registry.get_type(&ty).unwrap() else { + panic!() + }; + + let value = Value::Array { + ty: info.ty.clone(), + data, + }; + + return EvalAction::NormalBranch(0, smallvec![value]); +} + pub fn eval_new( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, From 11f6a1fa6f0bf489a8502a202dd9540d52a9144a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 17:43:01 -0300 Subject: [PATCH 05/26] Improve const --- src/vm/const.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vm/const.rs b/src/vm/const.rs index a9a805b..d6269d3 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -113,6 +113,10 @@ fn inner( }, CoreTypeConcrete::Uint128(_) => match inner_data { [GenericArg::Value(value)] => Value::U128(value.try_into().unwrap()), + [GenericArg::Type(type_id)] => match registry.get_type(type_id).unwrap() { + CoreTypeConcrete::Const(info) => inner(registry, &info.inner_ty, &info.inner_data), + _ => unreachable!(), + }, _ => unreachable!(), }, CoreTypeConcrete::Struct(_) => { From 52de51f1b2d6b1af91a57cd3db459c83991f12f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 15 Oct 2024 17:43:13 -0300 Subject: [PATCH 06/26] Add secp support for some libfuncs --- src/vm/starknet.rs | 156 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 7ef0779..887d818 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,5 +1,8 @@ use super::EvalAction; -use crate::{starknet::StarknetSyscallHandler, Value}; +use crate::{ + starknet::{StarknetSyscallHandler, U256}, + Value, +}; use cairo_lang_sierra::{ extensions::{ consts::SignatureAndConstConcreteLibfunc, @@ -10,6 +13,7 @@ use cairo_lang_sierra::{ }, program_registry::ProgramRegistry, }; +use num_traits::One; use smallvec::smallvec; use starknet_types_core::felt::Felt; @@ -98,7 +102,155 @@ pub fn eval( eval_send_message_to_l1(registry, info, args, syscall_handler) } StarkNetConcreteLibfunc::Testing(_info) => todo!(), - StarkNetConcreteLibfunc::Secp256(_info) => todo!(), + StarkNetConcreteLibfunc::Secp256(info) => match info { + cairo_lang_sierra::extensions::starknet::secp256::Secp256ConcreteLibfunc::K1(info) => { + match info { + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), + } + } + cairo_lang_sierra::extensions::starknet::secp256::Secp256ConcreteLibfunc::R1(info) => { + match info { + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(info) => eval_secp_r_new(registry, info, args, syscall_handler), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(info) => eval_secp_r_get_point_from_x(registry, info, args, syscall_handler), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), + } + } + }, + } +} + +fn eval_secp_r_new( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [Value::U128(mut gas), system @ Value::Unit, Value::Struct(x), Value::Struct(y)]: [Value; + 4] = args.try_into().unwrap() + else { + panic!() + }; + + let Value::U128(x_lo) = x[0] else { panic!() }; + let Value::U128(x_hi) = x[1] else { panic!() }; + let x = U256 { lo: x_lo, hi: x_hi }; + let Value::U128(y_lo) = y[0] else { panic!() }; + let Value::U128(y_hi) = y[1] else { panic!() }; + let y = U256 { lo: y_lo, hi: y_hi }; + + match syscall_handler.secp256r1_new(x, y, &mut gas) { + Ok(p) => { + let enum_ty = &info.branch_signatures()[0].vars[2].ty; + let value = match p { + Some(p) => Value::Enum { + self_ty: enum_ty.clone(), + index: 0, + payload: Box::new(p.into_value()), + }, + None => Value::Enum { + self_ty: enum_ty.clone(), + index: 0, + payload: Box::new(Value::Unit), + }, + }; + + EvalAction::NormalBranch(0, smallvec![Value::U128(gas), system, value]) + } + Err(payload) => { + // get felt type from the error branch array + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + let value = payload.into_iter().map(Value::Felt).collect::>(); + EvalAction::NormalBranch( + 1, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: value + } + ], + ) + } + } +} + +fn eval_secp_r_get_point_from_x( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [Value::U128(mut gas), system @ Value::Unit, Value::Struct(x), Value::Enum { + index: y_parity, .. + }]: [Value; 4] = args.try_into().unwrap() + else { + panic!() + }; + + let Value::U128(x_lo) = x[0] else { panic!() }; + let Value::U128(x_hi) = x[1] else { panic!() }; + let x = U256 { lo: x_lo, hi: x_hi }; + let y_parity = y_parity.is_one(); + + match syscall_handler.secp256r1_get_point_from_x(x, y_parity, &mut gas) { + Ok(p) => { + let enum_ty = &info.branch_signatures()[0].vars[2].ty; + let value = match p { + Some(p) => Value::Enum { + self_ty: enum_ty.clone(), + index: 0, + payload: Box::new(p.into_value()), + }, + None => Value::Enum { + self_ty: enum_ty.clone(), + index: 0, + payload: Box::new(Value::Unit), + }, + }; + + EvalAction::NormalBranch(0, smallvec![Value::U128(gas), system, value]) + } + Err(payload) => { + // get felt type from the error branch array + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + let value = payload.into_iter().map(Value::Felt).collect::>(); + EvalAction::NormalBranch( + 1, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: value + } + ], + ) + } } } From 2bf24262f81591fb6b38650c1daa0f24e06361cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 12:42:18 -0300 Subject: [PATCH 07/26] Add debug functions --- src/debug.rs | 183 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 152 insertions(+), 31 deletions(-) diff --git a/src/debug.rs b/src/debug.rs index 93c0555..dc60f32 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,37 +1,44 @@ -use cairo_lang_sierra::extensions::{ - array::ArrayConcreteLibfunc, - boolean::BoolConcreteLibfunc, - bounded_int::BoundedIntConcreteLibfunc, - boxing::BoxConcreteLibfunc, - bytes31::Bytes31ConcreteLibfunc, - casts::CastConcreteLibfunc, - circuit::CircuitConcreteLibfunc, - const_type::ConstConcreteLibfunc, - core::CoreConcreteLibfunc, - coupon::CouponConcreteLibfunc, - debug::DebugConcreteLibfunc, - ec::EcConcreteLibfunc, - enm::EnumConcreteLibfunc, - felt252::{Felt252BinaryOperationConcrete, Felt252BinaryOperator, Felt252Concrete}, - felt252_dict::{Felt252DictConcreteLibfunc, Felt252DictEntryConcreteLibfunc}, - gas::GasConcreteLibfunc, - int::{ - signed::SintConcrete, signed128::Sint128Concrete, unsigned::UintConcrete, - unsigned128::Uint128Concrete, unsigned256::Uint256Concrete, unsigned512::Uint512Concrete, - IntOperator, +use cairo_lang_sierra::{ + extensions::{ + array::ArrayConcreteLibfunc, + boolean::BoolConcreteLibfunc, + bounded_int::BoundedIntConcreteLibfunc, + boxing::BoxConcreteLibfunc, + bytes31::Bytes31ConcreteLibfunc, + casts::CastConcreteLibfunc, + circuit::CircuitConcreteLibfunc, + const_type::ConstConcreteLibfunc, + core::{CoreConcreteLibfunc, CoreLibfunc, CoreType, CoreTypeConcrete}, + coupon::CouponConcreteLibfunc, + debug::DebugConcreteLibfunc, + ec::EcConcreteLibfunc, + enm::EnumConcreteLibfunc, + felt252::{Felt252BinaryOperationConcrete, Felt252BinaryOperator, Felt252Concrete}, + felt252_dict::{Felt252DictConcreteLibfunc, Felt252DictEntryConcreteLibfunc}, + gas::GasConcreteLibfunc, + int::{ + signed::SintConcrete, signed128::Sint128Concrete, unsigned::UintConcrete, + unsigned128::Uint128Concrete, unsigned256::Uint256Concrete, + unsigned512::Uint512Concrete, IntOperator, + }, + lib_func::{BranchSignature, ParamSignature}, + mem::MemConcreteLibfunc, + nullable::NullableConcreteLibfunc, + pedersen::PedersenConcreteLibfunc, + poseidon::PoseidonConcreteLibfunc, + starknet::{ + secp256::{Secp256ConcreteLibfunc, Secp256OpConcreteLibfunc}, + testing::TestingConcreteLibfunc, + StarkNetConcreteLibfunc, + }, + structure::StructConcreteLibfunc, }, - mem::MemConcreteLibfunc, - nullable::NullableConcreteLibfunc, - pedersen::PedersenConcreteLibfunc, - poseidon::PoseidonConcreteLibfunc, - starknet::{ - secp256::{Secp256ConcreteLibfunc, Secp256OpConcreteLibfunc}, - testing::TestingConcreteLibfunc, - StarkNetConcreteLibfunc, - }, - structure::StructConcreteLibfunc, + ids::ConcreteTypeId, + program_registry::ProgramRegistry, }; +use crate::Value; + pub fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str { match value { CoreConcreteLibfunc::ApTracking(value) => match value { @@ -409,3 +416,117 @@ pub fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str { }, } } + +pub fn type_to_name( + ty_id: &ConcreteTypeId, + registry: &ProgramRegistry, +) -> String { + let ty = registry.get_type(ty_id).unwrap(); + match ty { + CoreTypeConcrete::Array(info) => { + format!("Array<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Box(info) => { + format!("Box<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Uninitialized(info) => { + format!("Uninitialized<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::NonZero(info) => { + format!("NonZero<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Nullable(info) => { + format!("Nullable<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Span(info) => { + format!("Span<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Snapshot(info) => { + format!("Snapshot<{}>", type_to_name(&info.ty, registry)) + } + CoreTypeConcrete::Struct(info) => { + let fields = info + .members + .iter() + .map(|ty_id| type_to_name(ty_id, registry)) + .collect::>(); + let fields = fields.join(", "); + + format!("Struct<{}>", fields) + } + CoreTypeConcrete::Enum(info) => { + let fields = info + .variants + .iter() + .map(|ty_id| type_to_name(ty_id, registry)) + .collect::>(); + let fields = fields.join(", "); + + format!("Enum<{}>", fields) + } + CoreTypeConcrete::Felt252Dict(_) => String::from("Felt252Dict"), + CoreTypeConcrete::Felt252DictEntry(_) => String::from("Felt252DictEntry"), + CoreTypeConcrete::SquashedFelt252Dict(_) => String::from("SquashedFelt252Dict"), + + CoreTypeConcrete::Bitwise(_) => String::from("Bitwise"), + CoreTypeConcrete::Circuit(_) => String::from("Circuit"), + CoreTypeConcrete::Const(_) => String::from("Const"), + CoreTypeConcrete::Coupon(_) => String::from("Coupon"), + CoreTypeConcrete::EcOp(_) => String::from("EcOp"), + CoreTypeConcrete::EcPoint(_) => String::from("EcPoint"), + CoreTypeConcrete::EcState(_) => String::from("EcState"), + CoreTypeConcrete::Felt252(_) => String::from("Felt252"), + CoreTypeConcrete::GasBuiltin(_) => String::from("GasBuiltin"), + CoreTypeConcrete::BuiltinCosts(_) => String::from("BuiltinCosts"), + CoreTypeConcrete::Uint8(_) => String::from("Uint8"), + CoreTypeConcrete::Uint16(_) => String::from("Uint16"), + CoreTypeConcrete::Uint32(_) => String::from("Uint32"), + CoreTypeConcrete::Uint64(_) => String::from("Uint64"), + CoreTypeConcrete::Uint128(_) => String::from("Uint128"), + CoreTypeConcrete::Uint128MulGuarantee(_) => String::from("Uint128MulGuarantee"), + CoreTypeConcrete::Sint8(_) => String::from("Sint8"), + CoreTypeConcrete::Sint16(_) => String::from("Sint16"), + CoreTypeConcrete::Sint32(_) => String::from("Sint32"), + CoreTypeConcrete::Sint64(_) => String::from("Sint64"), + CoreTypeConcrete::Sint128(_) => String::from("Sint128"), + CoreTypeConcrete::RangeCheck(_) => String::from("RangeCheck"), + CoreTypeConcrete::RangeCheck96(_) => String::from("RangeCheck96"), + CoreTypeConcrete::Pedersen(_) => String::from("Pedersen"), + CoreTypeConcrete::Poseidon(_) => String::from("Poseidon"), + CoreTypeConcrete::StarkNet(_) => String::from("StarkNet"), + CoreTypeConcrete::SegmentArena(_) => String::from("SegmentArena"), + CoreTypeConcrete::Bytes31(_) => String::from("Bytes31"), + CoreTypeConcrete::BoundedInt(_) => String::from("BoundedInt"), + } +} + +/// prints all the signature information, used while debugging to learn +/// how to implement a certain libfunc. +#[allow(dead_code)] +pub fn debug_signature( + registry: &ProgramRegistry, + params: &[ParamSignature], + branches: &[BranchSignature], + args: Vec, +) { + println!( + "Params: {:#?}", + params + .iter() + .map(|p| type_to_name(&p.ty, registry)) + .collect::>() + ); + println!( + "Branches: {:#?}", + branches + .iter() + .map(|b| { + b.vars + .iter() + .map(|vars| type_to_name(&vars.ty, registry)) + .collect::>() + }) + .collect::>() + ); + println!("Args: {:#?}", args); +} From 922af702bc6510c6d44fcaa3cc34350c28587848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 12:44:16 -0300 Subject: [PATCH 08/26] Fix bug --- src/vm/starknet.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 887d818..6ad79a7 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -155,7 +155,7 @@ fn eval_secp_r_new( }, None => Value::Enum { self_ty: enum_ty.clone(), - index: 0, + index: 1, payload: Box::new(Value::Unit), }, }; @@ -219,7 +219,7 @@ fn eval_secp_r_get_point_from_x( }, None => Value::Enum { self_ty: enum_ty.clone(), - index: 0, + index: 1, payload: Box::new(Value::Unit), }, }; From 94484cc40598f4dc4114267117f3ae209e7a8eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 14:41:08 -0300 Subject: [PATCH 09/26] Update signature --- src/debug.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug.rs b/src/debug.rs index dc60f32..456241f 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -507,7 +507,7 @@ pub fn debug_signature( registry: &ProgramRegistry, params: &[ParamSignature], branches: &[BranchSignature], - args: Vec, + args: &[Value], ) { println!( "Params: {:#?}", From 22232ddd78252493976e48a47adf49e5d788497e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 14:42:00 -0300 Subject: [PATCH 10/26] Unimplemented inv mod n --- src/vm/uint252.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vm/uint252.rs b/src/vm/uint252.rs index d57682e..7a201be 100644 --- a/src/vm/uint252.rs +++ b/src/vm/uint252.rs @@ -1,10 +1,11 @@ use super::EvalAction; -use crate::Value; +use crate::{debug::debug_signature, Value}; use cairo_lang_sierra::{ extensions::{ core::{CoreLibfunc, CoreType}, int::unsigned256::Uint256Concrete, lib_func::SignatureOnlyConcreteLibfunc, + ConcreteLibfunc, }, program_registry::ProgramRegistry, }; @@ -20,10 +21,25 @@ pub fn eval( Uint256Concrete::IsZero(info) => eval_is_zero(registry, info, args), Uint256Concrete::Divmod(info) => eval_divmod(registry, info, args), Uint256Concrete::SquareRoot(_) => todo!(), - Uint256Concrete::InvModN(_) => todo!(), + Uint256Concrete::InvModN(info) => eval_inv_mod_n(registry, info, args), } } +fn eval_inv_mod_n( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + debug_signature( + registry, + info.param_signatures(), + info.branch_signatures(), + &args, + ); + + todo!(); +} + pub fn eval_is_zero( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, From 5b1a5bfced487173ed20ee5253093e465fb9444b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 14:42:06 -0300 Subject: [PATCH 11/26] Add return check --- src/vm.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vm.rs b/src/vm.rs index bede656..10271e6 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -10,7 +10,7 @@ use cairo_lang_sierra::{ circuit::CircuitTypeConcrete, core::{CoreConcreteLibfunc, CoreLibfunc, CoreType, CoreTypeConcrete}, starknet::StarkNetTypeConcrete, - ConcreteType, + ConcreteLibfunc, ConcreteType, }, ids::{ConcreteLibfuncId, FunctionId, VarId}, program::{GenFunction, GenStatement, Invocation, Program, StatementIdx}, @@ -221,6 +221,21 @@ impl VirtualMachine { "invocation of {invocation} returned the wrong number of values" ); + assert!( + results + .iter() + .zip( + &self + .registry + .get_libfunc(&invocation.libfunc_id) + .unwrap() + .branch_signatures()[branch_idx] + .vars + ) + .all(|(value, ret)| value.is(&self.registry, &ret.ty)), + "invocation of {invocation} returned an invalid argument", + ); + frame.pc = frame.pc.next(&invocation.branches[branch_idx].target); frame.state.set( edit_state::put_results( From 80c6419b7f94d7ce4a47b0e64699832ac81da931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 15:45:25 -0300 Subject: [PATCH 12/26] Improve error message --- src/vm.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vm.rs b/src/vm.rs index 10271e6..422ac47 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -233,7 +233,10 @@ impl VirtualMachine { .vars ) .all(|(value, ret)| value.is(&self.registry, &ret.ty)), - "invocation of {invocation} returned an invalid argument", + "invocation of {} returned an invalid argument", + libfunc_to_name( + self.registry.get_libfunc(&invocation.libfunc_id).unwrap() + ) ); frame.pc = frame.pc.next(&invocation.branches[branch_idx].target); From af4e48b28f1f5228cd236e38be2cb75339bf87fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 15:45:46 -0300 Subject: [PATCH 13/26] Implement is for uninit type --- src/value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/value.rs b/src/value.rs index f0b51a8..3b8485c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -160,7 +160,7 @@ impl Value { CoreTypeConcrete::Sint16(_) => todo!(), CoreTypeConcrete::Sint64(_) => todo!(), CoreTypeConcrete::Nullable(info) => self.is(registry, &info.ty), - CoreTypeConcrete::Uninitialized(_) => todo!(), + CoreTypeConcrete::Uninitialized(_) => matches!(self, Self::Uninitialized { .. }), CoreTypeConcrete::Felt252DictEntry(_) => todo!(), CoreTypeConcrete::SquashedFelt252Dict(_) => todo!(), CoreTypeConcrete::Pedersen(_) => matches!(self, Self::Unit), From 9965b94d2ebe07eb985bf6dc147d1103a0d85e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 15:45:51 -0300 Subject: [PATCH 14/26] Fix non zero const --- src/vm/const.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vm/const.rs b/src/vm/const.rs index d6269d3..8f52d98 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -82,7 +82,13 @@ fn inner( [GenericArg::Value(value)] => Value::Felt(value.into()), _ => unreachable!(), }, - CoreTypeConcrete::NonZero(info) => inner(registry, &info.ty, inner_data), + CoreTypeConcrete::NonZero(_) => match inner_data { + [GenericArg::Type(type_id)] => match registry.get_type(type_id).unwrap() { + CoreTypeConcrete::Const(info) => inner(registry, &info.inner_ty, &info.inner_data), + _ => unreachable!(), + }, + _ => unreachable!(), + }, CoreTypeConcrete::Sint128(_) => match inner_data { [GenericArg::Value(value)] => Value::I128(value.try_into().unwrap()), _ => unreachable!(), From cb774dcaf4e5a6c63bebcb8062a41227b880c25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 15:53:04 -0300 Subject: [PATCH 15/26] Impl inv mod --- src/vm/uint252.rs | 51 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/vm/uint252.rs b/src/vm/uint252.rs index 7a201be..5131715 100644 --- a/src/vm/uint252.rs +++ b/src/vm/uint252.rs @@ -1,11 +1,10 @@ use super::EvalAction; -use crate::{debug::debug_signature, Value}; +use crate::Value; use cairo_lang_sierra::{ extensions::{ core::{CoreLibfunc, CoreType}, int::unsigned256::Uint256Concrete, lib_func::SignatureOnlyConcreteLibfunc, - ConcreteLibfunc, }, program_registry::ProgramRegistry, }; @@ -26,18 +25,46 @@ pub fn eval( } fn eval_inv_mod_n( - registry: &ProgramRegistry, - info: &SignatureOnlyConcreteLibfunc, + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - debug_signature( - registry, - info.param_signatures(), - info.branch_signatures(), - &args, - ); - - todo!(); + let [range_check @ Value::Unit, Value::Struct(x), Value::Struct(modulo)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let [Value::U128(x_lo), Value::U128(x_hi)]: [Value; 2] = x.clone().try_into().unwrap() else { + panic!() + }; + + let [Value::U128(mod_lo), Value::U128(mod_hi)]: [Value; 2] = modulo.clone().try_into().unwrap() + else { + panic!() + }; + + let x = u256_to_biguint(x_lo, x_hi); + let modulo = u256_to_biguint(mod_lo, mod_hi); + + match x.modinv(&modulo) { + Some(r) => EvalAction::NormalBranch( + 0, + smallvec![ + range_check, + u256_to_value(r), + Value::Unit, + Value::Unit, + Value::Unit, + Value::Unit, + Value::Unit, + Value::Unit, + Value::Unit, + Value::Unit + ], + ), + None => EvalAction::NormalBranch(1, smallvec![range_check, Value::Unit, Value::Unit]), + } } pub fn eval_is_zero( From 4f29d66bc1012e5cc1b7563461a5af2e67a8c603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 16:33:30 -0300 Subject: [PATCH 16/26] Add utility functions --- src/starknet/secp256k1_point.rs | 9 +++++++++ src/starknet/secp256r1_point.rs | 9 +++++++++ src/starknet/u256.rs | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/src/starknet/secp256k1_point.rs b/src/starknet/secp256k1_point.rs index 4e3a8a8..0c4844b 100644 --- a/src/starknet/secp256k1_point.rs +++ b/src/starknet/secp256k1_point.rs @@ -15,4 +15,13 @@ impl Secp256k1Point { Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]), ]) } + + pub fn from_value(v: Value) -> Self { + let Value::Struct(mut v) = v else { panic!() }; + + let y = U256::from_value(v.remove(1)); + let x = U256::from_value(v.remove(0)); + + Self { x, y } + } } diff --git a/src/starknet/secp256r1_point.rs b/src/starknet/secp256r1_point.rs index a51ecde..5036f78 100644 --- a/src/starknet/secp256r1_point.rs +++ b/src/starknet/secp256r1_point.rs @@ -15,4 +15,13 @@ impl Secp256r1Point { Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]), ]) } + + pub fn from_value(v: Value) -> Self { + let Value::Struct(mut v) = v else { panic!() }; + + let y = U256::from_value(v.remove(1)); + let x = U256::from_value(v.remove(0)); + + Self { x, y } + } } diff --git a/src/starknet/u256.rs b/src/starknet/u256.rs index da9c75e..43b6803 100644 --- a/src/starknet/u256.rs +++ b/src/starknet/u256.rs @@ -11,4 +11,12 @@ impl U256 { pub(crate) fn into_value(self) -> Value { Value::Struct(vec![Value::U128(self.lo), Value::U128(self.hi)]) } + + pub fn from_value(v: Value) -> Self { + let Value::Struct(v) = v else { panic!() }; + let Value::U128(lo) = v[0] else { panic!() }; + let Value::U128(hi) = v[1] else { panic!() }; + + Self { lo, hi } + } } From 45c8f8ca268a53171f3a9b71b10356d2f39e0051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 16:33:40 -0300 Subject: [PATCH 17/26] Implement more starknet debug prints --- src/debug.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/debug.rs b/src/debug.rs index 456241f..c92b012 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -29,7 +29,7 @@ use cairo_lang_sierra::{ starknet::{ secp256::{Secp256ConcreteLibfunc, Secp256OpConcreteLibfunc}, testing::TestingConcreteLibfunc, - StarkNetConcreteLibfunc, + StarkNetConcreteLibfunc, StarkNetTypeConcrete, }, structure::StructConcreteLibfunc, }, @@ -467,6 +467,19 @@ pub fn type_to_name( CoreTypeConcrete::Felt252Dict(_) => String::from("Felt252Dict"), CoreTypeConcrete::Felt252DictEntry(_) => String::from("Felt252DictEntry"), CoreTypeConcrete::SquashedFelt252Dict(_) => String::from("SquashedFelt252Dict"), + CoreTypeConcrete::StarkNet(selector) => match selector { + StarkNetTypeConcrete::ClassHash(_) => String::from("Starknet::ClassHash"), + StarkNetTypeConcrete::ContractAddress(_) => String::from("Starknet::ContractAddress"), + StarkNetTypeConcrete::StorageBaseAddress(_) => { + String::from("Starknet::StorageBaseAddress") + } + StarkNetTypeConcrete::StorageAddress(_) => String::from("Starknet::StorageAddress"), + StarkNetTypeConcrete::System(_) => String::from("Starknet::System"), + StarkNetTypeConcrete::Secp256Point(_) => String::from("Starknet::Secp256Point"), + StarkNetTypeConcrete::Sha256StateHandle(_) => { + String::from("Starknet::Sha256StateHandle") + } + }, CoreTypeConcrete::Bitwise(_) => String::from("Bitwise"), CoreTypeConcrete::Circuit(_) => String::from("Circuit"), @@ -493,7 +506,6 @@ pub fn type_to_name( CoreTypeConcrete::RangeCheck96(_) => String::from("RangeCheck96"), CoreTypeConcrete::Pedersen(_) => String::from("Pedersen"), CoreTypeConcrete::Poseidon(_) => String::from("Poseidon"), - CoreTypeConcrete::StarkNet(_) => String::from("StarkNet"), CoreTypeConcrete::SegmentArena(_) => String::from("SegmentArena"), CoreTypeConcrete::Bytes31(_) => String::from("Bytes31"), CoreTypeConcrete::BoundedInt(_) => String::from("BoundedInt"), From b8fc9402b63b540d1f01cade5833e22f653801bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 16:33:44 -0300 Subject: [PATCH 18/26] Implement point mul --- src/vm/starknet.rs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 6ad79a7..a5adcdc 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,6 +1,7 @@ use super::EvalAction; use crate::{ - starknet::{StarknetSyscallHandler, U256}, + debug::debug_signature, + starknet::{Secp256r1Point, StarknetSyscallHandler, U256}, Value, }; use cairo_lang_sierra::{ @@ -116,7 +117,7 @@ pub fn eval( match info { cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(info) => eval_secp_r_new(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(_) => todo!(), - cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(info) => eval_secp_r_mul(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(info) => eval_secp_r_get_point_from_x(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), } @@ -125,6 +126,36 @@ pub fn eval( } } +fn eval_secp_r_mul( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + debug_signature( + registry, + info.param_signatures(), + info.branch_signatures(), + &args, + ); + + let [Value::U128(mut gas), system @ Value::Unit, x, n]: [Value; 4] = args.try_into().unwrap() + else { + panic!() + }; + + let x = Secp256r1Point::from_value(x); + let n = U256::from_value(n); + + match syscall_handler.secp256r1_mul(x, n, &mut gas) { + Ok(x) => EvalAction::NormalBranch(0, smallvec![Value::U128(gas), system, x.into_value()]), + Err(r) => { + let r = Value::Struct(r.into_iter().map(Value::Felt).collect::>()); + EvalAction::NormalBranch(1, smallvec![Value::U128(gas), system, r]) + } + } +} + fn eval_secp_r_new( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, From 19d236990d788833387825a273d570c1f7cbc790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 16:34:43 -0300 Subject: [PATCH 19/26] Remove print and add add structure --- src/vm/starknet.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index a5adcdc..2322125 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -116,7 +116,7 @@ pub fn eval( cairo_lang_sierra::extensions::starknet::secp256::Secp256ConcreteLibfunc::R1(info) => { match info { cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(info) => eval_secp_r_new(registry, info, args, syscall_handler), - cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(info) => eval_secp_r_add(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(info) => eval_secp_r_mul(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(info) => eval_secp_r_get_point_from_x(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), @@ -126,19 +126,21 @@ pub fn eval( } } -fn eval_secp_r_mul( +fn eval_secp_r_add( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, args: Vec, syscall_handler: &mut impl StarknetSyscallHandler, ) -> EvalAction { - debug_signature( - registry, - info.param_signatures(), - info.branch_signatures(), - &args, - ); + todo!() +} +fn eval_secp_r_mul( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { let [Value::U128(mut gas), system @ Value::Unit, x, n]: [Value; 4] = args.try_into().unwrap() else { panic!() From 2dc3f9c200116aa5449bbc83af8a72c1829430bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 16:37:46 -0300 Subject: [PATCH 20/26] Implement add --- src/vm/starknet.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 2322125..ceec293 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,6 +1,5 @@ use super::EvalAction; use crate::{ - debug::debug_signature, starknet::{Secp256r1Point, StarknetSyscallHandler, U256}, Value, }; @@ -127,12 +126,26 @@ pub fn eval( } fn eval_secp_r_add( - registry: &ProgramRegistry, - info: &SignatureOnlyConcreteLibfunc, + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, args: Vec, syscall_handler: &mut impl StarknetSyscallHandler, ) -> EvalAction { - todo!() + let [Value::U128(mut gas), system @ Value::Unit, x, y]: [Value; 4] = args.try_into().unwrap() + else { + panic!() + }; + + let x = Secp256r1Point::from_value(x); + let y = Secp256r1Point::from_value(y); + + match syscall_handler.secp256r1_add(x, y, &mut gas) { + Ok(x) => EvalAction::NormalBranch(0, smallvec![Value::U128(gas), system, x.into_value()]), + Err(r) => { + let r = Value::Struct(r.into_iter().map(Value::Felt).collect::>()); + EvalAction::NormalBranch(1, smallvec![Value::U128(gas), system, r]) + } + } } fn eval_secp_r_mul( From 984b10c37c323a849ca187a4d75ab4ff1066d9f6 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 16 Oct 2024 16:58:10 -0300 Subject: [PATCH 21/26] add secp_get_xy libfunc --- src/vm/starknet.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index ceec293..fd86538 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,5 +1,6 @@ use super::EvalAction; use crate::{ + debug::debug_signature, starknet::{Secp256r1Point, StarknetSyscallHandler, U256}, Value, }; @@ -118,7 +119,7 @@ pub fn eval( cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Add(info) => eval_secp_r_add(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::Mul(info) => eval_secp_r_mul(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(info) => eval_secp_r_get_point_from_x(registry, info, args, syscall_handler), - cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(info) => secp_r_get_xy(registry, info, args, syscall_handler), } } }, @@ -300,6 +301,52 @@ fn eval_secp_r_get_point_from_x( } } +fn secp_r_get_xy( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [Value::U128(mut gas), system @ Value::Unit, secp_value]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let secp_value = Secp256r1Point::from_value(secp_value); + + match syscall_handler.secp256r1_get_xy(secp_value, &mut gas) { + Ok(payload) => { + let (x, y) = (payload.0.into_value(), payload.1.into_value()); + EvalAction::NormalBranch(0, smallvec![Value::U128(gas), system, x, y]) + } + Err(payload) => { + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + let payload = payload.into_iter().map(Value::Felt).collect::>(); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: payload + } + ], + ) + } + } +} + fn eval_class_hash_const( _registry: &ProgramRegistry, info: &SignatureAndConstConcreteLibfunc, From 427d1af887b4b06c0ddddb002e95435e09492c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 17:14:07 -0300 Subject: [PATCH 22/26] Remove unused --- src/vm/starknet.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index fd86538..6a30346 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,6 +1,5 @@ use super::EvalAction; use crate::{ - debug::debug_signature, starknet::{Secp256r1Point, StarknetSyscallHandler, U256}, Value, }; From e30c5e82ed99e5c1b109667f685cf12518af92ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 18:49:21 -0300 Subject: [PATCH 23/26] Print circuit types --- src/debug.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/debug.rs b/src/debug.rs index c92b012..8d14588 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -6,7 +6,7 @@ use cairo_lang_sierra::{ boxing::BoxConcreteLibfunc, bytes31::Bytes31ConcreteLibfunc, casts::CastConcreteLibfunc, - circuit::CircuitConcreteLibfunc, + circuit::{CircuitConcreteLibfunc, CircuitTypeConcrete}, const_type::ConstConcreteLibfunc, core::{CoreConcreteLibfunc, CoreLibfunc, CoreType, CoreTypeConcrete}, coupon::CouponConcreteLibfunc, @@ -482,7 +482,31 @@ pub fn type_to_name( }, CoreTypeConcrete::Bitwise(_) => String::from("Bitwise"), - CoreTypeConcrete::Circuit(_) => String::from("Circuit"), + CoreTypeConcrete::Circuit(selector) => match selector { + CircuitTypeConcrete::AddMod(_) => String::from("AddMod"), + CircuitTypeConcrete::MulMod(_) => String::from("MulMod"), + CircuitTypeConcrete::AddModGate(_) => String::from("AddModGate"), + CircuitTypeConcrete::Circuit(_) => String::from("Circuit"), + CircuitTypeConcrete::CircuitData(_) => String::from("CircuitData"), + CircuitTypeConcrete::CircuitOutputs(_) => String::from("CircuitOutputs"), + CircuitTypeConcrete::CircuitPartialOutputs(_) => String::from("CircuitPartialOutputs"), + CircuitTypeConcrete::CircuitDescriptor(_) => String::from("CircuitDescriptor"), + CircuitTypeConcrete::CircuitFailureGuarantee(_) => { + String::from("CircuitFailureGuarantee") + } + CircuitTypeConcrete::CircuitInput(_) => String::from("CircuitInput"), + CircuitTypeConcrete::CircuitInputAccumulator(_) => { + String::from("CircuitInputAccumulator") + } + CircuitTypeConcrete::CircuitModulus(_) => String::from("CircuitModulus"), + CircuitTypeConcrete::InverseGate(_) => String::from("InverseGate"), + CircuitTypeConcrete::MulModGate(_) => String::from("MulModGate"), + CircuitTypeConcrete::SubModGate(_) => String::from("SubModGate"), + CircuitTypeConcrete::U96Guarantee(_) => String::from("U96Guarantee"), + CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => { + String::from("U96LimbsLessThanGuarantee") + } + }, CoreTypeConcrete::Const(_) => String::from("Const"), CoreTypeConcrete::Coupon(_) => String::from("Coupon"), CoreTypeConcrete::EcOp(_) => String::from("EcOp"), From 747c874409405278bab2fad7c4f2ff35d387ab34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 18:49:31 -0300 Subject: [PATCH 24/26] Add circuit types to "is" --- src/value.rs | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/value.rs b/src/value.rs index 3b8485c..c8729e4 100644 --- a/src/value.rs +++ b/src/value.rs @@ -13,6 +13,8 @@ use serde::Serialize; use starknet_types_core::felt::Felt; use std::{collections::HashMap, fmt::Debug, ops::Range}; +use crate::debug::type_to_name; + #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum Value { Array { @@ -128,8 +130,7 @@ impl Value { } CoreTypeConcrete::Uint8(_) => matches!(self, Self::U8(_)), CoreTypeConcrete::Uint32(_) => matches!(self, Self::U32(_)), - CoreTypeConcrete::Uint128(_) - | CoreTypeConcrete::Circuit(CircuitTypeConcrete::U96Guarantee(_)) => { + CoreTypeConcrete::Uint128(_) => { matches!(self, Self::U128(_)) } @@ -137,9 +138,6 @@ impl Value { CoreTypeConcrete::RangeCheck(_) | CoreTypeConcrete::SegmentArena(_) | CoreTypeConcrete::RangeCheck96(_) - | CoreTypeConcrete::Circuit( - CircuitTypeConcrete::AddMod(_) | CircuitTypeConcrete::MulMod(_), - ) | CoreTypeConcrete::StarkNet(StarkNetTypeConcrete::System(_)) => { matches!(self, Self::Unit) } @@ -148,7 +146,29 @@ impl Value { CoreTypeConcrete::Coupon(_) => todo!(), CoreTypeConcrete::Bitwise(_) => matches!(self, Self::Unit), CoreTypeConcrete::Box(info) => self.is(registry, &info.ty), - CoreTypeConcrete::Circuit(_) => todo!(), + + // Circuit related types + CoreTypeConcrete::Circuit(selector) => match selector { + CircuitTypeConcrete::Circuit(_) => matches!(self, Self::Circuit(_)), + CircuitTypeConcrete::CircuitData(_) => matches!(self, Self::Circuit(_)), + CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::CircuitOutputs(_)), + CircuitTypeConcrete::CircuitInput(_) => matches!(self, Self::Unit), + CircuitTypeConcrete::CircuitInputAccumulator(_) => matches!(self, Self::Circuit(_)), + CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)), + CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)), + CircuitTypeConcrete::CircuitDescriptor(_) + | CircuitTypeConcrete::CircuitFailureGuarantee(_) + | CircuitTypeConcrete::AddMod(_) + | CircuitTypeConcrete::MulMod(_) + | CircuitTypeConcrete::AddModGate(_) + | CircuitTypeConcrete::CircuitPartialOutputs(_) + | CircuitTypeConcrete::InverseGate(_) + | CircuitTypeConcrete::MulModGate(_) + | CircuitTypeConcrete::SubModGate(_) + | CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => { + matches!(self, Self::Unit) + } + }, CoreTypeConcrete::Const(_) => todo!(), CoreTypeConcrete::EcOp(_) => matches!(self, Self::Unit), CoreTypeConcrete::EcPoint(_) => matches!(self, Self::EcPoint { .. }), @@ -178,7 +198,12 @@ impl Value { }; if !res { - dbg!("value is mismatch", ty.info(), self); + dbg!( + "value is mismatch", + ty.info(), + self, + type_to_name(type_id, registry) + ); } res From 6781a4c6af2bb63e733eb11e06346eb405641138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 16 Oct 2024 18:51:44 -0300 Subject: [PATCH 25/26] Fix circuit --- src/vm/circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/circuit.rs b/src/vm/circuit.rs index 5764a35..1716614 100644 --- a/src/vm/circuit.rs +++ b/src/vm/circuit.rs @@ -235,7 +235,7 @@ pub fn eval_u96_single_limb_less_than_guarantee_verify( _info: &SignatureOnlyConcreteLibfunc, _args: Vec, ) -> EvalAction { - EvalAction::NormalBranch(0, smallvec![Value::Unit]) + EvalAction::NormalBranch(0, smallvec![Value::U128(0)]) } pub fn eval_u96_guarantee_verify( From 19f2fc1405fcc8f8d7ef8efd5fdf098484f10722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 17 Oct 2024 10:26:05 -0300 Subject: [PATCH 26/26] Rename funcgtion --- src/lib.rs | 13 +++++++------ src/vm/array.rs | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 48068ed..88893fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,24 +35,25 @@ pub fn find_entry_point_by_name<'a>( .find(|x| x.id.debug_name.as_ref().map(|x| x.as_str()) == Some(name)) } -// If type is a single element container, finds it's inner type +// If type is invisible to sierra (i.e. a single element container), +// finds it's actual concrete type recursively. // If not, returns the current type -pub fn find_inner_type( +pub fn find_real_type( registry: &ProgramRegistry, ty: &ConcreteTypeId, ) -> ConcreteTypeId { match registry.get_type(ty).unwrap() { cairo_lang_sierra::extensions::core::CoreTypeConcrete::Box(info) => { - find_inner_type(registry, &info.ty) + find_real_type(registry, &info.ty) } cairo_lang_sierra::extensions::core::CoreTypeConcrete::Uninitialized(info) => { - find_inner_type(registry, &info.ty) + find_real_type(registry, &info.ty) } cairo_lang_sierra::extensions::core::CoreTypeConcrete::Span(info) => { - find_inner_type(registry, &info.ty) + find_real_type(registry, &info.ty) } cairo_lang_sierra::extensions::core::CoreTypeConcrete::Snapshot(info) => { - find_inner_type(registry, &info.ty) + find_real_type(registry, &info.ty) } _ => ty.clone(), } diff --git a/src/vm/array.rs b/src/vm/array.rs index 0c9d092..4f45f56 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::{find_inner_type, Value}; +use crate::{find_real_type, Value}; use cairo_lang_sierra::{ extensions::{ array::ArrayConcreteLibfunc, @@ -47,7 +47,7 @@ fn eval_span_from_tuple( }; let ty = &info.branch_signatures()[0].vars[0].ty; - let ty = find_inner_type(registry, ty); + let ty = find_real_type(registry, ty); let CoreTypeConcrete::Array(info) = registry.get_type(&ty).unwrap() else { panic!()