1
+ use crate :: hint_processor:: hint_processor_utils:: felt_to_usize;
1
2
use crate :: stdlib:: { borrow:: Cow , collections:: HashMap , prelude:: * } ;
2
3
3
4
use crate :: types:: errors:: math_errors:: MathError ;
@@ -17,9 +18,11 @@ use crate::{
17
18
vm:: { errors:: hint_errors:: HintError , vm_core:: VirtualMachine } ,
18
19
} ;
19
20
21
+ use num_bigint:: BigUint ;
22
+ use num_integer:: Integer ;
20
23
use num_traits:: ToPrimitive ;
21
24
22
- use super :: hint_utils:: get_integer_from_var_name;
25
+ use super :: hint_utils:: { get_integer_from_var_name, insert_value_into_ap } ;
23
26
24
27
fn get_fixed_size_u32_array < const T : usize > (
25
28
h_range : & Vec < Cow < Felt252 > > ,
@@ -242,6 +245,84 @@ pub fn blake2s_add_uint256_bigend(
242
245
Ok ( ( ) )
243
246
}
244
247
248
+ /* Implements Hint:
249
+ memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)
250
+ */
251
+ pub fn is_less_than_63_bits_and_not_end (
252
+ vm : & mut VirtualMachine ,
253
+ ids_data : & HashMap < String , HintReference > ,
254
+ ap_tracking : & ApTracking ,
255
+ ) -> Result < ( ) , HintError > {
256
+ let end = get_ptr_from_var_name ( "end" , vm, ids_data, ap_tracking) ?;
257
+ let packed_values = get_ptr_from_var_name ( "packed_values" , vm, ids_data, ap_tracking) ?;
258
+
259
+ if end == packed_values {
260
+ insert_value_into_ap ( vm, 0 ) ?
261
+ } else {
262
+ let val = vm. get_integer ( packed_values) ?;
263
+ insert_value_into_ap (
264
+ vm,
265
+ ( val. to_biguint ( ) < ( BigUint :: from ( 1_u32 ) << 63 ) ) as usize ,
266
+ ) ?
267
+ }
268
+ Ok ( ( ) )
269
+ }
270
+
271
+ /* Implements Hint:
272
+ offset = 0
273
+ for i in range(ids.packed_values_len):
274
+ val = (memory[ids.packed_values + i] % PRIME)
275
+ val_len = 2 if val < 2**63 else 8
276
+ if val_len == 8:
277
+ val += 2**255
278
+ for i in range(val_len - 1, -1, -1):
279
+ val, memory[ids.unpacked_u32s + offset + i] = divmod(val, 2**32)
280
+ assert val == 0
281
+ offset += val_len
282
+ */
283
+ pub fn blake2s_unpack_felts (
284
+ vm : & mut VirtualMachine ,
285
+ ids_data : & HashMap < String , HintReference > ,
286
+ ap_tracking : & ApTracking ,
287
+ ) -> Result < ( ) , HintError > {
288
+ let packed_values_len =
289
+ get_integer_from_var_name ( "packed_values_len" , vm, ids_data, ap_tracking) ?;
290
+ let packed_values = get_ptr_from_var_name ( "packed_values" , vm, ids_data, ap_tracking) ?;
291
+ let unpacked_u32s = get_ptr_from_var_name ( "unpacked_u32s" , vm, ids_data, ap_tracking) ?;
292
+
293
+ let vals = vm. get_integer_range ( packed_values, felt_to_usize ( & packed_values_len) ?) ?;
294
+ let pow2_32 = BigUint :: from ( 1_u32 ) << 32 ;
295
+ let pow2_63 = BigUint :: from ( 1_u32 ) << 63 ;
296
+ let pow2_255 = BigUint :: from ( 1_u32 ) << 255 ;
297
+
298
+ // Split value into either 2 or 8 32-bit limbs.
299
+ let out: Vec < MaybeRelocatable > = vals
300
+ . into_iter ( )
301
+ . map ( |val| val. to_biguint ( ) )
302
+ . flat_map ( |val| {
303
+ if val < pow2_63 {
304
+ let ( high, low) = val. div_rem ( & pow2_32) ;
305
+ vec ! [ high, low]
306
+ } else {
307
+ let mut limbs = vec ! [ BigUint :: from( 0_u32 ) ; 8 ] ;
308
+ let mut val: BigUint = val + & pow2_255;
309
+ for limb in limbs. iter_mut ( ) . rev ( ) {
310
+ let ( q, r) = val. div_rem ( & pow2_32) ;
311
+ * limb = r;
312
+ val = q;
313
+ }
314
+ limbs
315
+ }
316
+ } )
317
+ . map ( Felt252 :: from)
318
+ . map ( MaybeRelocatable :: from)
319
+ . collect ( ) ;
320
+
321
+ vm. load_data ( unpacked_u32s, & out)
322
+ . map_err ( HintError :: Memory ) ?;
323
+ Ok ( ( ) )
324
+ }
325
+
245
326
/* Implements Hint:
246
327
%{
247
328
from starkware.cairo.common.cairo_blake2s.blake2s_utils import IV, blake2s_compress
@@ -604,6 +685,103 @@ mod tests {
604
685
. is_none( ) ) ;
605
686
}
606
687
688
+ #[ test]
689
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
690
+ fn is_less_than_63_bits_and_not_end_ends ( ) {
691
+ let hint_code = hint_code:: IS_LESS_THAN_63_BITS_AND_NOT_END ;
692
+ //Create vm
693
+ let mut vm = vm ! ( ) ;
694
+ //Insert ids into memory
695
+ vm. segments = segments ! [ ( ( 1 , 0 ) , ( 1 , 2 ) ) , ( ( 1 , 1 ) , ( 1 , 2 ) ) , ( ( 1 , 2 ) , 123 ) ] ;
696
+ vm. set_fp ( 3 ) ;
697
+ vm. set_ap ( 3 ) ;
698
+ let ids_data = ids_data ! [ "end" , "packed_values" , "value" ] ;
699
+ //Execute the hint
700
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
701
+ //Check data ptr
702
+ check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 0 ) ] ;
703
+ }
704
+
705
+ #[ test]
706
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
707
+ fn is_less_than_63_bits_and_not_end_small ( ) {
708
+ let hint_code = hint_code:: IS_LESS_THAN_63_BITS_AND_NOT_END ;
709
+ //Create vm
710
+ let mut vm = vm ! ( ) ;
711
+ //Insert ids into memory
712
+ vm. segments = segments ! [ ( ( 1 , 0 ) , ( 1 , 3 ) ) , ( ( 1 , 1 ) , ( 1 , 2 ) ) , ( ( 1 , 2 ) , 123 ) ] ;
713
+ vm. set_fp ( 3 ) ;
714
+ vm. set_ap ( 3 ) ;
715
+ let ids_data = ids_data ! [ "end" , "packed_values" , "value" ] ;
716
+ //Execute the hint
717
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
718
+ //Check data ptr
719
+ check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 1 ) ] ;
720
+ }
721
+
722
+ #[ test]
723
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
724
+ fn is_less_than_63_bits_and_not_end_big ( ) {
725
+ let hint_code = hint_code:: IS_LESS_THAN_63_BITS_AND_NOT_END ;
726
+ //Create vm
727
+ let mut vm = vm ! ( ) ;
728
+ //Insert ids into memory
729
+ vm. segments = segments ! [
730
+ ( ( 1 , 0 ) , ( 1 , 3 ) ) ,
731
+ ( ( 1 , 1 ) , ( 1 , 2 ) ) ,
732
+ ( ( 1 , 2 ) , 0x10000000000000000 )
733
+ ] ;
734
+ vm. set_fp ( 3 ) ;
735
+ vm. set_ap ( 3 ) ;
736
+ let ids_data = ids_data ! [ "end" , "packed_values" , "value" ] ;
737
+ //Execute the hint
738
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
739
+ //Check data ptr
740
+ check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 0 ) ] ;
741
+ }
742
+
743
+ #[ test]
744
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
745
+ fn blake2s_unpack_felts ( ) {
746
+ let hint_code = hint_code:: BLAKE2S_UNPACK_FELTS ;
747
+ //Create vm
748
+ let mut vm = vm ! ( ) ;
749
+ //Insert ids into memory
750
+ vm. segments = segments ! [
751
+ ( ( 1 , 0 ) , 2 ) ,
752
+ ( ( 1 , 1 ) , ( 1 , 3 ) ) ,
753
+ ( ( 1 , 2 ) , ( 2 , 0 ) ) ,
754
+ ( ( 1 , 3 ) , 0x123456781234 ) ,
755
+ ( ( 1 , 4 ) , 0x1234abcd5678efab1234abcd )
756
+ ] ;
757
+ vm. set_fp ( 5 ) ;
758
+ vm. set_ap ( 5 ) ;
759
+ let ids_data = ids_data ! [
760
+ "packed_values_len" ,
761
+ "packed_values" ,
762
+ "unpacked_u32s" ,
763
+ "small_value" ,
764
+ "big_value"
765
+ ] ;
766
+ vm. segments . add ( ) ;
767
+ //Execute the hint
768
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
769
+ //Check data ptr
770
+ check_memory ! [
771
+ vm. segments. memory,
772
+ ( ( 2 , 0 ) , 0x1234 ) ,
773
+ ( ( 2 , 1 ) , 0x56781234 ) ,
774
+ ( ( 2 , 2 ) , 0x80000000 ) ,
775
+ ( ( 2 , 3 ) , 0 ) ,
776
+ ( ( 2 , 4 ) , 0 ) ,
777
+ ( ( 2 , 5 ) , 0 ) ,
778
+ ( ( 2 , 6 ) , 0 ) ,
779
+ ( ( 2 , 7 ) , 0x1234abcd ) ,
780
+ ( ( 2 , 8 ) , 0x5678efab ) ,
781
+ ( ( 2 , 9 ) , 0x1234abcd )
782
+ ] ;
783
+ }
784
+
607
785
#[ test]
608
786
#[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
609
787
fn blake2s_add_uint256_bigend_valid_non_zero ( ) {
0 commit comments