ab_blake3/
platform.rs

1use crate::{BlockBytes, BlockWords};
2use core::mem;
3
4pub(crate) const MAX_SIMD_DEGREE: usize = 1;
5
6// There are some places where we want a static size that's equal to the
7// MAX_SIMD_DEGREE, but also at least 2. Constant contexts aren't currently
8// allowed to use cmp::max, so we have to hardcode this additional constant
9// value. Get rid of this once cmp::max is a const fn.
10pub(crate) const MAX_SIMD_DEGREE_OR_2: usize = 2;
11
12macro_rules! extract_u32_from_byte_chunks {
13    ($src:ident, $chunk_index:literal) => {
14        u32::from_le_bytes([
15            $src[$chunk_index * 4 + 0],
16            $src[$chunk_index * 4 + 1],
17            $src[$chunk_index * 4 + 2],
18            $src[$chunk_index * 4 + 3],
19        ])
20    };
21}
22
23/// Converts bytes into `u32` words, the size matches BLAKE3 hash
24#[inline(always)]
25pub const fn words_from_le_bytes_32(bytes: &[u8; 32]) -> [u32; 8] {
26    let mut out = [0; 8];
27    out[0] = extract_u32_from_byte_chunks!(bytes, 0);
28    out[1] = extract_u32_from_byte_chunks!(bytes, 1);
29    out[2] = extract_u32_from_byte_chunks!(bytes, 2);
30    out[3] = extract_u32_from_byte_chunks!(bytes, 3);
31    out[4] = extract_u32_from_byte_chunks!(bytes, 4);
32    out[5] = extract_u32_from_byte_chunks!(bytes, 5);
33    out[6] = extract_u32_from_byte_chunks!(bytes, 6);
34    out[7] = extract_u32_from_byte_chunks!(bytes, 7);
35    out
36}
37
38/// Converts bytes into `u32` words, the size matches BLAKE3 block
39#[inline(always)]
40pub const fn words_from_le_bytes_64(bytes: &BlockBytes) -> BlockWords {
41    let mut out = [0; 16];
42    out[0] = extract_u32_from_byte_chunks!(bytes, 0);
43    out[1] = extract_u32_from_byte_chunks!(bytes, 1);
44    out[2] = extract_u32_from_byte_chunks!(bytes, 2);
45    out[3] = extract_u32_from_byte_chunks!(bytes, 3);
46    out[4] = extract_u32_from_byte_chunks!(bytes, 4);
47    out[5] = extract_u32_from_byte_chunks!(bytes, 5);
48    out[6] = extract_u32_from_byte_chunks!(bytes, 6);
49    out[7] = extract_u32_from_byte_chunks!(bytes, 7);
50    out[8] = extract_u32_from_byte_chunks!(bytes, 8);
51    out[9] = extract_u32_from_byte_chunks!(bytes, 9);
52    out[10] = extract_u32_from_byte_chunks!(bytes, 10);
53    out[11] = extract_u32_from_byte_chunks!(bytes, 11);
54    out[12] = extract_u32_from_byte_chunks!(bytes, 12);
55    out[13] = extract_u32_from_byte_chunks!(bytes, 13);
56    out[14] = extract_u32_from_byte_chunks!(bytes, 14);
57    out[15] = extract_u32_from_byte_chunks!(bytes, 15);
58    out
59}
60
61/// Converts `u32` words into bytes, the size matches BLAKE3 hash
62#[inline(always)]
63pub const fn le_bytes_from_words_32(words: &[u32; 8]) -> &[u8; 32] {
64    // SAFETY: All bit patterns are valid, output alignment is smaller (1 byte) than input
65    unsafe { mem::transmute::<&[u32; 8], &[u8; 32]>(words) }
66}