Skip to main content

lib_q_hash/
sha2_hashes.rs

1//! SHA-2 family (FIPS 180-4) wrappers implementing [`lib_q_core::Hash`].
2//!
3//! These are standard symmetric hash functions used for interoperability and as
4//! building blocks; they complement the SHA-3 / Keccak family in this crate.
5
6use alloc::vec::Vec;
7
8use digest::Digest;
9use lib_q_core::{
10    Hash,
11    Result,
12};
13use sha2::{
14    Sha224,
15    Sha256,
16    Sha384,
17    Sha512,
18    Sha512_224,
19    Sha512_256,
20};
21
22macro_rules! impl_sha2_fixed_output {
23    ($name:ident, $state:ty, $out_len:expr) => {
24        /// Fixed-output SHA-2 wrapper for the lib-q [`Hash`] trait.
25        #[derive(Clone, Debug)]
26        pub struct $name($state);
27
28        impl $name {
29            /// Create a new hasher in its initial state.
30            pub fn new() -> Self {
31                Self(Default::default())
32            }
33        }
34
35        impl Default for $name {
36            fn default() -> Self {
37                Self::new()
38            }
39        }
40
41        impl Hash for $name {
42            fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
43                let mut h = self.0.clone();
44                Digest::update(&mut h, data);
45                Ok(h.finalize().to_vec())
46            }
47
48            fn output_size(&self) -> usize {
49                $out_len
50            }
51        }
52    };
53}
54
55impl_sha2_fixed_output!(Sha224Hash, Sha224, 28);
56impl_sha2_fixed_output!(Sha256Hash, Sha256, 32);
57impl_sha2_fixed_output!(Sha384Hash, Sha384, 48);
58impl_sha2_fixed_output!(Sha512Hash, Sha512, 64);
59impl_sha2_fixed_output!(Sha512_224Hash, Sha512_224, 28);
60impl_sha2_fixed_output!(Sha512_256Hash, Sha512_256, 32);