From 2e2a859b86f4ac68c0e0ea68e4697af88d96c14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 7 Oct 2024 17:51:12 -0300 Subject: [PATCH 01/13] Implement byte reverse --- src/vm/uint128.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index d36e932..813edbe 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -33,7 +33,7 @@ pub fn eval( Uint128Concrete::Bitwise(info) => eval_bitwise(registry, info, args), Uint128Concrete::GuaranteeMul(info) => eval_guarantee_mul(registry, info, args), Uint128Concrete::MulGuaranteeVerify(info) => eval_guarantee_verify(registry, info, args), - Uint128Concrete::ByteReverse(_) => todo!(), + Uint128Concrete::ByteReverse(info) => eval_byte_reverse(registry, info, args), } } @@ -201,3 +201,17 @@ pub fn eval_from_felt( ) } } + +pub fn eval_byte_reverse( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U128(value)]: [Value; 2] = args.try_into().unwrap() else { + panic!() + }; + + let value = value.reverse_bits(); + + EvalAction::NormalBranch(0, smallvec![bitwise, Value::U128(value)]) +} From f53b47a6d30ed1a9c0e5bc424adcd48e423cc371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 8 Oct 2024 13:26:16 -0300 Subject: [PATCH 02/13] Fix warnings --- src/test_utils.rs | 2 ++ src/vm/int128.rs | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test_utils.rs b/src/test_utils.rs index 672ccec..03d70b6 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + use std::{fs, path::Path, sync::Arc}; use cairo_lang_compiler::{ diff --git a/src/vm/int128.rs b/src/vm/int128.rs index e1cfd1a..8c489fe 100644 --- a/src/vm/int128.rs +++ b/src/vm/int128.rs @@ -1,5 +1,3 @@ -use std::u128; - use cairo_lang_sierra::{ extensions::{ core::{CoreLibfunc, CoreType}, @@ -22,12 +20,12 @@ pub fn eval( args: Vec, ) -> EvalAction { match selector { - Sint128Concrete::Const(info) => todo!("1"), + Sint128Concrete::Const(_) => todo!("int128 const"), Sint128Concrete::Operation(info) => eval_operation(registry, info, args), Sint128Concrete::Equal(info) => eval_equal(registry, info, args), Sint128Concrete::ToFelt252(info) => eval_to_felt(registry, info, args), Sint128Concrete::FromFelt252(info) => eval_from_felt(registry, info, args), - Sint128Concrete::IsZero(info) => todo!("6"), + Sint128Concrete::IsZero(_) => todo!("int128 is_zero"), Sint128Concrete::Diff(info) => eval_diff(registry, info, args), } } From 0d0a1b4f294a7f4db199a6ee4833947ce53ecd19 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 8 Oct 2024 17:19:31 -0300 Subject: [PATCH 03/13] impl reverse_bytes for u128 --- src/vm/uint128.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index d36e932..e3876ec 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -33,10 +33,23 @@ pub fn eval( Uint128Concrete::Bitwise(info) => eval_bitwise(registry, info, args), Uint128Concrete::GuaranteeMul(info) => eval_guarantee_mul(registry, info, args), Uint128Concrete::MulGuaranteeVerify(info) => eval_guarantee_verify(registry, info, args), - Uint128Concrete::ByteReverse(_) => todo!(), + Uint128Concrete::ByteReverse(info) => eval_byte_reverse(registry, info, args), } } +pub fn eval_byte_reverse( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U128(input)]: [Value; 2] = args.try_into().unwrap() + else { + panic!() + }; + + EvalAction::NormalBranch(0, smallvec![bitwise, Value::U128(input.swap_bytes())]) +} + pub fn eval_guarantee_mul( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, From 028560083ef2544620a9e4759b57c66e2a0c8fed Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 8 Oct 2024 17:37:33 -0300 Subject: [PATCH 04/13] add default for nullale --- src/value.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/value.rs b/src/value.rs index b0fbb32..487749c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -62,6 +62,7 @@ pub enum Value { U32(u32), U64(u64), U8(u8), + Null, Uninitialized { ty: ConcreteTypeId, }, @@ -80,6 +81,7 @@ impl Value { CoreTypeConcrete::Uint16(_) => Value::U16(0), CoreTypeConcrete::Uint128(_) => Value::U128(0), CoreTypeConcrete::Felt252(_) => Value::Felt(0.into()), + CoreTypeConcrete::Nullable(_) => Value::Null, x => panic!("type {:?} has no default value implementation", x.info()), } } From 8441cec3898440e1ef5fdcf56737bb659847c906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 10 Oct 2024 18:24:55 -0300 Subject: [PATCH 05/13] Add const_as_box function --- src/vm/const.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vm/const.rs b/src/vm/const.rs index 66ad442..a59a9e5 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -2,7 +2,9 @@ use super::EvalAction; use crate::Value; use cairo_lang_sierra::{ extensions::{ - const_type::{ConstAsImmediateConcreteLibfunc, ConstConcreteLibfunc}, + const_type::{ + ConstAsBoxConcreteLibfunc, ConstAsImmediateConcreteLibfunc, ConstConcreteLibfunc, + }, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, }, ids::ConcreteTypeId, @@ -17,7 +19,7 @@ pub fn eval( args: Vec, ) -> EvalAction { match selector { - ConstConcreteLibfunc::AsBox(_) => todo!(), + ConstConcreteLibfunc::AsBox(info) => eval_as_box(registry, info, args), ConstConcreteLibfunc::AsImmediate(info) => eval_as_immediate(registry, info, args), } } @@ -74,6 +76,12 @@ pub fn eval_as_immediate( }, CoreTypeConcrete::Uint32(_) => match inner_data { [GenericArg::Value(value)] => Value::U32(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::Uint8(_) => match inner_data { @@ -120,3 +128,11 @@ pub fn eval_as_immediate( smallvec![inner(registry, &const_ty.inner_ty, &const_ty.inner_data)], ) } + +pub fn eval_as_box( + _registry: &ProgramRegistry, + _info: &ConstAsBoxConcreteLibfunc, + _args: Vec, +) -> EvalAction { + todo!() +} From abc69071f1a09108b6a7d78c46c3602fda162235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 14 Oct 2024 13:33:49 -0300 Subject: [PATCH 06/13] Implement more libs --- src/value.rs | 2 +- src/vm.rs | 5 ++ src/vm/array.rs | 30 ++++++- src/vm/cast.rs | 34 +++++++- src/vm/const.rs | 189 +++++++++++++++++++++++---------------------- src/vm/starknet.rs | 96 ++++++++++++++++++++++- src/vm/uint128.rs | 2 +- 7 files changed, 259 insertions(+), 99 deletions(-) diff --git a/src/value.rs b/src/value.rs index b0fbb32..6b76db8 100644 --- a/src/value.rs +++ b/src/value.rs @@ -173,7 +173,7 @@ impl Value { | StarkNetTypeConcrete::StorageAddress(_) => matches!(self, Self::Felt(_)), StarkNetTypeConcrete::System(_) => matches!(self, Self::Unit), StarkNetTypeConcrete::Secp256Point(_) => todo!(), - StarkNetTypeConcrete::Sha256StateHandle(_) => todo!(), + StarkNetTypeConcrete::Sha256StateHandle(_) => matches!(self, Self::Struct { .. }), }, }; diff --git a/src/vm.rs b/src/vm.rs index 507b124..bede656 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -7,6 +7,7 @@ use crate::{ use cairo_lang_sierra::{ edit_state, extensions::{ + circuit::CircuitTypeConcrete, core::{CoreConcreteLibfunc, CoreLibfunc, CoreType, CoreTypeConcrete}, starknet::StarkNetTypeConcrete, ConcreteType, @@ -137,6 +138,10 @@ impl VirtualMachine { } CoreTypeConcrete::StarkNet(StarkNetTypeConcrete::System(_)) => Value::Unit, CoreTypeConcrete::RangeCheck(_) + | CoreTypeConcrete::RangeCheck96(_) + | CoreTypeConcrete::Circuit( + CircuitTypeConcrete::MulMod(_) | CircuitTypeConcrete::AddMod(_), + ) | CoreTypeConcrete::Pedersen(_) | CoreTypeConcrete::Poseidon(_) | CoreTypeConcrete::Bitwise(_) diff --git a/src/vm/array.rs b/src/vm/array.rs index fbee0f2..e4814e1 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -29,7 +29,9 @@ pub fn eval( eval_snapshot_pop_front(registry, info, args) } ArrayConcreteLibfunc::SnapshotPopBack(info) => eval_snapshot_pop_back(registry, info, args), - ArrayConcreteLibfunc::SnapshotMultiPopFront(_) => todo!(), + ArrayConcreteLibfunc::SnapshotMultiPopFront(info) => { + eval_snapshot_multi_pop_front(registry, info, args) + } ArrayConcreteLibfunc::SnapshotMultiPopBack(_) => todo!(), } } @@ -185,3 +187,29 @@ pub fn eval_snapshot_pop_back( EvalAction::NormalBranch(1, smallvec![Value::Array { data, ty }]) } } + +fn eval_snapshot_multi_pop_front( + registry: &ProgramRegistry, + info: &cairo_lang_sierra::extensions::array::ConcreteMultiPopLibfunc, + args: Vec, +) -> EvalAction { + let [rangecheck, Value::Array { mut data, ty }]: [Value; 2] = args.try_into().unwrap() else { + panic!() + }; + + let CoreTypeConcrete::Struct(popped_cty) = registry.get_type(&info.popped_ty).unwrap() else { + panic!() + }; + + if data.len() >= popped_cty.members.len() { + let new_data = data.split_off(popped_cty.members.len()); + let value = Value::Struct(data); + assert!(value.is(registry, &info.popped_ty)); + EvalAction::NormalBranch( + 0, + smallvec![rangecheck, Value::Array { data: new_data, ty }, value], + ) + } else { + EvalAction::NormalBranch(1, smallvec![rangecheck, Value::Array { data, ty }]) + } +} diff --git a/src/vm/cast.rs b/src/vm/cast.rs index 30a1d03..fde3937 100644 --- a/src/vm/cast.rs +++ b/src/vm/cast.rs @@ -97,7 +97,39 @@ pub fn eval_upcast( CoreTypeConcrete::Uint32(_) => Value::U32(value.try_into().unwrap()), CoreTypeConcrete::Uint64(_) => Value::U64(value.try_into().unwrap()), CoreTypeConcrete::Uint128(_) => Value::U128(value.try_into().unwrap()), - _ => todo!(), + CoreTypeConcrete::Felt252(_) => Value::Felt(value.try_into().unwrap()), + CoreTypeConcrete::Array(_) => todo!("Array"), + CoreTypeConcrete::Coupon(_) => todo!("Coupon"), + CoreTypeConcrete::Bitwise(_) => todo!("Bitwise"), + CoreTypeConcrete::Box(_) => todo!("Box"), + CoreTypeConcrete::Circuit(_) => todo!("Circuit"), + CoreTypeConcrete::Const(_) => todo!("Const"), + CoreTypeConcrete::EcOp(_) => todo!("EcOp"), + CoreTypeConcrete::EcPoint(_) => todo!("EcPoint"), + CoreTypeConcrete::EcState(_) => todo!("EcState"), + CoreTypeConcrete::GasBuiltin(_) => todo!("GasBuiltin"), + CoreTypeConcrete::BuiltinCosts(_) => todo!("BuiltinCosts"), + CoreTypeConcrete::Uint128MulGuarantee(_) => todo!("Uint128MulGuarantee"), + CoreTypeConcrete::Sint16(_) => todo!("Sint16"), + CoreTypeConcrete::Sint64(_) => todo!("Sint64"), + CoreTypeConcrete::NonZero(_) => todo!("NonZero"), + CoreTypeConcrete::Nullable(_) => todo!("Nullable"), + CoreTypeConcrete::RangeCheck(_) => todo!("RangeCheck"), + CoreTypeConcrete::RangeCheck96(_) => todo!("RangeCheck96"), + CoreTypeConcrete::Uninitialized(_) => todo!("Uninitialized"), + CoreTypeConcrete::Enum(_) => todo!("Enum"), + CoreTypeConcrete::Struct(_) => todo!("Struct"), + CoreTypeConcrete::Felt252Dict(_) => todo!("Felt252Dict"), + CoreTypeConcrete::Felt252DictEntry(_) => todo!("Felt252DictEntry"), + CoreTypeConcrete::SquashedFelt252Dict(_) => todo!("SquashedFelt252Dict"), + CoreTypeConcrete::Pedersen(_) => todo!("Pedersen"), + CoreTypeConcrete::Poseidon(_) => todo!("Poseidon"), + CoreTypeConcrete::Span(_) => todo!("Span"), + CoreTypeConcrete::StarkNet(_) => todo!("StarkNet"), + CoreTypeConcrete::SegmentArena(_) => todo!("SegmentArena"), + CoreTypeConcrete::Snapshot(_) => todo!("Snapshot"), + CoreTypeConcrete::Bytes31(_) => todo!("Bytes31"), + CoreTypeConcrete::BoundedInt(_) => todo!("BoundedInt"), }], ) } diff --git a/src/vm/const.rs b/src/vm/const.rs index a59a9e5..a9a805b 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -31,94 +31,6 @@ pub fn eval_as_immediate( ) -> EvalAction { let [] = args.try_into().unwrap(); - fn inner( - registry: &ProgramRegistry, - type_id: &ConcreteTypeId, - inner_data: &[GenericArg], - ) -> Value { - match registry.get_type(type_id).unwrap() { - CoreTypeConcrete::BoundedInt(info) => 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!(), - }, - [GenericArg::Value(value)] => { - assert!(value >= &info.range.lower && value < &info.range.upper); - Value::BoundedInt { - range: info.range.lower.clone()..info.range.upper.clone(), - value: value.clone(), - } - } - _ => unreachable!(), - }, - CoreTypeConcrete::Felt252(_) => match inner_data { - [GenericArg::Value(value)] => Value::Felt(value.into()), - _ => unreachable!(), - }, - CoreTypeConcrete::NonZero(info) => inner(registry, &info.ty, inner_data), - CoreTypeConcrete::Sint128(_) => match inner_data { - [GenericArg::Value(value)] => Value::I128(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Sint32(_) => match inner_data { - [GenericArg::Value(value)] => Value::I32(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Sint8(_) => match inner_data { - [GenericArg::Value(value)] => Value::I8(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Uint64(_) => match inner_data { - [GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Uint32(_) => match inner_data { - [GenericArg::Value(value)] => Value::U32(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::Uint8(_) => match inner_data { - [GenericArg::Value(value)] => Value::U8(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Uint128(_) => match inner_data { - [GenericArg::Value(value)] => Value::U128(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Struct(_) => { - let mut fields = Vec::new(); - - for field in inner_data { - match field { - GenericArg::Type(const_field_ty) => { - let field_type = registry.get_type(const_field_ty).unwrap(); - - match &field_type { - CoreTypeConcrete::Const(const_ty) => { - let field_value = - inner(registry, &const_ty.inner_ty, &const_ty.inner_data); - fields.push(field_value); - } - _ => unreachable!(), - }; - } - _ => unreachable!(), - } - } - - Value::Struct(fields) - } - _ => todo!("{}", type_id), - } - } - let const_ty = match registry.get_type(&info.const_type).unwrap() { CoreTypeConcrete::Const(x) => x, _ => unreachable!(), @@ -130,9 +42,102 @@ pub fn eval_as_immediate( } pub fn eval_as_box( - _registry: &ProgramRegistry, - _info: &ConstAsBoxConcreteLibfunc, - _args: Vec, + registry: &ProgramRegistry, + info: &ConstAsBoxConcreteLibfunc, + args: Vec, ) -> EvalAction { - todo!() + let [] = args.try_into().unwrap(); + + let const_ty = match registry.get_type(&info.const_type).unwrap() { + CoreTypeConcrete::Const(x) => x, + _ => unreachable!(), + }; + EvalAction::NormalBranch( + 0, + smallvec![inner(registry, &const_ty.inner_ty, &const_ty.inner_data)], + ) +} + +fn inner( + registry: &ProgramRegistry, + type_id: &ConcreteTypeId, + inner_data: &[GenericArg], +) -> Value { + match registry.get_type(type_id).unwrap() { + CoreTypeConcrete::BoundedInt(info) => 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!(), + }, + [GenericArg::Value(value)] => { + assert!(value >= &info.range.lower && value < &info.range.upper); + Value::BoundedInt { + range: info.range.lower.clone()..info.range.upper.clone(), + value: value.clone(), + } + } + _ => unreachable!(), + }, + CoreTypeConcrete::Felt252(_) => match inner_data { + [GenericArg::Value(value)] => Value::Felt(value.into()), + _ => unreachable!(), + }, + CoreTypeConcrete::NonZero(info) => inner(registry, &info.ty, inner_data), + CoreTypeConcrete::Sint128(_) => match inner_data { + [GenericArg::Value(value)] => Value::I128(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Sint32(_) => match inner_data { + [GenericArg::Value(value)] => Value::I32(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Sint8(_) => match inner_data { + [GenericArg::Value(value)] => Value::I8(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Uint64(_) => match inner_data { + [GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Uint32(_) => match inner_data { + [GenericArg::Value(value)] => Value::U32(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::Uint8(_) => match inner_data { + [GenericArg::Value(value)] => Value::U8(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Uint128(_) => match inner_data { + [GenericArg::Value(value)] => Value::U128(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Struct(_) => { + let mut fields = Vec::new(); + + for field in inner_data { + match field { + GenericArg::Type(const_field_ty) => { + let field_type = registry.get_type(const_field_ty).unwrap(); + + match &field_type { + CoreTypeConcrete::Const(const_ty) => { + let field_value = + inner(registry, &const_ty.inner_ty, &const_ty.inner_data); + fields.push(field_value); + } + _ => unreachable!(), + }; + } + _ => unreachable!(), + } + } + + Value::Struct(fields) + } + _ => todo!("{}", type_id), + } } diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index fa1401b..7ef0779 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -79,9 +79,15 @@ pub fn eval( } StarkNetConcreteLibfunc::Deploy(info) => eval_deploy(registry, info, args, syscall_handler), StarkNetConcreteLibfunc::Keccak(info) => eval_keccak(registry, info, args, syscall_handler), - StarkNetConcreteLibfunc::Sha256ProcessBlock(_) => todo!(), - StarkNetConcreteLibfunc::Sha256StateHandleInit(_) => todo!(), - StarkNetConcreteLibfunc::Sha256StateHandleDigest(_) => todo!(), + StarkNetConcreteLibfunc::Sha256ProcessBlock(info) => { + eval_sha256_process_block(registry, info, args, syscall_handler) + } + StarkNetConcreteLibfunc::Sha256StateHandleInit(info) => { + eval_sha256_state_handle_init(registry, info, args, syscall_handler) + } + StarkNetConcreteLibfunc::Sha256StateHandleDigest(info) => { + eval_sha256_state_handle_digest(registry, info, args, syscall_handler) + } StarkNetConcreteLibfunc::LibraryCall(info) => { eval_library_call(registry, info, args, syscall_handler) } @@ -925,3 +931,87 @@ fn eval_send_message_to_l1( ), } } + +fn eval_sha256_state_handle_init( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, + _syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [value]: [Value; 1] = args.try_into().unwrap(); + + EvalAction::NormalBranch(0, smallvec![value]) +} + +fn eval_sha256_state_handle_digest( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, + _syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [value]: [Value; 1] = args.try_into().unwrap(); + + EvalAction::NormalBranch(0, smallvec![value]) +} + +fn eval_sha256_process_block( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + let [Value::U128(mut gas), system, Value::Struct(prev_state), Value::Struct(current_block)]: [Value; 4] = args.try_into().unwrap() else { + panic!() + }; + + let prev_state: [u32; 8] = prev_state + .into_iter() + .map(|v| { + let Value::U32(v) = v else { panic!() }; + v + }) + .collect::>() + .try_into() + .unwrap(); + let current_block: [u32; 16] = current_block + .into_iter() + .map(|v| { + let Value::U32(v) = v else { panic!() }; + v + }) + .collect::>() + .try_into() + .unwrap(); + + // 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!(), + } + }; + + match syscall_handler.sha256_process_block(prev_state, current_block, &mut gas) { + Ok(payload) => { + let payload = payload.into_iter().map(Value::U32).collect::>(); + EvalAction::NormalBranch( + 0, + smallvec![Value::U128(gas), system, Value::Struct(payload)], + ) + } + Err(payload) => EvalAction::NormalBranch( + 1, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: payload.into_iter().map(Value::Felt).collect::>(), + } + ], + ), + } +} diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index 813edbe..7dc4c83 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -211,7 +211,7 @@ pub fn eval_byte_reverse( panic!() }; - let value = value.reverse_bits(); + let value = value.swap_bytes(); EvalAction::NormalBranch(0, smallvec![bitwise, Value::U128(value)]) } From 23f439e410380facfa55d54f23e21e4dfae95aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 14 Oct 2024 13:40:58 -0300 Subject: [PATCH 07/13] Remove impossible branches --- src/vm/cast.rs | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/vm/cast.rs b/src/vm/cast.rs index fde3937..10aaacf 100644 --- a/src/vm/cast.rs +++ b/src/vm/cast.rs @@ -98,38 +98,10 @@ pub fn eval_upcast( CoreTypeConcrete::Uint64(_) => Value::U64(value.try_into().unwrap()), CoreTypeConcrete::Uint128(_) => Value::U128(value.try_into().unwrap()), CoreTypeConcrete::Felt252(_) => Value::Felt(value.try_into().unwrap()), - CoreTypeConcrete::Array(_) => todo!("Array"), - CoreTypeConcrete::Coupon(_) => todo!("Coupon"), - CoreTypeConcrete::Bitwise(_) => todo!("Bitwise"), - CoreTypeConcrete::Box(_) => todo!("Box"), - CoreTypeConcrete::Circuit(_) => todo!("Circuit"), - CoreTypeConcrete::Const(_) => todo!("Const"), - CoreTypeConcrete::EcOp(_) => todo!("EcOp"), - CoreTypeConcrete::EcPoint(_) => todo!("EcPoint"), - CoreTypeConcrete::EcState(_) => todo!("EcState"), - CoreTypeConcrete::GasBuiltin(_) => todo!("GasBuiltin"), - CoreTypeConcrete::BuiltinCosts(_) => todo!("BuiltinCosts"), - CoreTypeConcrete::Uint128MulGuarantee(_) => todo!("Uint128MulGuarantee"), CoreTypeConcrete::Sint16(_) => todo!("Sint16"), CoreTypeConcrete::Sint64(_) => todo!("Sint64"), - CoreTypeConcrete::NonZero(_) => todo!("NonZero"), - CoreTypeConcrete::Nullable(_) => todo!("Nullable"), - CoreTypeConcrete::RangeCheck(_) => todo!("RangeCheck"), - CoreTypeConcrete::RangeCheck96(_) => todo!("RangeCheck96"), - CoreTypeConcrete::Uninitialized(_) => todo!("Uninitialized"), - CoreTypeConcrete::Enum(_) => todo!("Enum"), - CoreTypeConcrete::Struct(_) => todo!("Struct"), - CoreTypeConcrete::Felt252Dict(_) => todo!("Felt252Dict"), - CoreTypeConcrete::Felt252DictEntry(_) => todo!("Felt252DictEntry"), - CoreTypeConcrete::SquashedFelt252Dict(_) => todo!("SquashedFelt252Dict"), - CoreTypeConcrete::Pedersen(_) => todo!("Pedersen"), - CoreTypeConcrete::Poseidon(_) => todo!("Poseidon"), - CoreTypeConcrete::Span(_) => todo!("Span"), - CoreTypeConcrete::StarkNet(_) => todo!("StarkNet"), - CoreTypeConcrete::SegmentArena(_) => todo!("SegmentArena"), - CoreTypeConcrete::Snapshot(_) => todo!("Snapshot"), - CoreTypeConcrete::Bytes31(_) => todo!("Bytes31"), CoreTypeConcrete::BoundedInt(_) => todo!("BoundedInt"), + _ => todo!(), }], ) } From 55ddb8bf81fd840dc77ae42f45450971604ce912 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 14 Oct 2024 14:32:06 -0300 Subject: [PATCH 08/13] pull from libs branchs --- src/vm/const.rs | 4 ++++ src/vm/uint128.rs | 13 ------------- 2 files changed, 4 insertions(+), 13 deletions(-) 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(_) => { diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index 09e902b..7dc4c83 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -37,19 +37,6 @@ pub fn eval( } } -pub fn eval_byte_reverse( - _registry: &ProgramRegistry, - _info: &SignatureOnlyConcreteLibfunc, - args: Vec, -) -> EvalAction { - let [bitwise @ Value::Unit, Value::U128(input)]: [Value; 2] = args.try_into().unwrap() - else { - panic!() - }; - - EvalAction::NormalBranch(0, smallvec![bitwise, Value::U128(input.swap_bytes())]) -} - pub fn eval_guarantee_mul( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, From c999c4c1ab69eeaabc4712ac2f16b08260766a27 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 14 Oct 2024 18:13:39 -0300 Subject: [PATCH 09/13] initial getpointfromx --- src/vm/array.rs | 37 +++++++++++++++++++++++++++++-- src/vm/starknet.rs | 54 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/vm/array.rs b/src/vm/array.rs index e4814e1..dd0ccde 100644 --- a/src/vm/array.rs +++ b/src/vm/array.rs @@ -5,6 +5,7 @@ use cairo_lang_sierra::{ 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), @@ -50,7 +51,7 @@ pub fn eval_new( CoreTypeConcrete::Array(info) => &info.ty, _ => unreachable!(), }; - + //dbg!("ARRAY: {}", &ty); EvalAction::NormalBranch( 0, smallvec![Value::Array { @@ -60,6 +61,38 @@ pub fn eval_new( ) } +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 type_info = registry + .get_type(&info.branch_signatures()[0].vars[0].ty) + .unwrap(); + let ty = match type_info { + CoreTypeConcrete::Snapshot(info) => { + let type_info = registry.get_type(&info.ty).unwrap(); + match type_info { + CoreTypeConcrete::Array(info) => &info.ty, + _ => unreachable!(), + } + } + _ => unreachable!(), + }; + + EvalAction::NormalBranch( + 0, + smallvec![Value::Array { + ty: ty.clone(), + data + }], + ) +} + pub fn eval_append( registry: &ProgramRegistry, info: &SignatureAndTypeConcreteLibfunc, diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 7ef0779..e3e71df 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,11 +1,11 @@ use super::EvalAction; -use crate::{starknet::StarknetSyscallHandler, Value}; +use crate::{starknet::{ StarknetSyscallHandler, U256}, Value}; use cairo_lang_sierra::{ extensions::{ consts::SignatureAndConstConcreteLibfunc, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::SignatureOnlyConcreteLibfunc, - starknet::StarkNetConcreteLibfunc, + starknet::{self, secp256::Secp256ConcreteLibfunc, StarkNetConcreteLibfunc}, ConcreteLibfunc, }, program_registry::ProgramRegistry, @@ -98,7 +98,9 @@ pub fn eval( eval_send_message_to_l1(registry, info, args, syscall_handler) } StarkNetConcreteLibfunc::Testing(_info) => todo!(), - StarkNetConcreteLibfunc::Secp256(_info) => todo!(), + StarkNetConcreteLibfunc::Secp256(info) => { + eval_secp256(registry, info, args, syscall_handler) + } } } @@ -1015,3 +1017,49 @@ fn eval_sha256_process_block( ), } } + +fn eval_secp256( + registry: &ProgramRegistry, + info: &Secp256ConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler, +) -> EvalAction { + match info { + Secp256ConcreteLibfunc::K1(libfunc) => match libfunc { + 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!(), + }, + Secp256ConcreteLibfunc::R1(libfunc) => match libfunc { + 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(info) => { + dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); + dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); + dbg!("ARGS {}", &args); + let [Value::U128(mut gas), system, Value::Struct(x_arg), Value::Enum { self_ty: _, index, payload: _ }]: [Value; 4] = args.try_into().unwrap() else { + panic!() + }; + let Value::U128(lo) = x_arg[0] else { + panic!(); + }; + let Value::U128(hi) = x_arg[1] else { + panic!(); + }; + let x = U256 { lo, hi }; + let y_parity = index == 0; + + match syscall_handler.secp256r1_get_point_from_x(x, y_parity, &mut gas) { + Ok(ok) => {}, + Err(err) => {} + } + + EvalAction::NormalBranch(0, smallvec![]) + }, + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), + }, + } +} From ad8183884d6028c870272eee1546860a843c1fbd Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 15 Oct 2024 11:03:28 -0300 Subject: [PATCH 10/13] implement some secp256 libfuncs --- src/value.rs | 2 +- src/vm/starknet.rs | 191 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 167 insertions(+), 26 deletions(-) diff --git a/src/value.rs b/src/value.rs index 3cb165d..4b16f54 100644 --- a/src/value.rs +++ b/src/value.rs @@ -174,7 +174,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 { .. }), }, }; diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index e3e71df..789cffc 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1,5 +1,8 @@ use super::EvalAction; -use crate::{starknet::{ StarknetSyscallHandler, U256}, Value}; +use crate::{ + starknet::{StarknetSyscallHandler, U256}, + Value, +}; use cairo_lang_sierra::{ extensions::{ consts::SignatureAndConstConcreteLibfunc, @@ -1033,33 +1036,171 @@ fn eval_secp256( cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), }, Secp256ConcreteLibfunc::R1(libfunc) => match libfunc { - cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(_) => todo!(), + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::New(info) => eval_secp256r1_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) => { - dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); - dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); - dbg!("ARGS {}", &args); - let [Value::U128(mut gas), system, Value::Struct(x_arg), Value::Enum { self_ty: _, index, payload: _ }]: [Value; 4] = args.try_into().unwrap() else { - panic!() - }; - let Value::U128(lo) = x_arg[0] else { - panic!(); - }; - let Value::U128(hi) = x_arg[1] else { - panic!(); - }; - let x = U256 { lo, hi }; - let y_parity = index == 0; - - match syscall_handler.secp256r1_get_point_from_x(x, y_parity, &mut gas) { - Ok(ok) => {}, - Err(err) => {} - } - - EvalAction::NormalBranch(0, smallvec![]) - }, + cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetPointFromX(info) => eval_secp256r1_get_point_from_x(registry, info, args, syscall_handler), cairo_lang_sierra::extensions::starknet::secp256::Secp256OpConcreteLibfunc::GetXy(_) => todo!(), }, } } + +// Secp256R1 libfuncs evaluations + +fn eval_secp256r1_new( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler +) -> EvalAction { + dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); + dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); + dbg!("ARGS {}", &args); + + let [Value::U128(mut gas), system, Value::Struct(x), Value::Struct(y)]: [Value; 4] = args.try_into().unwrap() else { + panic!() + }; + + let [Value::U128(lo_x), Value::U128(hi_x)]: [Value; 2] = x[..].to_owned().try_into().unwrap() else { + panic!(); + }; + let [Value::U128(lo_y), Value::U128(hi_y)]: [Value; 2] = y[..].to_owned().try_into().unwrap() else { + panic!(); + }; + + let x_u256 = U256 { lo: lo_x, hi: hi_x }; + let y_u256 = U256 { lo: lo_y, hi: hi_y }; + + match syscall_handler.secp256r1_new(x_u256, y_u256, &mut gas) { + Ok(payload) => { + let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); + match payload { + Some(p) => { + dbg!("SOME"); + let payload = Box::new(p.into_value()); + EvalAction::NormalBranch(0, smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 0, + payload + } + ]) + } + None => { + dbg!("NONE"); + let payload = Box::new(Value::Struct(vec![ + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + ])); + EvalAction::NormalBranch(0, smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 1, + payload + }, + ]) + } + }}, + Err(payload) => { + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + EvalAction::NormalBranch(1, smallvec![ + Value::U128(gas), + system, + Value::Array { + ty:felt_ty, + data: payload.into_iter().map(Value::Felt).collect::>() + } + ]) + } + } +} + +fn eval_secp256r1_get_point_from_x( + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, + syscall_handler: &mut impl StarknetSyscallHandler +) -> EvalAction { + // dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); + // dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); + // dbg!("ARGS {}", &args); + let [Value::U128(mut gas), system, Value::Struct(x_arg), Value::Enum { self_ty: _, index, payload: _ }]: [Value; 4] = args.try_into().unwrap() else { + panic!() + }; + + let [Value::U128(lo), Value::U128(hi)]: [Value; 2] = x_arg[..].to_owned().try_into().unwrap() else { + panic!(); + }; + + let x = U256 { lo, hi }; + let y_parity = index == 0; + + match syscall_handler.secp256r1_get_point_from_x(x, y_parity, &mut gas) { + Ok(payload) => { + let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); + match payload { + Some(p) => { + dbg!("SOME"); + let payload = Box::new(p.into_value()); + EvalAction::NormalBranch(0, smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 0, + payload + } + ]) + } + None => { + dbg!("NONE"); + let payload = Box::new(Value::Struct(vec![ + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + ])); + EvalAction::NormalBranch(0, smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 1, + payload + }, + ]) + } + }}, + Err(payload) => { + let felt_ty = { + match registry + .get_type(&info.branch_signatures()[1].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Array(info) => info.ty.clone(), + _ => unreachable!(), + } + }; + + EvalAction::NormalBranch(1, smallvec![ + Value::U128(gas), + system, + Value::Array { + ty:felt_ty, + data: payload.into_iter().map(Value::Felt).collect::>() + } + ]) + } + } +} From b2907a12f33d85f94b20e73ea017dc907169851e Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 15 Oct 2024 11:04:47 -0300 Subject: [PATCH 11/13] format --- src/vm/starknet.rs | 210 +++++++++++++++++++++++++++------------------ 1 file changed, 127 insertions(+), 83 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 789cffc..e9960ac 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -1051,20 +1051,38 @@ fn eval_secp256r1_new( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, args: Vec, - syscall_handler: &mut impl StarknetSyscallHandler + syscall_handler: &mut impl StarknetSyscallHandler, ) -> EvalAction { - dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); - dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); + dbg!( + "SIGNATURE: {}", + info.signature + .param_signatures + .iter() + .map(|x| &x.ty) + .collect::>() + ); + dbg!( + "SIGNATURE: {}", + info.signature + .branch_signatures + .iter() + .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) + .collect::>() + ); dbg!("ARGS {}", &args); - let [Value::U128(mut gas), system, Value::Struct(x), Value::Struct(y)]: [Value; 4] = args.try_into().unwrap() else { + let [Value::U128(mut gas), system, Value::Struct(x), Value::Struct(y)]: [Value; 4] = + args.try_into().unwrap() + else { panic!() }; - let [Value::U128(lo_x), Value::U128(hi_x)]: [Value; 2] = x[..].to_owned().try_into().unwrap() else { + let [Value::U128(lo_x), Value::U128(hi_x)]: [Value; 2] = x[..].to_owned().try_into().unwrap() + else { panic!(); }; - let [Value::U128(lo_y), Value::U128(hi_y)]: [Value; 2] = y[..].to_owned().try_into().unwrap() else { + let [Value::U128(lo_y), Value::U128(hi_y)]: [Value; 2] = y[..].to_owned().try_into().unwrap() + else { panic!(); }; @@ -1075,36 +1093,43 @@ fn eval_secp256r1_new( Ok(payload) => { let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); match payload { - Some(p) => { - dbg!("SOME"); - let payload = Box::new(p.into_value()); - EvalAction::NormalBranch(0, smallvec![ - Value::U128(gas), - system, - Value::Enum { - self_ty: payload_ty, - index: 0, - payload - } - ]) - } - None => { - dbg!("NONE"); - let payload = Box::new(Value::Struct(vec![ - Value::Struct(vec![Value::U128(0), Value::U128(0)]), - Value::Struct(vec![Value::U128(0), Value::U128(0)]), - ])); - EvalAction::NormalBranch(0, smallvec![ - Value::U128(gas), - system, - Value::Enum { - self_ty: payload_ty, - index: 1, - payload - }, - ]) + Some(p) => { + dbg!("SOME"); + let payload = Box::new(p.into_value()); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 0, + payload + } + ], + ) + } + None => { + dbg!("NONE"); + let payload = Box::new(Value::Struct(vec![ + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + ])); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 1, + payload + }, + ], + ) + } } - }}, + } Err(payload) => { let felt_ty = { match registry @@ -1116,14 +1141,17 @@ fn eval_secp256r1_new( } }; - EvalAction::NormalBranch(1, smallvec![ - Value::U128(gas), - system, - Value::Array { - ty:felt_ty, - data: payload.into_iter().map(Value::Felt).collect::>() - } - ]) + EvalAction::NormalBranch( + 1, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: payload.into_iter().map(Value::Felt).collect::>() + } + ], + ) } } } @@ -1132,16 +1160,22 @@ fn eval_secp256r1_get_point_from_x( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, args: Vec, - syscall_handler: &mut impl StarknetSyscallHandler + syscall_handler: &mut impl StarknetSyscallHandler, ) -> EvalAction { // dbg!("SIGNATURE: {}", info.signature.param_signatures.iter().map(|x| &x.ty).collect::>()); // dbg!("SIGNATURE: {}", info.signature.branch_signatures.iter().map(|x| x.vars.iter().map(|x|&x.ty).collect::>()).collect::>()); // dbg!("ARGS {}", &args); - let [Value::U128(mut gas), system, Value::Struct(x_arg), Value::Enum { self_ty: _, index, payload: _ }]: [Value; 4] = args.try_into().unwrap() else { + let [Value::U128(mut gas), system, Value::Struct(x_arg), Value::Enum { + self_ty: _, + index, + payload: _, + }]: [Value; 4] = args.try_into().unwrap() + else { panic!() }; - let [Value::U128(lo), Value::U128(hi)]: [Value; 2] = x_arg[..].to_owned().try_into().unwrap() else { + let [Value::U128(lo), Value::U128(hi)]: [Value; 2] = x_arg[..].to_owned().try_into().unwrap() + else { panic!(); }; @@ -1152,36 +1186,43 @@ fn eval_secp256r1_get_point_from_x( Ok(payload) => { let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); match payload { - Some(p) => { - dbg!("SOME"); - let payload = Box::new(p.into_value()); - EvalAction::NormalBranch(0, smallvec![ - Value::U128(gas), - system, - Value::Enum { - self_ty: payload_ty, - index: 0, - payload - } - ]) - } - None => { - dbg!("NONE"); - let payload = Box::new(Value::Struct(vec![ - Value::Struct(vec![Value::U128(0), Value::U128(0)]), - Value::Struct(vec![Value::U128(0), Value::U128(0)]), - ])); - EvalAction::NormalBranch(0, smallvec![ - Value::U128(gas), - system, - Value::Enum { - self_ty: payload_ty, - index: 1, - payload - }, - ]) + Some(p) => { + dbg!("SOME"); + let payload = Box::new(p.into_value()); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 0, + payload + } + ], + ) + } + None => { + dbg!("NONE"); + let payload = Box::new(Value::Struct(vec![ + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + Value::Struct(vec![Value::U128(0), Value::U128(0)]), + ])); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::U128(gas), + system, + Value::Enum { + self_ty: payload_ty, + index: 1, + payload + }, + ], + ) + } } - }}, + } Err(payload) => { let felt_ty = { match registry @@ -1193,14 +1234,17 @@ fn eval_secp256r1_get_point_from_x( } }; - EvalAction::NormalBranch(1, smallvec![ - Value::U128(gas), - system, - Value::Array { - ty:felt_ty, - data: payload.into_iter().map(Value::Felt).collect::>() - } - ]) + EvalAction::NormalBranch( + 1, + smallvec![ + Value::U128(gas), + system, + Value::Array { + ty: felt_ty, + data: payload.into_iter().map(Value::Felt).collect::>() + } + ], + ) } } } From e7f1da56b8a94092eaad86a9beccd1a41929d2ec Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 15 Oct 2024 17:36:19 -0300 Subject: [PATCH 12/13] add u256 invmod --- src/value.rs | 7 ++++- src/vm/function_call.rs | 4 ++- src/vm/starknet.rs | 47 ++++++++++++++-------------- src/vm/uint252.rs | 68 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/src/value.rs b/src/value.rs index 4b16f54..20c4a55 100644 --- a/src/value.rs +++ b/src/value.rs @@ -108,7 +108,10 @@ impl Value { matches!(self, Self::FeltDict { ty, .. } if *ty == info.ty) } CoreTypeConcrete::GasBuiltin(_) => matches!(self, Self::U128(_)), - CoreTypeConcrete::NonZero(info) => self.is(registry, &info.ty), + CoreTypeConcrete::NonZero(info) => { + dbg!("HOLA NOZERO"); + self.is(registry, &info.ty) + } CoreTypeConcrete::Sint128(_) => matches!(self, Self::I128(_)), CoreTypeConcrete::Sint32(_) => matches!(self, Self::I32(_)), CoreTypeConcrete::Sint8(_) => matches!(self, Self::I8(_)), @@ -120,6 +123,7 @@ impl Value { | StarkNetTypeConcrete::StorageAddress(_), ) => matches!(self, Self::Felt(_)), CoreTypeConcrete::Struct(info) => { + dbg!("HOLA STRUCT"); matches!(self, Self::Struct(members) if members.len() == info.members.len() && members @@ -132,6 +136,7 @@ impl Value { CoreTypeConcrete::Uint32(_) => matches!(self, Self::U32(_)), CoreTypeConcrete::Uint128(_) | CoreTypeConcrete::Circuit(CircuitTypeConcrete::U96Guarantee(_)) => { + dbg!("HOLA U128"); matches!(self, Self::U128(_)) } diff --git a/src/vm/function_call.rs b/src/vm/function_call.rs index 3b72985..bbf8efd 100644 --- a/src/vm/function_call.rs +++ b/src/vm/function_call.rs @@ -17,7 +17,9 @@ pub fn eval( assert!(args .iter() .zip(&info.function.params) - .all(|(value, param)| value.is(registry, ¶m.ty))); + .all(|(value, param)| { + value.is(registry, ¶m.ty) + })); EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect()) } diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index e9960ac..79c7c87 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -8,7 +8,7 @@ use cairo_lang_sierra::{ consts::SignatureAndConstConcreteLibfunc, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::SignatureOnlyConcreteLibfunc, - starknet::{self, secp256::Secp256ConcreteLibfunc, StarkNetConcreteLibfunc}, + starknet::{secp256::Secp256ConcreteLibfunc, StarkNetConcreteLibfunc}, ConcreteLibfunc, }, program_registry::ProgramRegistry, @@ -1053,23 +1053,23 @@ fn eval_secp256r1_new( args: Vec, syscall_handler: &mut impl StarknetSyscallHandler, ) -> EvalAction { - dbg!( - "SIGNATURE: {}", - info.signature - .param_signatures - .iter() - .map(|x| &x.ty) - .collect::>() - ); - dbg!( - "SIGNATURE: {}", - info.signature - .branch_signatures - .iter() - .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) - .collect::>() - ); - dbg!("ARGS {}", &args); + // dbg!( + // "SIGNATURE: {}", + // info.signature + // .param_signatures + // .iter() + // .map(|x| &x.ty) + // .collect::>() + // ); + // dbg!( + // "SIGNATURE: {}", + // info.signature + // .branch_signatures + // .iter() + // .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) + // .collect::>() + // ); + // dbg!("ARGS {}", &args); let [Value::U128(mut gas), system, Value::Struct(x), Value::Struct(y)]: [Value; 4] = args.try_into().unwrap() @@ -1077,11 +1077,11 @@ fn eval_secp256r1_new( panic!() }; - let [Value::U128(lo_x), Value::U128(hi_x)]: [Value; 2] = x[..].to_owned().try_into().unwrap() + let [Value::U128(lo_x), Value::U128(hi_x)]: [Value; 2] = x.to_owned().try_into().unwrap() else { panic!(); }; - let [Value::U128(lo_y), Value::U128(hi_y)]: [Value; 2] = y[..].to_owned().try_into().unwrap() + let [Value::U128(lo_y), Value::U128(hi_y)]: [Value; 2] = y.to_owned().try_into().unwrap() else { panic!(); }; @@ -1092,9 +1092,9 @@ fn eval_secp256r1_new( match syscall_handler.secp256r1_new(x_u256, y_u256, &mut gas) { Ok(payload) => { let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); + match payload { Some(p) => { - dbg!("SOME"); let payload = Box::new(p.into_value()); EvalAction::NormalBranch( 0, @@ -1110,7 +1110,6 @@ fn eval_secp256r1_new( ) } None => { - dbg!("NONE"); let payload = Box::new(Value::Struct(vec![ Value::Struct(vec![Value::U128(0), Value::U128(0)]), Value::Struct(vec![Value::U128(0), Value::U128(0)]), @@ -1131,6 +1130,7 @@ fn eval_secp256r1_new( } } Err(payload) => { + dbg!("ERR"); let felt_ty = { match registry .get_type(&info.branch_signatures()[1].vars[2].ty) @@ -1187,8 +1187,8 @@ fn eval_secp256r1_get_point_from_x( let payload_ty = info.branch_signatures()[0].vars[2].ty.clone(); match payload { Some(p) => { - dbg!("SOME"); let payload = Box::new(p.into_value()); + dbg!(&payload); EvalAction::NormalBranch( 0, smallvec![ @@ -1203,7 +1203,6 @@ fn eval_secp256r1_get_point_from_x( ) } None => { - dbg!("NONE"); let payload = Box::new(Value::Struct(vec![ Value::Struct(vec![Value::U128(0), Value::U128(0)]), Value::Struct(vec![Value::U128(0), Value::U128(0)]), diff --git a/src/vm/uint252.rs b/src/vm/uint252.rs index d57682e..bdc7e91 100644 --- a/src/vm/uint252.rs +++ b/src/vm/uint252.rs @@ -20,7 +20,7 @@ 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), } } @@ -107,3 +107,69 @@ pub fn eval_divmod( ], ) } + +pub fn eval_inv_mod_n( + _registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + // dbg!( + // "SIGNATURE: {}", + // info.signature + // .param_signatures + // .iter() + // .map(|x| &x.ty) + // .collect::>() + // ); + // dbg!( + // "BRANCH: {}", + // info.signature + // .branch_signatures + // .iter() + // .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) + // .collect::>() + // ); + let [range_check @ Value::Unit, Value::Struct(fields), Value::Struct(modulus_struct)]: [Value; + 3] = args.try_into().unwrap() + else { + panic!() + }; + + let [Value::U128(fields_lo), Value::U128(fields_hi)]: [Value; 2] = + fields.clone().try_into().unwrap() + else { + panic!() + }; + + let [Value::Struct(modulus)]: [Value; 1] = modulus_struct.try_into().unwrap() else { + panic!() + }; + + let [Value::U128(mod_lo), Value::U128(mod_hi)]: [Value; 2] = + modulus.clone().try_into().unwrap() + else { + panic!() + }; + + let num = u256_to_biguint(fields_lo, fields_hi); + let modulus = u256_to_biguint(mod_lo, mod_hi); + + match num.modinv(&modulus) { + 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]), + } +} From 753610682910f9cd4e2da8b89b9857e94675b9c6 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 15 Oct 2024 17:40:42 -0300 Subject: [PATCH 13/13] format u256 invmod is not working yet --- src/value.rs | 3 --- src/vm/function_call.rs | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/value.rs b/src/value.rs index 20c4a55..d2940d7 100644 --- a/src/value.rs +++ b/src/value.rs @@ -109,7 +109,6 @@ impl Value { } CoreTypeConcrete::GasBuiltin(_) => matches!(self, Self::U128(_)), CoreTypeConcrete::NonZero(info) => { - dbg!("HOLA NOZERO"); self.is(registry, &info.ty) } CoreTypeConcrete::Sint128(_) => matches!(self, Self::I128(_)), @@ -123,7 +122,6 @@ impl Value { | StarkNetTypeConcrete::StorageAddress(_), ) => matches!(self, Self::Felt(_)), CoreTypeConcrete::Struct(info) => { - dbg!("HOLA STRUCT"); matches!(self, Self::Struct(members) if members.len() == info.members.len() && members @@ -136,7 +134,6 @@ impl Value { CoreTypeConcrete::Uint32(_) => matches!(self, Self::U32(_)), CoreTypeConcrete::Uint128(_) | CoreTypeConcrete::Circuit(CircuitTypeConcrete::U96Guarantee(_)) => { - dbg!("HOLA U128"); matches!(self, Self::U128(_)) } diff --git a/src/vm/function_call.rs b/src/vm/function_call.rs index bbf8efd..a3fa7c1 100644 --- a/src/vm/function_call.rs +++ b/src/vm/function_call.rs @@ -17,9 +17,7 @@ pub fn eval( assert!(args .iter() .zip(&info.function.params) - .all(|(value, param)| { - value.is(registry, ¶m.ty) - })); + .all(|(value, param)| { value.is(registry, ¶m.ty) })); EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect()) }