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