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 blake2s_unpack_nondet_jmp (
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) ?. into_owned ( ) ;
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,106 @@ mod tests {
604
684
. is_none( ) ) ;
605
685
}
606
686
687
+ #[ test]
688
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
689
+ fn blake2s_unpack_nondet_jmp_ends ( ) {
690
+ let hint_code =
691
+ "memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)" ;
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 blake2s_unpack_nondet_jmp_small ( ) {
708
+ let hint_code =
709
+ "memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)" ;
710
+ //Create vm
711
+ let mut vm = vm ! ( ) ;
712
+ //Insert ids into memory
713
+ vm. segments = segments ! [ ( ( 1 , 0 ) , ( 1 , 3 ) ) , ( ( 1 , 1 ) , ( 1 , 2 ) ) , ( ( 1 , 2 ) , 123 ) ] ;
714
+ vm. set_fp ( 3 ) ;
715
+ vm. set_ap ( 3 ) ;
716
+ let ids_data = ids_data ! [ "end" , "packed_values" , "value" ] ;
717
+ //Execute the hint
718
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
719
+ //Check data ptr
720
+ check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 1 ) ] ;
721
+ }
722
+
723
+ #[ test]
724
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
725
+ fn blake2s_unpack_nondet_jmp_big ( ) {
726
+ let hint_code =
727
+ "memory[ap] = (ids.end != ids.packed_values) and (memory[ids.packed_values] < 2**63)" ;
728
+ //Create vm
729
+ let mut vm = vm ! ( ) ;
730
+ //Insert ids into memory
731
+ vm. segments = segments ! [
732
+ ( ( 1 , 0 ) , ( 1 , 3 ) ) ,
733
+ ( ( 1 , 1 ) , ( 1 , 2 ) ) ,
734
+ ( ( 1 , 2 ) , 0x10000000000000000 )
735
+ ] ;
736
+ vm. set_fp ( 3 ) ;
737
+ vm. set_ap ( 3 ) ;
738
+ let ids_data = ids_data ! [ "end" , "packed_values" , "value" ] ;
739
+ //Execute the hint
740
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
741
+ //Check data ptr
742
+ check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 0 ) ] ;
743
+ }
744
+
745
+ #[ test]
746
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
747
+ fn blake2s_unpack_felts ( ) {
748
+ let hint_code = hint_code:: BLAKE2S_UNPACK_FELTS ;
749
+ //Create vm
750
+ let mut vm = vm ! ( ) ;
751
+ //Insert ids into memory
752
+ vm. segments = segments ! [
753
+ ( ( 1 , 0 ) , 2 ) ,
754
+ ( ( 1 , 1 ) , ( 1 , 3 ) ) ,
755
+ ( ( 1 , 2 ) , ( 2 , 0 ) ) ,
756
+ ( ( 1 , 3 ) , 0x123456781234 ) ,
757
+ ( ( 1 , 4 ) , 0x1234abcd5678efab1234abcd )
758
+ ] ;
759
+ vm. set_fp ( 5 ) ;
760
+ vm. set_ap ( 5 ) ;
761
+ let ids_data = ids_data ! [
762
+ "packed_values_len" ,
763
+ "packed_values" ,
764
+ "unpacked_u32s" ,
765
+ "small_value" ,
766
+ "big_value"
767
+ ] ;
768
+ vm. segments . add ( ) ;
769
+ //Execute the hint
770
+ assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
771
+ //Check data ptr
772
+ check_memory ! [
773
+ vm. segments. memory,
774
+ ( ( 2 , 0 ) , 0x1234 ) ,
775
+ ( ( 2 , 1 ) , 0x56781234 ) ,
776
+ ( ( 2 , 2 ) , 0x80000000 ) ,
777
+ ( ( 2 , 3 ) , 0 ) ,
778
+ ( ( 2 , 4 ) , 0 ) ,
779
+ ( ( 2 , 5 ) , 0 ) ,
780
+ ( ( 2 , 6 ) , 0 ) ,
781
+ ( ( 2 , 7 ) , 0x1234abcd ) ,
782
+ ( ( 2 , 8 ) , 0x5678efab ) ,
783
+ ( ( 2 , 9 ) , 0x1234abcd )
784
+ ] ;
785
+ }
786
+
607
787
#[ test]
608
788
#[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
609
789
fn blake2s_add_uint256_bigend_valid_non_zero ( ) {
0 commit comments