Skip to content

Commit a2f119e

Browse files
committed
digest: replace Reset trait with methods; add *into* methods
Closes RustCrypto/hashes#86 Replaces the `Reset` trait with a set of `_reset` methods on all of the various traits, and uses these as the default impl for the methods which consume hashers. Also adds a set of methods to `FixedOutput` (`finalize_fixed_into*`) which eliminate copies by accepting an existing buffer as an argument.
1 parent e312a03 commit a2f119e

File tree

4 files changed

+59
-41
lines changed

4 files changed

+59
-41
lines changed

digest/src/dev.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
pub use blobby;
44

5-
use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader};
5+
use super::{ExtendableOutput, Update, VariableOutput, XofReader};
66
use core::fmt::Debug;
77

88
/// Define test
@@ -51,7 +51,7 @@ mod foo {
5151
}
5252

5353
// Test if reset works correctly
54-
hasher2.reset();
54+
hasher2.finalize_reset();
5555
hasher2.update(input);
5656
if hasher2.finalize().as_slice() != output {
5757
return Some("whole message after reset");
@@ -101,7 +101,7 @@ pub use self::foo::{digest_test, one_million_a};
101101
/// XOF test
102102
pub fn xof_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
103103
where
104-
D: Update + ExtendableOutput + Default + Debug + Reset + Clone,
104+
D: Update + ExtendableOutput + Default + Debug + Clone,
105105
{
106106
let mut hasher = D::default();
107107
let mut buf = [0u8; 1024];
@@ -119,7 +119,7 @@ where
119119
}
120120

121121
// Test if hasher resets correctly
122-
hasher2.reset();
122+
hasher2.finalize_xof_reset();
123123
hasher2.update(input);
124124

125125
{
@@ -168,7 +168,7 @@ where
168168
/// Variable-output digest test
169169
pub fn variable_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str>
170170
where
171-
D: Update + VariableOutput + Reset + Debug + Clone,
171+
D: Update + VariableOutput + Debug + Clone,
172172
{
173173
let mut hasher = D::new(output.len()).unwrap();
174174
let mut buf = [0u8; 128];
@@ -182,7 +182,7 @@ where
182182
}
183183

184184
// Test if reset works correctly
185-
hasher2.reset();
185+
hasher2.finalize_variable_reset(|_| ());
186186
hasher2.update(input);
187187
hasher2.finalize_variable(|res| buf.copy_from_slice(res));
188188
if buf != output {

digest/src/digest.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{FixedOutput, Reset, Update};
1+
use super::{FixedOutput, Update};
22
use generic_array::typenum::Unsigned;
33
use generic_array::{ArrayLength, GenericArray};
44

@@ -32,9 +32,6 @@ pub trait Digest {
3232
/// re-creation.
3333
fn finalize_reset(&mut self) -> Output<Self>;
3434

35-
/// Reset hasher instance to its initial state.
36-
fn reset(&mut self);
37-
3835
/// Get output size of the hasher
3936
fn output_size() -> usize;
4037

@@ -49,7 +46,7 @@ pub trait Digest {
4946
fn digest(data: &[u8]) -> Output<Self>;
5047
}
5148

52-
impl<D: Update + FixedOutput + Reset + Clone + Default> Digest for D {
49+
impl<D: Update + FixedOutput + Clone + Default> Digest for D {
5350
type OutputSize = <Self as FixedOutput>::OutputSize;
5451

5552
fn new() -> Self {
@@ -72,13 +69,7 @@ impl<D: Update + FixedOutput + Reset + Clone + Default> Digest for D {
7269
}
7370

7471
fn finalize_reset(&mut self) -> Output<Self> {
75-
let res = self.clone().finalize_fixed();
76-
self.reset();
77-
res
78-
}
79-
80-
fn reset(&mut self) {
81-
<Self as Reset>::reset(self)
72+
self.finalize_fixed_reset()
8273
}
8374

8475
fn output_size() -> usize {

digest/src/dyn_digest.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![cfg(feature = "alloc")]
22
use alloc::boxed::Box;
33

4-
use super::{FixedOutput, Reset, Update};
4+
use super::{FixedOutput, Update};
55
use generic_array::typenum::Unsigned;
66

77
/// The `DynDigest` trait is a modification of `Digest` trait suitable
@@ -18,33 +18,25 @@ pub trait DynDigest {
1818
/// Retrieve result and consume boxed hasher instance
1919
fn finalize(self: Box<Self>) -> Box<[u8]>;
2020

21-
/// Reset hasher instance to its initial state.
22-
fn reset(&mut self);
23-
2421
/// Get output size of the hasher
2522
fn output_size(&self) -> usize;
2623

2724
/// Clone hasher state into a boxed trait object
2825
fn box_clone(&self) -> Box<dyn DynDigest>;
2926
}
3027

31-
impl<D: Update + FixedOutput + Reset + Clone + 'static> DynDigest for D {
28+
impl<D: Update + FixedOutput + Clone + 'static> DynDigest for D {
3229
fn update(&mut self, data: &[u8]) {
3330
Update::update(self, data);
3431
}
3532

33+
#[inline]
3634
fn finalize_reset(&mut self) -> Box<[u8]> {
37-
let res = self.clone().finalize_fixed().to_vec().into_boxed_slice();
38-
Reset::reset(self);
39-
res
40-
}
41-
42-
fn finalize(self: Box<Self>) -> Box<[u8]> {
43-
self.finalize_fixed().to_vec().into_boxed_slice()
35+
self.finalize_fixed_reset().to_vec().into_boxed_slice()
4436
}
4537

46-
fn reset(&mut self) {
47-
Reset::reset(self);
38+
fn finalize(mut self: Box<Self>) -> Box<[u8]> {
39+
self.finalize_reset()
4840
}
4941

5042
fn output_size(&self) -> usize {

digest/src/lib.rs

+44-9
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,33 @@ pub trait FixedOutput {
8080
type OutputSize: ArrayLength<u8>;
8181

8282
/// Retrieve result and consume hasher instance.
83-
fn finalize_fixed(self) -> GenericArray<u8, Self::OutputSize>;
83+
#[inline]
84+
fn finalize_fixed(mut self) -> GenericArray<u8, Self::OutputSize>
85+
where
86+
Self: Sized,
87+
{
88+
self.finalize_fixed_reset()
89+
}
90+
91+
/// Retrieve result and reset hasher instance.
92+
#[inline]
93+
fn finalize_fixed_reset(&mut self) -> GenericArray<u8, Self::OutputSize> {
94+
let mut buf = Default::default();
95+
self.finalize_fixed_into_reset(&mut buf);
96+
buf
97+
}
98+
99+
/// Retrieve result into provided buffer and consume hasher instance.
100+
#[inline]
101+
fn finalize_fixed_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>)
102+
where
103+
Self: Sized,
104+
{
105+
self.finalize_fixed_into_reset(out);
106+
}
107+
108+
/// Retrieve result and provided buffer and consume hasher instance.
109+
fn finalize_fixed_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
84110
}
85111

86112
/// Trait for returning digest result with the variable size
@@ -99,7 +125,16 @@ pub trait VariableOutput: core::marker::Sized {
99125
///
100126
/// Closure is guaranteed to be called, length of the buffer passed to it
101127
/// will be equal to `output_size`.
102-
fn finalize_variable<F: FnOnce(&[u8])>(self, f: F);
128+
#[inline]
129+
fn finalize_variable(mut self, f: impl FnOnce(&[u8])) {
130+
self.finalize_variable_reset(f);
131+
}
132+
133+
/// Retrieve result via closure and reset hasher.
134+
///
135+
/// Closure is guaranteed to be called, length of the buffer passed to it
136+
/// will be equal to `output_size`.
137+
fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8]));
103138

104139
/// Retrieve result into vector and consume hasher.
105140
#[cfg(feature = "alloc")]
@@ -135,7 +170,13 @@ pub trait ExtendableOutput: core::marker::Sized {
135170
type Reader: XofReader;
136171

137172
/// Retrieve XOF reader and consume hasher instance.
138-
fn finalize_xof(self) -> Self::Reader;
173+
#[inline]
174+
fn finalize_xof(mut self) -> Self::Reader {
175+
self.finalize_xof_reset()
176+
}
177+
178+
/// Retrieve XOF reader and reset hasher instance.
179+
fn finalize_xof_reset(&mut self) -> Self::Reader;
139180

140181
/// Retrieve result into vector of specified length.
141182
#[cfg(feature = "alloc")]
@@ -147,12 +188,6 @@ pub trait ExtendableOutput: core::marker::Sized {
147188
}
148189
}
149190

150-
/// Trait for resetting hash instances
151-
pub trait Reset {
152-
/// Reset hasher instance to its initial state and return current state.
153-
fn reset(&mut self);
154-
}
155-
156191
#[macro_export]
157192
/// Implements `std::io::Write` trait for implementer of [`Update`]
158193
macro_rules! impl_write {

0 commit comments

Comments
 (0)