Coverage Report

Created: 2026-09-01 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.11.3/src/digest.rs
Line
Count
Source
1
use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update};
2
use common::{Output, OutputSizeUser, typenum::Unsigned};
3
4
#[cfg(feature = "alloc")]
5
use alloc::boxed::Box;
6
#[cfg(feature = "oid")]
7
use const_oid::DynAssociatedOid;
8
9
/// Marker trait for cryptographic hash functions.
10
pub trait HashMarker {}
11
12
/// Convenience wrapper trait covering functionality of cryptographic hash
13
/// functions with fixed output size.
14
///
15
/// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and
16
/// [`HashMarker`] traits and provides additional convenience methods.
17
pub trait Digest: OutputSizeUser {
18
    /// Create new hasher instance.
19
    fn new() -> Self;
20
21
    /// Create new hasher instance which has processed the provided data.
22
    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self;
23
24
    /// Process data, updating the internal state.
25
    fn update(&mut self, data: impl AsRef<[u8]>);
26
27
    /// Process input data in a chained manner.
28
    #[must_use]
29
    fn chain_update(self, data: impl AsRef<[u8]>) -> Self;
30
31
    /// Retrieve result and consume hasher instance.
32
    fn finalize(self) -> Output<Self>;
33
34
    /// Write result into provided array and consume the hasher instance.
35
    fn finalize_into(self, out: &mut Output<Self>);
36
37
    /// Retrieve result and reset hasher instance.
38
    fn finalize_reset(&mut self) -> Output<Self>
39
    where
40
        Self: FixedOutputReset;
41
42
    /// Write result into provided array and reset the hasher instance.
43
    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
44
    where
45
        Self: FixedOutputReset;
46
47
    /// Reset hasher instance to its initial state.
48
    fn reset(&mut self)
49
    where
50
        Self: Reset;
51
52
    /// Get output size of the hasher
53
    fn output_size() -> usize;
54
55
    /// Compute hash of `data`.
56
    fn digest(data: impl AsRef<[u8]>) -> Output<Self>;
57
}
58
59
impl<D: FixedOutput + Default + Update + HashMarker> Digest for D {
60
    #[inline]
61
    fn new() -> Self {
62
        Self::default()
63
    }
64
65
    #[inline]
66
    fn new_with_prefix(data: impl AsRef<[u8]>) -> Self
67
    where
68
        Self: Default + Sized,
69
    {
70
        let mut h = Self::default();
71
        h.update(data.as_ref());
72
        h
73
    }
74
75
    #[inline]
76
0
    fn update(&mut self, data: impl AsRef<[u8]>) {
77
0
        Update::update(self, data.as_ref());
78
0
    }
79
80
    #[inline]
81
    fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self {
82
        Update::update(&mut self, data.as_ref());
83
        self
84
    }
85
86
    #[inline]
87
0
    fn finalize(self) -> Output<Self> {
88
0
        FixedOutput::finalize_fixed(self)
89
0
    }
90
91
    #[inline]
92
    fn finalize_into(self, out: &mut Output<Self>) {
93
        FixedOutput::finalize_into(self, out);
94
    }
95
96
    #[inline]
97
    fn finalize_reset(&mut self) -> Output<Self>
98
    where
99
        Self: FixedOutputReset,
100
    {
101
        FixedOutputReset::finalize_fixed_reset(self)
102
    }
103
104
    #[inline]
105
    fn finalize_into_reset(&mut self, out: &mut Output<Self>)
106
    where
107
        Self: FixedOutputReset,
108
    {
109
        FixedOutputReset::finalize_into_reset(self, out);
110
    }
111
112
    #[inline]
113
    fn reset(&mut self)
114
    where
115
        Self: Reset,
116
    {
117
        Reset::reset(self);
118
    }
119
120
    #[inline]
121
    fn output_size() -> usize {
122
        Self::OutputSize::to_usize()
123
    }
124
125
    #[inline]
126
    fn digest(data: impl AsRef<[u8]>) -> Output<Self> {
127
        let mut hasher = Self::default();
128
        hasher.update(data.as_ref());
129
        hasher.finalize()
130
    }
131
}
132
133
/// Modification of the [`Digest`] trait suitable for trait objects.
134
pub trait DynDigest {
135
    /// Digest input data.
136
    ///
137
    /// This method can be called repeatedly for use with streaming messages.
138
    fn update(&mut self, data: &[u8]);
139
140
    /// Retrieve result and reset hasher instance
141
    #[cfg(feature = "alloc")]
142
    fn finalize_reset(&mut self) -> Box<[u8]> {
143
        let mut result = vec![0; self.output_size()];
144
        self.finalize_into_reset(&mut result).unwrap();
145
        result.into_boxed_slice()
146
    }
147
148
    /// Retrieve result and consume boxed hasher instance
149
    #[cfg(feature = "alloc")]
150
    #[allow(clippy::boxed_local)]
151
    #[must_use]
152
    fn finalize(mut self: Box<Self>) -> Box<[u8]> {
153
        let mut result = vec![0; self.output_size()];
154
        self.finalize_into_reset(&mut result).unwrap();
155
        result.into_boxed_slice()
156
    }
157
158
    /// Write result into provided array and consume the hasher instance.
159
    ///
160
    /// # Errors
161
    /// If buffer length is not equal to `output_size`.
162
    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize>;
163
164
    /// Write result into provided array and reset the hasher instance.
165
    ///
166
    /// # Errors
167
    /// If buffer length is not equal to `output_size`.
168
    fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>;
169
170
    /// Reset hasher instance to its initial state.
171
    fn reset(&mut self);
172
173
    /// Get output size of the hasher
174
    fn output_size(&self) -> usize;
175
176
    /// Clone hasher state into a boxed trait object
177
    #[cfg(feature = "alloc")]
178
    fn box_clone(&self) -> Box<dyn DynDigest>;
179
}
180
181
impl<D: Update + FixedOutputReset + Reset + Clone + 'static> DynDigest for D {
182
    fn update(&mut self, data: &[u8]) {
183
        Update::update(self, data);
184
    }
185
186
    #[cfg(feature = "alloc")]
187
    fn finalize_reset(&mut self) -> Box<[u8]> {
188
        FixedOutputReset::finalize_fixed_reset(self)
189
            .to_vec()
190
            .into_boxed_slice()
191
    }
192
193
    #[cfg(feature = "alloc")]
194
    fn finalize(self: Box<Self>) -> Box<[u8]> {
195
        FixedOutput::finalize_fixed(*self)
196
            .to_vec()
197
            .into_boxed_slice()
198
    }
199
200
    fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
201
        buf.try_into()
202
            .map_err(|_| InvalidBufferSize)
203
            .map(|buf| FixedOutput::finalize_into(self, buf))
204
    }
205
206
    fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> {
207
        let buf = <&mut Output<Self>>::try_from(buf).map_err(|_| InvalidBufferSize)?;
208
        FixedOutputReset::finalize_into_reset(self, buf);
209
        Ok(())
210
    }
211
212
    fn reset(&mut self) {
213
        Reset::reset(self);
214
    }
215
216
    fn output_size(&self) -> usize {
217
        <Self as OutputSizeUser>::OutputSize::to_usize()
218
    }
219
220
    #[cfg(feature = "alloc")]
221
    fn box_clone(&self) -> Box<dyn DynDigest> {
222
        Box::new(self.clone())
223
    }
224
}
225
226
#[cfg(feature = "alloc")]
227
impl Clone for Box<dyn DynDigest> {
228
    fn clone(&self) -> Self {
229
        self.box_clone()
230
    }
231
}
232
233
/// Convenience wrapper trait around [DynDigest] and [DynAssociatedOid].
234
#[cfg(feature = "oid")]
235
pub trait DynDigestWithOid: DynDigest + DynAssociatedOid {}
236
237
#[cfg(feature = "oid")]
238
impl<T: DynDigest + DynAssociatedOid> DynDigestWithOid for T {}