libcrux_traits/digest/
slice.rs1use super::arrayref;
5
6pub trait Hash {
8 fn hash(digest: &mut [u8], payload: &[u8]) -> Result<usize, HashError>;
10}
11
12pub trait DigestIncremental: super::DigestIncrementalBase {
14 fn finish(state: &mut Self::IncrementalState, digest: &mut [u8]) -> Result<usize, FinishError>;
18}
19
20#[derive(Debug, PartialEq)]
22pub enum FinishError {
23 InvalidDigestLength,
25 Unknown,
27}
28
29impl core::fmt::Display for FinishError {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 let text = match self {
32 FinishError::InvalidDigestLength => {
33 "the length of the provided digest buffer is invalid"
34 }
35 FinishError::Unknown => "indicates an unknown error",
36 };
37
38 f.write_str(text)
39 }
40}
41
42#[derive(Debug, PartialEq)]
44pub enum HashError {
45 InvalidDigestLength,
47 InvalidPayloadLength,
49 Unknown,
51}
52
53impl core::fmt::Display for HashError {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55 let text = match self {
56 HashError::InvalidDigestLength => "the length of the provided digest buffer is invalid",
57 HashError::InvalidPayloadLength => "the length of the provided payload is invalid",
58 HashError::Unknown => "indicates an unknown error",
59 };
60
61 f.write_str(text)
62 }
63}
64
65#[cfg(feature = "error-in-core")]
66mod error_in_core {
67
68 impl core::error::Error for super::HashError {}
69 impl core::error::Error for super::FinishError {}
70}
71
72impl From<arrayref::HashError> for HashError {
73 fn from(e: arrayref::HashError) -> Self {
74 match e {
75 arrayref::HashError::InvalidPayloadLength => Self::InvalidPayloadLength,
76 arrayref::HashError::Unknown => Self::Unknown,
77 }
78 }
79}
80
81#[macro_export]
82macro_rules! impl_hash_trait {
84 ($type:ty => $len:expr) => {
85 impl $crate::digest::slice::Hash for $type {
86 fn hash(
87 digest: &mut [u8],
88 payload: &[u8],
89 ) -> Result<usize, $crate::digest::slice::HashError> {
90 let digest: &mut [u8; $len] = digest
91 .try_into()
92 .map_err(|_| $crate::digest::slice::HashError::InvalidDigestLength)?;
93 <Self as $crate::digest::arrayref::Hash<$len>>::hash(digest, payload)
94 .map(|_| $len)
95 .map_err($crate::digest::slice::HashError::from)
96 }
97 }
98 };
99}
100
101#[macro_export]
102macro_rules! impl_digest_incremental_trait {
104 ($type:ty => $incremental_state:ty, $len:expr) => {
105 impl $crate::digest::slice::DigestIncremental for $type {
106 fn finish(
107 state: &mut Self::IncrementalState,
108 digest: &mut [u8],
109 ) -> Result<usize, $crate::digest::slice::FinishError> {
110 let digest: &mut [u8; $len] = digest
111 .try_into()
112 .map_err(|_| $crate::digest::slice::FinishError::InvalidDigestLength)?;
113 <Self as $crate::digest::arrayref::DigestIncremental<$len>>::finish(state, digest);
114
115 Ok($len)
116 }
117 }
118 };
119}
120
121pub use impl_digest_incremental_trait;
122pub use impl_hash_trait;