/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 {} |