Skip to content

Commit 4f53f96

Browse files
committed
digest: add FixedOutputDirty trait + finalize_into*
Adds a `FixedOutputDirty` trait which writes the digest output to a provided byte array, but does not reset the internal state. This is intended for implementations to use in order to ensure that they are not reset in the event the instance is consumed. Also adds a set of `finalize_into` and `finalize_into_reset` methods to `FixedOutput` whhich also write their input into a provided byte array, and changes the existing `finalize_fixed` (and newly added `finalize_fixed_reset`) methods to have a default implementation which returns a byte array allocated on the stack. Finally, adds a blanket impl of `FixedOutput` for `FixedOutputDirty` + `Reset` types which handles safely invoking the underlying implementation by either consuming the instance (avoiding a reset) or borrowing the hasher, obtaining the output, and resetting.
1 parent e312a03 commit 4f53f96

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

digest/src/dyn_digest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl<D: Update + FixedOutput + Reset + Clone + 'static> DynDigest for D {
3434
}
3535

3636
fn finalize_reset(&mut self) -> Box<[u8]> {
37-
let res = self.clone().finalize_fixed().to_vec().into_boxed_slice();
37+
let res = self.finalize_fixed_reset().to_vec().into_boxed_slice();
3838
Reset::reset(self);
3939
res
4040
}

digest/src/lib.rs

+53-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,59 @@ pub trait FixedOutput {
7979
/// Output size for fixed output digest
8080
type OutputSize: ArrayLength<u8>;
8181

82-
/// Retrieve result and consume hasher instance.
83-
fn finalize_fixed(self) -> GenericArray<u8, Self::OutputSize>;
82+
/// Write result into provided array and consume the hasher instance.
83+
fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>);
84+
85+
/// Write result into provided array and reset the hasher instance.
86+
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
87+
88+
/// Retrieve result and consume the hasher instance.
89+
#[inline]
90+
fn finalize_fixed(self) -> GenericArray<u8, Self::OutputSize>
91+
where
92+
Self: Sized,
93+
{
94+
let mut out = Default::default();
95+
self.finalize_into(&mut out);
96+
out
97+
}
98+
99+
/// Retrieve result and reset the hasher instance.
100+
#[inline]
101+
fn finalize_fixed_reset(&mut self) -> GenericArray<u8, Self::OutputSize> {
102+
let mut out = Default::default();
103+
self.finalize_into_reset(&mut out);
104+
out
105+
}
106+
}
107+
108+
/// Trait for fixed-output digest implementations to use to retrieve the
109+
/// hash output.
110+
pub trait FixedOutputDirty {
111+
/// Output size for fixed output digest
112+
type OutputSize: ArrayLength<u8>;
113+
114+
/// Retrieve result into provided buffer and leave hasher in a dirty state.
115+
/// Usage of this method in user code is discouraged, prefer `finalize_fixed`
116+
/// or `finalize_fixed_reset`.
117+
///
118+
/// Implementations should panic if this is called twice without resetting.
119+
fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
120+
}
121+
122+
impl<D: FixedOutputDirty + Reset> FixedOutput for D {
123+
type OutputSize = D::OutputSize;
124+
125+
#[inline]
126+
fn finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
127+
self.finalize_into_dirty(out);
128+
}
129+
130+
#[inline]
131+
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
132+
self.finalize_into_dirty(out);
133+
self.reset();
134+
}
84135
}
85136

86137
/// Trait for returning digest result with the variable size

0 commit comments

Comments
 (0)