1 use crate::{CVWords, IncrementCounter, BLOCK_LEN, OUT_LEN};
2
3 // Unsafe because this may only be called on platforms supporting NEON.
hash_many<const N: usize>( inputs: &[&[u8; N]], key: &CVWords, counter: u64, increment_counter: IncrementCounter, flags: u8, flags_start: u8, flags_end: u8, out: &mut [u8], )4 pub 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]
blake3_compress_in_place_portable( cv: *mut u32, block: *const u8, block_len: u8, counter: u64, flags: u8, )37 pub 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
55 pub mod ffi {
56 extern "C" {
blake3_hash_many_neon( inputs: *const *const u8, num_inputs: usize, blocks: usize, key: *const u32, counter: u64, increment_counter: bool, flags: u8, flags_start: u8, flags_end: u8, out: *mut u8, )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)]
73 mod test {
74 use super::*;
75
76 #[test]
test_hash_many()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 }
83