1use crate::{CVWords, IncrementCounter, BLOCK_LEN, OUT_LEN};
2
3pub unsafe fn compress_in_place(
5 cv: &mut CVWords,
6 block: &[u8; BLOCK_LEN],
7 block_len: u8,
8 counter: u64,
9 flags: u8,
10) {
11 unsafe {
12 ffi::blake3_compress_in_place_sse2(
13 cv.as_mut_ptr(),
14 block.as_ptr(),
15 block_len,
16 counter,
17 flags,
18 )
19 }
20}
21
22pub unsafe fn compress_xof(
24 cv: &CVWords,
25 block: &[u8; BLOCK_LEN],
26 block_len: u8,
27 counter: u64,
28 flags: u8,
29) -> [u8; 64] {
30 unsafe {
31 let mut out = [0u8; 64];
32 ffi::blake3_compress_xof_sse2(
33 cv.as_ptr(),
34 block.as_ptr(),
35 block_len,
36 counter,
37 flags,
38 out.as_mut_ptr(),
39 );
40 out
41 }
42}
43
44pub unsafe fn hash_many<const N: usize>(
46 inputs: &[&[u8; N]],
47 key: &CVWords,
48 counter: u64,
49 increment_counter: IncrementCounter,
50 flags: u8,
51 flags_start: u8,
52 flags_end: u8,
53 out: &mut [u8],
54) {
55 unsafe {
56 assert!(out.len() >= inputs.len() * OUT_LEN);
60 ffi::blake3_hash_many_sse2(
61 inputs.as_ptr() as *const *const u8,
62 inputs.len(),
63 N / BLOCK_LEN,
64 key.as_ptr(),
65 counter,
66 increment_counter.yes(),
67 flags,
68 flags_start,
69 flags_end,
70 out.as_mut_ptr(),
71 )
72 }
73}
74
75pub mod ffi {
76 extern "C" {
77 pub fn blake3_compress_in_place_sse2(
78 cv: *mut u32,
79 block: *const u8,
80 block_len: u8,
81 counter: u64,
82 flags: u8,
83 );
84 pub fn blake3_compress_xof_sse2(
85 cv: *const u32,
86 block: *const u8,
87 block_len: u8,
88 counter: u64,
89 flags: u8,
90 out: *mut u8,
91 );
92 pub fn blake3_hash_many_sse2(
93 inputs: *const *const u8,
94 num_inputs: usize,
95 blocks: usize,
96 key: *const u32,
97 counter: u64,
98 increment_counter: bool,
99 flags: u8,
100 flags_start: u8,
101 flags_end: u8,
102 out: *mut u8,
103 );
104 }
105}
106
107#[cfg(test)]
108mod test {
109 use super::*;
110
111 #[test]
112 fn test_compress() {
113 if !crate::platform::sse2_detected() {
114 return;
115 }
116 crate::test::test_compress_fn(compress_in_place, compress_xof);
117 }
118
119 #[test]
120 fn test_hash_many() {
121 if !crate::platform::sse2_detected() {
122 return;
123 }
124 crate::test::test_hash_many_fn(hash_many, hash_many);
125 }
126}