use crate::{is, whilst};
#[doc = crate::_tags!(crypto hash)]
#[doc = crate::_doc_meta!{location("data/codec/crypto")}]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[must_use]
pub struct Digest<const N: usize>(pub [u8; N]);
#[rustfmt::skip]
impl<const N: usize> Digest<N> {
pub const LEN: usize = N;
pub const fn new(bytes: [u8; N]) -> Self { Self(bytes) }
#[must_use] pub const fn as_array(&self) -> &[u8; N] { &self.0 }
#[must_use] pub const fn into_array(self) -> [u8; N] { self.0 }
#[must_use] pub const fn as_slice(&self) -> &[u8; N] { &self.0 }
#[must_use] pub const fn len(&self) -> usize { N }
#[must_use] pub const fn is_empty(&self) -> bool { N == 0 }
#[must_use]
pub const fn eq(&self, other: &Self) -> bool {
let mut diff = 0u8;
whilst! { i in 0..N; { diff |= self.0[i] ^ other.0[i]; }}
diff == 0
}
#[must_use]
pub const fn eq_slice(&self, bytes: &[u8]) -> bool {
is! { bytes.len() != N, return false }
let mut diff = 0u8;
whilst! { i in 0..N; { diff |= self.0[i] ^ bytes[i]; }}
diff == 0
}
}
#[rustfmt::skip]
mod impls_traits {
use crate::{ConstInit, Digest};
impl<const N: usize> ConstInit for Digest<N> {
const INIT: Self = Self([0; N]);
}
impl<const N: usize> From<[u8; N]> for Digest<N> {
fn from(bytes: [u8; N]) -> Self { Self(bytes) }
}
impl<const N: usize> From<Digest<N>> for [u8; N] {
fn from(digest: Digest<N>) -> Self { digest.0 }
}
impl<const N: usize> AsRef<[u8]> for Digest<N> {
fn as_ref(&self) -> &[u8] { &self.0 }
}
}
#[doc = crate::_tags!(crypto hash construction)]
#[doc = crate::_doc_meta!{location("data/codec/crypto")}]
#[doc(hidden)]
#[macro_export]
macro_rules! digest· {
( $(#[$attr:meta])* $vis:vis struct $name:ident: Md5 $(;)?) => {
$crate::__crypto_impl_md5! { $(#[$attr])* $vis struct $name }
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha1 $(;)?) => {
$crate::__crypto_impl_sha1! { $(#[$attr])* $vis struct $name }
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha256 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u32, doc: "SHA-256",
digest_bits: 256, digest_len: 32, output_words: 8, output_tail_bytes: 0,
initial_state: [
0x6A09_E667, 0xBB67_AE85, 0x3C6E_F372, 0xA54F_F53A,
0x510E_527F, 0x9B05_688C, 0x1F83_D9AB, 0x5BE0_CD19]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha512 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u64, doc: "SHA-512",
digest_bits: 512, digest_len: 64, output_words: 8, output_tail_bytes: 0,
initial_state: [
0x6A09_E667_F3BC_C908, 0xBB67_AE85_84CA_A73B,
0x3C6E_F372_FE94_F82B, 0xA54F_F53A_5F1D_36F1,
0x510E_527F_ADE6_82D1, 0x9B05_688C_2B3E_6C1F,
0x1F83_D9AB_FB41_BD6B, 0x5BE0_CD19_137E_2179]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha224 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u32, doc: "SHA-224",
digest_bits: 224, digest_len: 28, output_words: 7, output_tail_bytes: 0,
initial_state: [
0xC105_9ED8, 0x367C_D507, 0x3070_DD17, 0xF70E_5939,
0xFFC0_0B31, 0x6858_1511, 0x64F9_8FA7, 0xBEFA_4FA4]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha384 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u64, doc: "SHA-384",
digest_bits: 384, digest_len: 48, output_words: 6, output_tail_bytes: 0,
initial_state: [
0xCBBB_9D5D_C105_9ED8, 0x629A_292A_367C_D507,
0x9159_015A_3070_DD17, 0x152F_ECD8_F70E_5939,
0x6733_2667_FFC0_0B31, 0x8EB4_4A87_6858_1511,
0xDB0C_2E0D_64F9_8FA7, 0x47B5_481D_BEFA_4FA4]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha512_224 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u64, doc: "SHA-512/224",
digest_bits: 224, digest_len: 28, output_words: 3, output_tail_bytes: 4,
initial_state: [
0x8C3D_37C8_1954_4DA2, 0x73E1_9966_89DC_D4D6,
0x1DFA_B7AE_32FF_9C82, 0x679D_D514_582F_9FCF,
0x0F6D_2B69_7BD4_4DA8, 0x77E3_6F73_04C4_8942,
0x3F9D_85A8_6A1D_36C8, 0x1112_E6AD_91D6_92A1]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: Sha512_256 $(;)?) => {
$crate::__crypto_impl_sha2! { $(#[$attr])* $vis struct $name; word: u64, doc: "SHA-512/256",
digest_bits: 256, digest_len: 32, output_words: 4, output_tail_bytes: 0,
initial_state: [
0x2231_2194_FC2B_F72C, 0x9F55_5FA3_C84C_64C2,
0x2393_B86B_6F53_B151, 0x9638_7719_5940_EABD,
0x9628_3EE2_A88E_FFE3, 0xBE5E_1E25_5386_3992,
0x2B01_99FC_2C85_B8AA, 0x0EB7_2DDC_81C5_2CA2]
}
};
($(#[$attr:meta])* $vis:vis struct $name:ident: $hash:ident $(;)?) => {
compile_error! { concat!("Hash function not supported: ", stringify!($hash)) }
};
}
#[doc(inline)]
pub use digest· as digest;