diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index c836ab447..4515c290f 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -34,7 +34,7 @@ impl DynDigest for D { } fn finalize_reset(&mut self) -> Box<[u8]> { - let res = self.clone().finalize_fixed().to_vec().into_boxed_slice(); + let res = self.finalize_fixed_reset().to_vec().into_boxed_slice(); Reset::reset(self); res } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 79bef801d..72a7e00a9 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -79,8 +79,64 @@ pub trait FixedOutput { /// Output size for fixed output digest type OutputSize: ArrayLength; - /// Retrieve result and consume hasher instance. - fn finalize_fixed(self) -> GenericArray; + /// Write result into provided array and consume the hasher instance. + fn finalize_into(self, out: &mut GenericArray); + + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> GenericArray + where + Self: Sized, + { + let mut out = Default::default(); + self.finalize_into(&mut out); + out + } + + /// Retrieve result and reset the hasher instance. + #[inline] + fn finalize_fixed_reset(&mut self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } +} + +/// Trait for fixed-output digest implementations to use to retrieve the +/// hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`] +/// methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`FixedOutput`]. +pub trait FixedOutputDirty { + /// Output size for fixed output digest + type OutputSize: ArrayLength; + + /// Retrieve result into provided buffer and leave hasher in a dirty state. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_into_dirty(&mut self, out: &mut GenericArray); +} + +impl FixedOutput for D { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + self.reset(); + } } /// Trait for returning digest result with the variable size