@@ -445,8 +445,13 @@ impl VirtualMachine {
445
445
. memory
446
446
. mark_as_accessed ( operands_addresses. op1_addr ) ;
447
447
448
- if instruction. opcode_extension == OpcodeExtension :: Blake {
449
- self . handle_blake2s_instruction ( & operands_addresses) ?;
448
+ if instruction. opcode_extension == OpcodeExtension :: Blake
449
+ || instruction. opcode_extension == OpcodeExtension :: BlakeFinalize
450
+ {
451
+ self . handle_blake2s_instruction (
452
+ & operands_addresses,
453
+ instruction. opcode_extension == OpcodeExtension :: BlakeFinalize ,
454
+ ) ?;
450
455
}
451
456
452
457
self . update_registers ( instruction, operands) ?;
@@ -455,7 +460,7 @@ impl VirtualMachine {
455
460
Ok ( ( ) )
456
461
}
457
462
458
- /// Executes a Blake2s instruction.
463
+ /// Executes a Blake2s or Blake2sLastBlock instruction.
459
464
/// Expects operands to be RelocatableValue and to point to segments of memory.
460
465
/// op0 is expected to point to a sequence of 8 u32 values (state).
461
466
/// op1 is expected to point to a sequence of 16 u32 values (message).
@@ -469,6 +474,7 @@ impl VirtualMachine {
469
474
fn handle_blake2s_instruction (
470
475
& mut self ,
471
476
operands_addresses : & OperandsAddresses ,
477
+ is_last_block : bool ,
472
478
) -> Result < ( ) , VirtualMachineError > {
473
479
let counter = self . segments . memory . get_u32 ( operands_addresses. dst_addr ) ?;
474
480
@@ -490,10 +496,12 @@ impl VirtualMachine {
490
496
. try_into ( )
491
497
. map_err ( |_| VirtualMachineError :: Blake2sInvalidOperand ( 1 , 16 ) ) ?;
492
498
499
+ let f0 = if is_last_block { 0xffffffff } else { 0 } ;
500
+
493
501
let ap = self . run_context . get_ap ( ) ;
494
502
let output_address = self . segments . memory . get_relocatable ( ap) ?;
495
503
496
- let new_state = blake2s_compress ( & state, & message, counter, 0 , 0 , 0 ) ;
504
+ let new_state = blake2s_compress ( & state, & message, counter, 0 , f0 , 0 ) ;
497
505
498
506
for ( i, & val) in new_state. iter ( ) . enumerate ( ) {
499
507
self . segments . memory . insert_as_accessed (
@@ -4496,7 +4504,7 @@ mod tests {
4496
4504
} ;
4497
4505
4498
4506
assert_matches ! (
4499
- vm. handle_blake2s_instruction( & operands_addresses) ,
4507
+ vm. handle_blake2s_instruction( & operands_addresses, false ) ,
4500
4508
Err ( VirtualMachineError :: Memory ( MemoryError :: UnknownMemoryCell ( bx) ) ) if * bx == ( 0 , 7 ) . into( )
4501
4509
) ;
4502
4510
}
@@ -4528,7 +4536,7 @@ mod tests {
4528
4536
} ;
4529
4537
4530
4538
assert_matches ! (
4531
- vm. handle_blake2s_instruction( & operands_addresses) ,
4539
+ vm. handle_blake2s_instruction( & operands_addresses, false ) ,
4532
4540
Err ( VirtualMachineError :: Memory ( MemoryError :: UnknownMemoryCell ( bx) ) ) if * bx == ( 0 , 8 ) . into( )
4533
4541
) ;
4534
4542
}
@@ -4568,7 +4576,7 @@ mod tests {
4568
4576
} ;
4569
4577
4570
4578
assert_matches ! (
4571
- vm. handle_blake2s_instruction( & operands_addresses) ,
4579
+ vm. handle_blake2s_instruction( & operands_addresses, false ) ,
4572
4580
Err ( VirtualMachineError :: Memory ( MemoryError :: InconsistentMemory ( bx) ) ) if * bx == ( ( 0 , 0 ) . into( ) , 0 . into( ) , 1848029226 . into( ) )
4573
4581
) ;
4574
4582
}
@@ -4621,7 +4629,10 @@ mod tests {
4621
4629
ap : 0 ,
4622
4630
fp : 0 ,
4623
4631
} ;
4624
- assert_matches ! ( vm. handle_blake2s_instruction( & operands_addresses) , Ok ( ( ) ) ) ;
4632
+ assert_matches ! (
4633
+ vm. handle_blake2s_instruction( & operands_addresses, false ) ,
4634
+ Ok ( ( ) )
4635
+ ) ;
4625
4636
4626
4637
let state: [ u32 ; 8 ] = vm
4627
4638
. get_u32_range ( ( 0 , 0 ) . into ( ) , 8 )
@@ -4647,6 +4658,84 @@ mod tests {
4647
4658
assert_eq ! ( new_state, expected_new_state) ;
4648
4659
}
4649
4660
4661
+ #[ test]
4662
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
4663
+ fn handle_blake2s_last_block_instruction_ok ( ) {
4664
+ let mut vm = vm ! ( ) ;
4665
+ vm. segments . memory = memory ! [
4666
+ // State
4667
+ ( ( 0 , 0 ) , 0x6B08E647 ) ,
4668
+ ( ( 0 , 1 ) , 0xBB67AE85 ) ,
4669
+ ( ( 0 , 2 ) , 0x3C6EF372 ) ,
4670
+ ( ( 0 , 3 ) , 0xA54FF53A ) ,
4671
+ ( ( 0 , 4 ) , 0x510E527F ) ,
4672
+ ( ( 0 , 5 ) , 0x9B05688C ) ,
4673
+ ( ( 0 , 6 ) , 0x1F83D9AB ) ,
4674
+ ( ( 0 , 7 ) , 0x5BE0CD19 ) ,
4675
+ // Message
4676
+ ( ( 0 , 8 ) , 930933030 ) ,
4677
+ ( ( 0 , 9 ) , 1766240503 ) ,
4678
+ ( ( 0 , 10 ) , 3660871006 ) ,
4679
+ ( ( 0 , 11 ) , 388409270 ) ,
4680
+ ( ( 0 , 12 ) , 1948594622 ) ,
4681
+ ( ( 0 , 13 ) , 3119396969 ) ,
4682
+ ( ( 0 , 14 ) , 3924579183 ) ,
4683
+ ( ( 0 , 15 ) , 2089920034 ) ,
4684
+ ( ( 0 , 16 ) , 3857888532 ) ,
4685
+ ( ( 0 , 17 ) , 929304360 ) ,
4686
+ ( ( 0 , 18 ) , 1810891574 ) ,
4687
+ ( ( 0 , 19 ) , 860971754 ) ,
4688
+ ( ( 0 , 20 ) , 1822893775 ) ,
4689
+ ( ( 0 , 21 ) , 2008495810 ) ,
4690
+ ( ( 0 , 22 ) , 2958962335 ) ,
4691
+ ( ( 0 , 23 ) , 2340515744 ) ,
4692
+ // Counter
4693
+ ( ( 0 , 24 ) , 64 ) ,
4694
+ // AP
4695
+ ( ( 1 , 0 ) , ( 0 , 25 ) ) ,
4696
+ ( ( 2 , 0 ) , ( 0 , 0 ) ) ,
4697
+ ( ( 2 , 1 ) , ( 0 , 8 ) )
4698
+ ] ;
4699
+ let operands_addresses = OperandsAddresses {
4700
+ dst_addr : ( 0 , 24 ) . into ( ) ,
4701
+ op0_addr : ( 2 , 0 ) . into ( ) ,
4702
+ op1_addr : ( 2 , 1 ) . into ( ) ,
4703
+ } ;
4704
+ vm. run_context = RunContext {
4705
+ pc : ( 0 , 0 ) . into ( ) ,
4706
+ ap : 0 ,
4707
+ fp : 0 ,
4708
+ } ;
4709
+ assert_matches ! (
4710
+ vm. handle_blake2s_instruction( & operands_addresses, true ) ,
4711
+ Ok ( ( ) )
4712
+ ) ;
4713
+
4714
+ let state: [ u32 ; 8 ] = vm
4715
+ . get_u32_range ( ( 0 , 0 ) . into ( ) , 8 )
4716
+ . unwrap ( )
4717
+ . try_into ( )
4718
+ . unwrap ( ) ;
4719
+ let message: [ u32 ; 16 ] = vm
4720
+ . get_u32_range ( ( 0 , 8 ) . into ( ) , 16 )
4721
+ . unwrap ( )
4722
+ . try_into ( )
4723
+ . unwrap ( ) ;
4724
+ let counter = vm. segments . memory . get_u32 ( ( 0 , 24 ) . into ( ) ) . unwrap ( ) ;
4725
+
4726
+ let expected_new_state: [ u32 ; 8 ] =
4727
+ blake2s_compress ( & state, & message, counter, 0 , 0xffffffff , 0 )
4728
+ . try_into ( )
4729
+ . unwrap ( ) ;
4730
+
4731
+ let new_state: [ u32 ; 8 ] = vm
4732
+ . get_u32_range ( ( 0 , 25 ) . into ( ) , 8 )
4733
+ . unwrap ( )
4734
+ . try_into ( )
4735
+ . unwrap ( ) ;
4736
+ assert_eq ! ( new_state, expected_new_state) ;
4737
+ }
4738
+
4650
4739
#[ test]
4651
4740
#[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test) ]
4652
4741
fn get_traceback_entries_bad_usort ( ) {
0 commit comments