blake3/
ffi_neon.rs

1use crate::{CVWords, IncrementCounter, BLOCK_LEN, OUT_LEN};
2
3// Unsafe because this may only be called on platforms supporting NEON.
4pub unsafe fn hash_many<const N: usize>(
5    inputs: &[&[u8; N]],
6    key: &CVWords,
7    counter: u64,
8    increment_counter: IncrementCounter,
9    flags: u8,
10    flags_start: u8,
11    flags_end: u8,
12    out: &mut [u8],
13) {
14    // The Rust hash_many implementations do bounds checking on the `out`
15    // array, but the C implementations don't. Even though this is an unsafe
16    // function, assert the bounds here.
17    assert!(out.len() >= inputs.len() * OUT_LEN);
18    ffi::blake3_hash_many_neon(
19        inputs.as_ptr() as *const *const u8,
20        inputs.len(),
21        N / BLOCK_LEN,
22        key.as_ptr(),
23        counter,
24        increment_counter.yes(),
25        flags,
26        flags_start,
27        flags_end,
28        out.as_mut_ptr(),
29    )
30}
31
32// blake3_neon.c normally depends on blake3_portable.c, because the NEON
33// implementation only provides 4x compression, and it relies on the portable
34// implementation for 1x compression. However, we expose the portable Rust
35// implementation here instead, to avoid linking in unnecessary code.
36#[no_mangle]
37pub extern "C" fn blake3_compress_in_place_portable(
38    cv: *mut u32,
39    block: *const u8,
40    block_len: u8,
41    counter: u64,
42    flags: u8,
43) {
44    unsafe {
45        crate::portable::compress_in_place(
46            &mut *(cv as *mut [u32; 8]),
47            &*(block as *const [u8; 64]),
48            block_len,
49            counter,
50            flags,
51        )
52    }
53}
54
55pub mod ffi {
56    extern "C" {
57        pub fn blake3_hash_many_neon(
58            inputs: *const *const u8,
59            num_inputs: usize,
60            blocks: usize,
61            key: *const u32,
62            counter: u64,
63            increment_counter: bool,
64            flags: u8,
65            flags_start: u8,
66            flags_end: u8,
67            out: *mut u8,
68        );
69    }
70}
71
72#[cfg(test)]
73mod test {
74    use super::*;
75
76    #[test]
77    fn test_hash_many() {
78        // This entire file is gated on feature="neon", so NEON support is
79        // assumed here.
80        crate::test::test_hash_many_fn(hash_many, hash_many);
81    }
82}