apple_cryptokit/hashing/
sha512.rs

1// SHA-512 hash algorithm implementation
2
3use super::HashFunction;
4use std::ffi::c_void;
5
6/// SHA-512 output size
7pub const SHA512_OUTPUT_SIZE: usize = 64;
8
9// SHA512 Swift FFI declarations
10extern "C" {
11    #[link_name = "sha512_hash"]
12    fn swift_sha512_hash(data: *const u8, length: i32, out_hash: *mut u8);
13
14    #[link_name = "sha512_init"]
15    fn swift_sha512_init() -> *mut c_void;
16
17    #[link_name = "sha512_update"]
18    fn swift_sha512_update(ptr: *mut c_void, data: *const u8, len: i32);
19
20    #[link_name = "sha512_finalize"]
21    fn swift_sha512_finalize(ptr: *mut c_void, out: *mut u8);
22
23    #[link_name = "sha512_free"]
24    fn swift_sha512_free(ptr: *mut c_void);
25}
26
27/// SHA512 one-shot hash computation
28pub fn sha512_hash(data: &[u8]) -> [u8; 64] {
29    let mut output = [0u8; 64];
30    sha512_hash_to(data, &mut output);
31    output
32}
33
34/// SHA512 hash computation to provided buffer (zero allocation)
35///
36/// # Arguments
37/// - `output`: must be at least 64 bytes
38///
39/// # Panics
40/// Panics if output buffer is too small
41pub fn sha512_hash_to(data: &[u8], output: &mut [u8]) {
42    assert!(
43        output.len() >= SHA512_OUTPUT_SIZE,
44        "Output buffer too small: {} < {}",
45        output.len(),
46        SHA512_OUTPUT_SIZE
47    );
48    unsafe {
49        swift_sha512_hash(data.as_ptr(), data.len() as i32, output.as_mut_ptr());
50    }
51}
52
53/// SHA512 streaming hash state
54pub struct Sha512 {
55    ptr: *mut c_void,
56}
57
58impl Sha512 {
59    /// Create a new SHA512 hash state
60    pub fn new() -> Self {
61        let ptr = unsafe { swift_sha512_init() };
62        Self { ptr }
63    }
64
65    /// Update hash state
66    pub fn update(&mut self, data: &[u8]) {
67        unsafe {
68            swift_sha512_update(self.ptr, data.as_ptr(), data.len() as i32);
69        }
70    }
71
72    /// Finalize hash computation and return result
73    pub fn finalize(self) -> [u8; 64] {
74        self.snapshot()
75    }
76
77    pub fn snapshot(&self) -> [u8; 64] {
78        let mut hash = [0u8; 64];
79        unsafe {
80            swift_sha512_finalize(self.ptr, hash.as_mut_ptr());
81        }
82        hash
83    }
84}
85
86impl Default for Sha512 {
87    fn default() -> Self {
88        Self::new()
89    }
90}
91
92impl Drop for Sha512 {
93    fn drop(&mut self) {
94        unsafe {
95            swift_sha512_free(self.ptr);
96        }
97    }
98}
99
100/// SHA512 hash algorithm implementation
101pub struct SHA512;
102
103impl HashFunction for SHA512 {
104    const OUTPUT_SIZE: usize = SHA512_OUTPUT_SIZE;
105
106    fn hash_to(data: &[u8], output: &mut [u8]) {
107        sha512_hash_to(data, output)
108    }
109}
110
111// Re-export
112pub use SHA512 as Sha512Algorithm;