@@ -268,51 +268,82 @@ pub fn is_less_than_63_bits_and_not_end(
268
268
Ok ( ( ) )
269
269
}
270
270
271
- /* Implements Hint:
271
+ pub enum BlakeEncodingMode {
272
+ /// 2 limbs if val < 2⁶³, otherwise 8 limbs after adding 2^255.
273
+ UseEncoding ,
274
+ /// Always 8 limbs.
275
+ NoEncoding ,
276
+ }
277
+
278
+ /* If mode is `BlakeEncodingMode::UseEncoding`, implements the following hint:
272
279
offset = 0
273
280
for i in range(ids.packed_values_len):
274
281
val = (memory[ids.packed_values + i] % PRIME)
275
282
val_len = 2 if val < 2**63 else 8
276
283
if val_len == 8:
277
284
val += 2**255
278
- for i in range(val_len - 1, -1, -1):
285
+ for i in range(val_len):
286
+ val, memory[ids.unpacked_u32s + offset + i] = divmod(val, 2**32)
287
+ assert val == 0
288
+ offset += val_len
289
+
290
+ If mode is `BlakeEncodingMode::NoEncoding`, implements the following hint:
291
+ offset = 0
292
+ for i in range(ids.packed_values_len):
293
+ val = (memory[ids.packed_values + i] % PRIME)
294
+ for i in range(8):
279
295
val, memory[ids.unpacked_u32s + offset + i] = divmod(val, 2**32)
280
296
assert val == 0
281
297
offset += val_len
282
298
*/
283
- pub fn blake2s_unpack_felts (
299
+ pub fn split_packed_felts (
284
300
vm : & mut VirtualMachine ,
285
301
ids_data : & HashMap < String , HintReference > ,
286
302
ap_tracking : & ApTracking ,
303
+ mode : BlakeEncodingMode ,
287
304
) -> Result < ( ) , HintError > {
288
305
let packed_values_len =
289
306
get_integer_from_var_name ( "packed_values_len" , vm, ids_data, ap_tracking) ?;
290
307
let packed_values = get_ptr_from_var_name ( "packed_values" , vm, ids_data, ap_tracking) ?;
291
308
let unpacked_u32s = get_ptr_from_var_name ( "unpacked_u32s" , vm, ids_data, ap_tracking) ?;
292
309
293
310
let vals = vm. get_integer_range ( packed_values, felt_to_usize ( & packed_values_len) ?) ?;
311
+
294
312
let pow2_32 = BigUint :: from ( 1_u32 ) << 32 ;
295
313
let pow2_63 = BigUint :: from ( 1_u32 ) << 63 ;
296
314
let pow2_255 = BigUint :: from ( 1_u32 ) << 255 ;
297
315
298
- // Split value into either 2 or 8 32-bit limbs.
299
316
let out: Vec < MaybeRelocatable > = vals
300
317
. 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 {
318
+ . map ( |v| v. to_biguint ( ) )
319
+ . flat_map ( |mut val| match mode {
320
+ BlakeEncodingMode :: NoEncoding => {
321
+ // Always 8 little‑endian limbs.
307
322
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 ( ) {
323
+ for limb in & mut limbs {
310
324
let ( q, r) = val. div_rem ( & pow2_32) ;
311
325
* limb = r;
312
326
val = q;
313
327
}
314
328
limbs
315
329
}
330
+ BlakeEncodingMode :: UseEncoding => {
331
+ if val < pow2_63 {
332
+ // 2 limbs: low, high.
333
+ let ( high, low) = val. div_rem ( & pow2_32) ;
334
+ vec ! [ low, high]
335
+ } else {
336
+ // 8 limbs after adding 2**255.
337
+ val += & pow2_255;
338
+ let mut limbs = vec ! [ BigUint :: from( 0_u32 ) ; 8 ] ;
339
+ for limb in & mut limbs {
340
+ let ( q, r) = val. div_rem ( & pow2_32) ;
341
+ * limb = r;
342
+ val = q;
343
+ }
344
+ limbs
345
+ }
346
+ }
316
347
} )
317
348
. map ( Felt252 :: from)
318
349
. map ( MaybeRelocatable :: from)
@@ -740,22 +771,28 @@ mod tests {
740
771
check_memory ! [ vm. segments. memory, ( ( 1 , 3 ) , 0 ) ] ;
741
772
}
742
773
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
774
+ /// Builds a VM, writes the packed_values_len, packed_values, unpacked_u32s and the
775
+ /// actual small and big felts to the memory.
776
+ /// Returns the VM and the ids_data HashMap.
777
+ fn prepare_vm_for_splitting_felts_for_blake (
778
+ small_val : i128 ,
779
+ big_val : i128 ,
780
+ ) -> ( VirtualMachine , HashMap < String , HintReference > ) {
748
781
let mut vm = vm ! ( ) ;
749
- //Insert ids into memory
750
782
vm. segments = segments ! [
783
+ // ids.packed_values_len = 2
751
784
( ( 1 , 0 ) , 2 ) ,
785
+ // ids.packed_values = (1,3)
752
786
( ( 1 , 1 ) , ( 1 , 3 ) ) ,
787
+ // ids.unpacked_u32s = (2,0)
753
788
( ( 1 , 2 ) , ( 2 , 0 ) ) ,
754
- ( ( 1 , 3 ) , 0x123456781234 ) ,
755
- ( ( 1 , 4 ) , 0x1234abcd5678efab1234abcd )
789
+ // packed small / big felts
790
+ ( ( 1 , 3 ) , small_val) ,
791
+ ( ( 1 , 4 ) , big_val)
756
792
] ;
757
793
vm. set_fp ( 5 ) ;
758
794
vm. set_ap ( 5 ) ;
795
+
759
796
let ids_data = ids_data ! [
760
797
"packed_values_len" ,
761
798
"packed_values" ,
@@ -764,21 +801,64 @@ mod tests {
764
801
"big_value"
765
802
] ;
766
803
vm. segments . add ( ) ;
767
- //Execute the hint
768
- assert_matches ! ( run_hint!( vm, ids_data, hint_code) , Ok ( ( ) ) ) ;
769
- //Check data ptr
804
+ ( vm, ids_data)
805
+ }
806
+
807
+ #[ test]
808
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
809
+ fn blake2s_encode_and_split_felts ( ) {
810
+ let ( mut vm, ids_data) = prepare_vm_for_splitting_felts_for_blake (
811
+ 0x123456781234u128 as i128 ,
812
+ 0x1234abcd5678efab1234abcd ,
813
+ ) ;
814
+ assert_matches ! (
815
+ run_hint!( vm, ids_data, hint_code:: BLAKE2S_ENCODE_AND_SPLIT_FELTS ) ,
816
+ Ok ( ( ) )
817
+ ) ;
818
+ check_memory ! [
819
+ vm. segments. memory,
820
+ ( ( 2 , 0 ) , 0x56781234 ) ,
821
+ ( ( 2 , 1 ) , 0x1234 ) ,
822
+ ( ( 2 , 2 ) , 0x1234abcd ) ,
823
+ ( ( 2 , 3 ) , 0x5678efab ) ,
824
+ ( ( 2 , 4 ) , 0x1234abcd ) ,
825
+ ( ( 2 , 5 ) , 0 ) ,
826
+ ( ( 2 , 6 ) , 0 ) ,
827
+ ( ( 2 , 7 ) , 0 ) ,
828
+ ( ( 2 , 8 ) , 0 ) ,
829
+ ( ( 2 , 9 ) , 0x80000000 ) ,
830
+ ] ;
831
+ }
832
+
833
+ #[ test]
834
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
835
+ fn blake2s_split_felts_to_u32s ( ) {
836
+ let ( mut vm, ids_data) = prepare_vm_for_splitting_felts_for_blake (
837
+ 0x123456781234u128 as i128 ,
838
+ 0x1234abcd5678efab1234abcd5678efab ,
839
+ ) ;
840
+ assert_matches ! (
841
+ run_hint!( vm, ids_data, hint_code:: BLAKE2S_SPLIT_FELTS_TO_U32S ) ,
842
+ Ok ( ( ) )
843
+ ) ;
770
844
check_memory ! [
771
845
vm. segments. memory,
772
- ( ( 2 , 0 ) , 0x1234 ) ,
773
- ( ( 2 , 1 ) , 0x56781234 ) ,
774
- ( ( 2 , 2 ) , 0x80000000 ) ,
846
+ ( ( 2 , 0 ) , 0x56781234 ) ,
847
+ ( ( 2 , 1 ) , 0x1234 ) ,
848
+ ( ( 2 , 2 ) , 0 ) ,
775
849
( ( 2 , 3 ) , 0 ) ,
776
850
( ( 2 , 4 ) , 0 ) ,
777
851
( ( 2 , 5 ) , 0 ) ,
778
852
( ( 2 , 6 ) , 0 ) ,
779
- ( ( 2 , 7 ) , 0x1234abcd ) ,
853
+ ( ( 2 , 7 ) , 0 ) ,
780
854
( ( 2 , 8 ) , 0x5678efab ) ,
781
- ( ( 2 , 9 ) , 0x1234abcd )
855
+ ( ( 2 , 9 ) , 0x1234abcd ) ,
856
+ ( ( 2 , 10 ) , 0x5678efab ) ,
857
+ ( ( 2 , 11 ) , 0x1234abcd ) ,
858
+ ( ( 2 , 12 ) , 0 ) ,
859
+ ( ( 2 , 13 ) , 0 ) ,
860
+ ( ( 2 , 14 ) , 0 ) ,
861
+ ( ( 2 , 15 ) , 0 ) ,
782
862
] ;
783
863
}
784
864
0 commit comments