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