@@ -12,7 +12,6 @@ use cairo_lang_sierra_gas::core_libfunc_cost::{
1212use itertools:: Itertools ;
1313use lambdaworks_math:: field:: fields:: mersenne31:: extensions:: Degree4ExtensionField ;
1414use lazy_static:: lazy_static;
15- use num_bigint:: BigInt ;
1615use num_traits:: { ToPrimitive , Zero } ;
1716use rand:: Rng ;
1817use starknet_curve:: curve_params:: BETA ;
@@ -30,7 +29,6 @@ use std::{
3029 fs:: File ,
3130 io:: Write ,
3231 mem:: { forget, ManuallyDrop } ,
33- ops:: Shl ,
3432 os:: fd:: FromRawFd ,
3533 ptr:: { self , null_mut} ,
3634 rc:: Rc ,
@@ -191,7 +189,7 @@ pub unsafe extern "C" fn cairo_native__libfunc__blake_compress(
191189/// Felt252 type used in cairo native runtime
192190#[ derive( Debug ) ]
193191pub struct FeltDict {
194- pub mappings : HashMap < [ u8 ; 32 ] , usize > ,
192+ pub mappings : HashMap < Felt , usize > ,
195193
196194 pub layout : Layout ,
197195 pub elements : * mut ( ) ,
@@ -308,7 +306,7 @@ pub unsafe extern "C" fn cairo_native__dict_get(
308306 let num_mappings = dict. mappings . len ( ) ;
309307 let has_capacity = num_mappings != dict. mappings . capacity ( ) ;
310308
311- let ( is_present, index) = match dict. mappings . entry ( * key) {
309+ let ( is_present, index) = match dict. mappings . entry ( Felt :: from_bytes_le ( key) ) {
312310 Entry :: Occupied ( entry) => ( true , * entry. get ( ) ) ,
313311 Entry :: Vacant ( entry) => {
314312 entry. insert ( num_mappings) ;
@@ -364,24 +362,22 @@ unsafe fn create_dict_entries_array(dict: &mut FeltDict) -> ArrayAbi<c_void> {
364362
365363 // Allocate data separately (no inline prefix)
366364 let data_ptr = libc_malloc ( tuple_stride * dict. mappings . len ( ) ) ;
365+ let mut work_ptr = data_ptr;
367366
368367 // Get the stride for the inner types of the tuple
369368 let key_size = Layout :: new :: < Felt252Abi > ( ) . pad_to_align ( ) . size ( ) ;
370- let generic_ty_size = dict. layout . pad_to_align ( ) . size ( ) ;
371-
372- for ( key, elem_index) in & dict. mappings {
373- // Move the ptr to the offset of the tuple we want to modify
374- let key_ptr = data_ptr. byte_add ( tuple_stride * elem_index) as * mut [ u8 ; 32 ] ;
375-
376- // Save the key and move to the offset of the 'first_value'
377- * key_ptr = * key;
378- let first_val_ptr = key_ptr. byte_add ( key_size) as * mut u8 ;
379- first_val_ptr. write_bytes ( 0 , generic_ty_size) ;
380-
381- // Get the element, move to the offset of the 'last_value' and save the element in that address
382- let element = dict. elements . byte_add ( generic_ty_size * elem_index) as * mut u8 ;
383- let last_val_ptr = first_val_ptr. byte_add ( generic_ty_size) ;
384- std:: ptr:: copy_nonoverlapping ( element, last_val_ptr, generic_ty_size) ;
369+ let element_size = dict. layout . pad_to_align ( ) . size ( ) ;
370+
371+ for ( key, elem_index) in dict. mappings . iter ( ) . sorted ( ) {
372+ let key_ptr = work_ptr as * mut [ u8 ; 32 ] ;
373+ let default_value_ptr = work_ptr. byte_add ( key_size) as * mut u8 ;
374+ let final_value_ptr = default_value_ptr. byte_add ( element_size) ;
375+ work_ptr = work_ptr. byte_add ( tuple_stride) ;
376+
377+ * key_ptr = key. to_bytes_le ( ) ;
378+ default_value_ptr. write_bytes ( 0 , element_size) ;
379+ let value = dict. elements . byte_add ( element_size * elem_index) as * mut u8 ;
380+ final_value_ptr. copy_from_nonoverlapping ( value, element_size) ;
385381 }
386382
387383 // Allocate and initialize ArrayMetadata struct
@@ -444,7 +440,7 @@ pub unsafe extern "C" fn cairo_native__dict_squash(
444440 range_check_ptr : & mut u64 ,
445441 gas_ptr : & mut u64 ,
446442) {
447- let dict = Rc :: from_raw ( dict_ptr) ;
443+ let dict = & * dict_ptr;
448444
449445 * gas_ptr +=
450446 ( dict. count . saturating_sub ( dict. mappings . len ( ) as u64 ) ) * * DICT_GAS_REFUND_PER_ACCESS ;
@@ -453,11 +449,8 @@ pub unsafe extern "C" fn cairo_native__dict_squash(
453449 // https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/felt252_dict.rs?plain=1#L131-L136
454450 * range_check_ptr += 2 ;
455451
456- let no_big_keys = dict
457- . mappings
458- . keys ( )
459- . map ( Felt :: from_bytes_le)
460- . all ( |key| key < Felt :: from ( BigInt :: from ( 1 ) . shl ( 128 ) ) ) ;
452+ let u128_max = Felt :: from ( u128:: MAX ) ;
453+ let no_big_keys = dict. mappings . keys ( ) . all ( |key| * key <= u128_max) ;
461454 let number_of_keys = dict. mappings . len ( ) as u64 ;
462455
463456 // How we update the range check depends on whether we have any big key or not.
@@ -498,8 +491,6 @@ pub unsafe extern "C" fn cairo_native__dict_squash(
498491 // For each non unique accessed key, we increase the range check an additional time.
499492 // https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/felt252_dict.rs?plain=1#L602
500493 * range_check_ptr += dict. count . saturating_sub ( dict. mappings . len ( ) as u64 ) ;
501-
502- forget ( dict) ;
503494}
504495
505496/// Compute `ec_point_from_x_nz(x)` and store it.
0 commit comments