Internal BLAKE3 implementation. Set `define_var` to `false` if the message on the stack is already defined as [`StackTracker`] variables. Set `use_full_tables` to `false` to use half tables instead of full tables. ## See [`blake3_compute_script_with_limb`].
(
stack: &mut StackTracker,
mut msg_len: u32,
define_var: bool,
use_full_tables: bool,
limb_len: u8,
)
| 20 | /// |
| 21 | /// [`blake3_compute_script_with_limb`]. |
| 22 | fn blake3( |
| 23 | stack: &mut StackTracker, |
| 24 | mut msg_len: u32, |
| 25 | define_var: bool, |
| 26 | use_full_tables: bool, |
| 27 | limb_len: u8, |
| 28 | ) { |
| 29 | // this assumes that the stack is empty |
| 30 | if msg_len == 0 { |
| 31 | // af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262 |
| 32 | //hardcoded hash of empty msg |
| 33 | let empty_msg_hash = "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262"; |
| 34 | let empty_msg_hash_bytearray = <[u8; 32]>::from_hex(empty_msg_hash).unwrap(); |
| 35 | |
| 36 | stack.custom( |
| 37 | script!( |
| 38 | // push the hash value |
| 39 | for byte in empty_msg_hash_bytearray{ |
| 40 | {byte} |
| 41 | } |
| 42 | //convert bytes to nibbles |
| 43 | {U256::transform_limbsize(8,4)} |
| 44 | ), |
| 45 | 0, |
| 46 | false, |
| 47 | 0, |
| 48 | "push empty string hash in nibble form", |
| 49 | ); |
| 50 | stack.define(8_u32 * 8, "blake3-hash"); |
| 51 | return; |
| 52 | } |
| 53 | |
| 54 | // We require message take atmost a chunk. i.e, 1024 bytes. |
| 55 | assert!( |
| 56 | msg_len <= 1024, |
| 57 | "msg length must be less than or equal to 1024 bytes" |
| 58 | ); |
| 59 | assert!( |
| 60 | (4..32).contains(&limb_len), |
| 61 | "limb length must be in the range [4, 32)" |
| 62 | ); |
| 63 | |
| 64 | //number of msg blocks |
| 65 | let num_blocks = msg_len.div_ceil(64); |
| 66 | |
| 67 | // If the compact form of message is on stack but not associated with variable, convert it to StackVariable |
| 68 | if define_var { |
| 69 | let limb_count = 256u32.div_ceil(limb_len as u32); |
| 70 | for i in (0..num_blocks).rev() { |
| 71 | stack.define(limb_count, &format!("msg{}p0", i)); |
| 72 | stack.define(limb_count, &format!("msg{}p1", i)); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | // Push msg to alt stack to get the table on top |
| 77 | for _ in 0..num_blocks { |
| 78 | stack.to_altstack(); |
| 79 | stack.to_altstack(); |
no test coverage detected