aboutsummaryrefslogtreecommitdiff
path: root/3rdparty/BLAKE3/src/ffi_neon.rs
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/BLAKE3/src/ffi_neon.rs')
-rw-r--r--3rdparty/BLAKE3/src/ffi_neon.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/3rdparty/BLAKE3/src/ffi_neon.rs b/3rdparty/BLAKE3/src/ffi_neon.rs
new file mode 100644
index 000000000..889974277
--- /dev/null
+++ b/3rdparty/BLAKE3/src/ffi_neon.rs
@@ -0,0 +1,82 @@
+use crate::{CVWords, IncrementCounter, BLOCK_LEN, OUT_LEN};
+
+// Unsafe because this may only be called on platforms supporting NEON.
+pub unsafe fn hash_many<A: arrayvec::Array<Item = u8>>(
+ inputs: &[&A],
+ key: &CVWords,
+ counter: u64,
+ increment_counter: IncrementCounter,
+ flags: u8,
+ flags_start: u8,
+ flags_end: u8,
+ out: &mut [u8],
+) {
+ // The Rust hash_many implementations do bounds checking on the `out`
+ // array, but the C implementations don't. Even though this is an unsafe
+ // function, assert the bounds here.
+ assert!(out.len() >= inputs.len() * OUT_LEN);
+ ffi::blake3_hash_many_neon(
+ inputs.as_ptr() as *const *const u8,
+ inputs.len(),
+ A::CAPACITY / BLOCK_LEN,
+ key.as_ptr(),
+ counter,
+ increment_counter.yes(),
+ flags,
+ flags_start,
+ flags_end,
+ out.as_mut_ptr(),
+ )
+}
+
+// blake3_neon.c normally depends on blake3_portable.c, because the NEON
+// implementation only provides 4x compression, and it relies on the portable
+// implementation for 1x compression. However, we expose the portable Rust
+// implementation here instead, to avoid linking in unnecessary code.
+#[no_mangle]
+pub extern "C" fn blake3_compress_in_place_portable(
+ cv: *mut u32,
+ block: *const u8,
+ block_len: u8,
+ counter: u64,
+ flags: u8,
+) {
+ unsafe {
+ crate::portable::compress_in_place(
+ &mut *(cv as *mut [u32; 8]),
+ &*(block as *const [u8; 64]),
+ block_len,
+ counter,
+ flags,
+ )
+ }
+}
+
+pub mod ffi {
+ extern "C" {
+ pub fn 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,
+ );
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_hash_many() {
+ // This entire file is gated on feature="neon", so NEON support is
+ // assumed here.
+ crate::test::test_hash_many_fn(hash_many, hash_many);
+ }
+}