@@ -140,7 +140,7 @@ impl<D: FixedOutputDirty + Reset> FixedOutput for D {
140
140
}
141
141
142
142
/// Trait for returning digest result with the variable size
143
- pub trait VariableOutput : core :: marker :: Sized {
143
+ pub trait VariableOutput : Sized {
144
144
/// Create new hasher instance with the given output size.
145
145
///
146
146
/// It will return `Err(InvalidOutputSize)` in case if hasher can not return
@@ -155,7 +155,13 @@ pub trait VariableOutput: core::marker::Sized {
155
155
///
156
156
/// Closure is guaranteed to be called, length of the buffer passed to it
157
157
/// will be equal to `output_size`.
158
- fn finalize_variable < F : FnOnce ( & [ u8 ] ) > ( self , f : F ) ;
158
+ fn finalize_variable ( self , f : impl FnOnce ( & [ u8 ] ) ) ;
159
+
160
+ /// Retrieve result via closure and reset the hasher state.
161
+ ///
162
+ /// Closure is guaranteed to be called, length of the buffer passed to it
163
+ /// will be equal to `output_size`.
164
+ fn finalize_variable_reset ( & mut self , f : impl FnOnce ( & [ u8 ] ) ) ;
159
165
160
166
/// Retrieve result into a boxed slice and consume hasher.
161
167
///
@@ -169,6 +175,66 @@ pub trait VariableOutput: core::marker::Sized {
169
175
self . finalize_variable ( |res| buf. copy_from_slice ( res) ) ;
170
176
buf
171
177
}
178
+
179
+ /// Retrieve result into a boxed slice and reset hasher state.
180
+ ///
181
+ /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
182
+ /// they have size of 2 and 3 words respectively.
183
+ #[ cfg( feature = "alloc" ) ]
184
+ #[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
185
+ fn finalize_boxed_reset ( & mut self ) -> Box < [ u8 ] > {
186
+ let n = self . output_size ( ) ;
187
+ let mut buf = vec ! [ 0u8 ; n] . into_boxed_slice ( ) ;
188
+ self . finalize_variable_reset ( |res| buf. copy_from_slice ( res) ) ;
189
+ buf
190
+ }
191
+ }
192
+
193
+ /// Trait for variable-sized output digest implementations to use to retrieve
194
+ /// the hash output.
195
+ ///
196
+ /// Usage of this trait in user code is discouraged. Instead use the
197
+ /// [`VariableOutput::finalize_variable`] or
198
+ /// [`VariableOutput::finalize_variable_reset`] methods.
199
+ ///
200
+ /// Types which impl this trait along with [`Reset`] will receive a blanket
201
+ /// impl of [`VariableOutput`].
202
+ pub trait VariableOutputDirty : Sized {
203
+ /// Create new hasher instance with the given output size.
204
+ ///
205
+ /// It will return `Err(InvalidOutputSize)` in case if hasher can not return
206
+ /// specified output size. It will always return an error if output size
207
+ /// equals to zero.
208
+ fn new ( output_size : usize ) -> Result < Self , InvalidOutputSize > ;
209
+
210
+ /// Get output size of the hasher instance provided to the `new` method
211
+ fn output_size ( & self ) -> usize ;
212
+
213
+ /// Retrieve result into provided buffer and leave hasher in a dirty state.
214
+ ///
215
+ /// Implementations should panic if this is called twice without resetting.
216
+ fn finalize_variable_dirty ( & mut self , f : impl FnOnce ( & [ u8 ] ) ) ;
217
+ }
218
+
219
+ impl < D : VariableOutputDirty + Reset > VariableOutput for D {
220
+ fn new ( output_size : usize ) -> Result < Self , InvalidOutputSize > {
221
+ <Self as VariableOutputDirty >:: new ( output_size)
222
+ }
223
+
224
+ fn output_size ( & self ) -> usize {
225
+ <Self as VariableOutputDirty >:: output_size ( self )
226
+ }
227
+
228
+ #[ inline]
229
+ fn finalize_variable ( mut self , f : impl FnOnce ( & [ u8 ] ) ) {
230
+ self . finalize_variable_dirty ( f) ;
231
+ }
232
+
233
+ #[ inline]
234
+ fn finalize_variable_reset ( & mut self , f : impl FnOnce ( & [ u8 ] ) ) {
235
+ self . finalize_variable_dirty ( f) ;
236
+ self . reset ( ) ;
237
+ }
172
238
}
173
239
174
240
/// Trait for describing readers which are used to extract extendable output
@@ -193,14 +259,18 @@ pub trait XofReader {
193
259
}
194
260
195
261
/// Trait which describes extendable-output functions (XOF).
196
- pub trait ExtendableOutput : core :: marker :: Sized {
262
+ pub trait ExtendableOutput : Sized {
197
263
/// Reader
198
264
type Reader : XofReader ;
199
265
200
266
/// Retrieve XOF reader and consume hasher instance.
201
267
fn finalize_xof ( self ) -> Self :: Reader ;
202
268
203
- /// Retrieve result into a boxed slice of the specified size.
269
+ /// Retrieve XOF reader and reset hasher instance state.
270
+ fn finalize_xof_reset ( & mut self ) -> Self :: Reader ;
271
+
272
+ /// Retrieve result into a boxed slice of the specified size and consume
273
+ /// the hasher.
204
274
///
205
275
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
206
276
/// they have size of 2 and 3 words respectively.
@@ -211,6 +281,54 @@ pub trait ExtendableOutput: core::marker::Sized {
211
281
self . finalize_xof ( ) . read ( & mut buf) ;
212
282
buf
213
283
}
284
+
285
+ /// Retrieve result into a boxed slice of the specified size and reset
286
+ /// the hasher's state.
287
+ ///
288
+ /// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
289
+ /// they have size of 2 and 3 words respectively.
290
+ #[ cfg( feature = "alloc" ) ]
291
+ #[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
292
+ fn finalize_boxed_reset ( & mut self , n : usize ) -> Box < [ u8 ] > {
293
+ let mut buf = vec ! [ 0u8 ; n] . into_boxed_slice ( ) ;
294
+ self . finalize_xof_reset ( ) . read ( & mut buf) ;
295
+ buf
296
+ }
297
+ }
298
+
299
+ /// Trait for extendable-output function (XOF) implementations to use to
300
+ /// retrieve the hash output.
301
+ ///
302
+ /// Usage of this trait in user code is discouraged. Instead use the
303
+ /// [`VariableOutput::finalize_variable`] or
304
+ /// [`VariableOutput::finalize_variable_reset`] methods.
305
+ ///
306
+ /// Types which impl this trait along with [`Reset`] will receive a blanket
307
+ /// impl of [`VariableOutput`].
308
+ pub trait ExtendableOutputDirty : Sized {
309
+ /// Reader
310
+ type Reader : XofReader ;
311
+
312
+ /// Retrieve XOF reader and consume hasher instance.
313
+ ///
314
+ /// Implementations should panic if this is called twice without resetting.
315
+ fn finalize_xof_dirty ( & mut self ) -> Self :: Reader ;
316
+ }
317
+
318
+ impl < X : ExtendableOutputDirty + Reset > ExtendableOutput for X {
319
+ type Reader = X :: Reader ;
320
+
321
+ #[ inline]
322
+ fn finalize_xof ( mut self ) -> Self :: Reader {
323
+ self . finalize_xof_dirty ( )
324
+ }
325
+
326
+ #[ inline]
327
+ fn finalize_xof_reset ( & mut self ) -> Self :: Reader {
328
+ let reader = self . finalize_xof_dirty ( ) ;
329
+ self . reset ( ) ;
330
+ reader
331
+ }
214
332
}
215
333
216
334
/// Trait for resetting hash instances
0 commit comments