1 //! Fixed-size output digest support
2 
3 use crate::Reset;
4 use generic_array::{ArrayLength, GenericArray};
5 
6 /// Trait for returning digest result with the fixed size
7 pub trait FixedOutput {
8     /// Output size for fixed output digest
9     type OutputSize: ArrayLength<u8>;
10 
11     /// Write result into provided array and consume the hasher instance.
finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>)12     fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>);
13 
14     /// Write result into provided array and reset the hasher instance.
finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>)15     fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
16 
17     /// Retrieve result and consume the hasher instance.
18     #[inline]
finalize_fixed(self) -> GenericArray<u8, Self::OutputSize> where Self: Sized,19     fn finalize_fixed(self) -> GenericArray<u8, Self::OutputSize>
20     where
21         Self: Sized,
22     {
23         let mut out = Default::default();
24         self.finalize_into(&mut out);
25         out
26     }
27 
28     /// Retrieve result and reset the hasher instance.
29     #[inline]
finalize_fixed_reset(&mut self) -> GenericArray<u8, Self::OutputSize>30     fn finalize_fixed_reset(&mut self) -> GenericArray<u8, Self::OutputSize> {
31         let mut out = Default::default();
32         self.finalize_into_reset(&mut out);
33         out
34     }
35 }
36 
37 /// Trait for fixed-output digest implementations to use to retrieve the
38 /// hash output.
39 ///
40 /// Usage of this trait in user code is discouraged. Instead use the
41 /// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`]
42 /// methods.
43 ///
44 /// Types which impl this trait along with [`Reset`] will receive a blanket
45 /// impl of [`FixedOutput`].
46 pub trait FixedOutputDirty {
47     /// Output size for fixed output digest
48     type OutputSize: ArrayLength<u8>;
49 
50     /// Retrieve result into provided buffer and leave hasher in a dirty state.
51     ///
52     /// This method is expected to only be called once unless
53     /// [`Reset::reset`] is called, after which point it can be
54     /// called again and reset again (and so on).
finalize_into_dirty(&mut self, out: &mut GenericArray<u8, Self::OutputSize>)55     fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
56 }
57 
58 impl<D: FixedOutputDirty + Reset> FixedOutput for D {
59     type OutputSize = D::OutputSize;
60 
61     #[inline]
finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>)62     fn finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
63         self.finalize_into_dirty(out);
64     }
65 
66     #[inline]
finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>)67     fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
68         self.finalize_into_dirty(out);
69         self.reset();
70     }
71 }
72