Skip to content

Commit 5b4b533

Browse files
committed
digest: factor out fixed, variable, and xof modules
Each of these now defines two traits and a blanket impl, so `lib.rs` was getting rather bloated. This commit factors each of them into their own modules.
1 parent 4ce01a5 commit 5b4b533

File tree

5 files changed

+281
-262
lines changed

5 files changed

+281
-262
lines changed

digest/src/dyn_digest.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use generic_array::typenum::Unsigned;
66

77
/// The `DynDigest` trait is a modification of `Digest` trait suitable
88
/// for trait objects.
9+
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
910
pub trait DynDigest {
1011
/// Digest input data.
1112
///

digest/src/fixed.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.
12+
fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>);
13+
14+
/// Write result into provided array and reset the hasher instance.
15+
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
16+
17+
/// Retrieve result and consume the hasher instance.
18+
#[inline]
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]
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+
/// Implementations should panic if this is called twice without resetting.
53+
fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
54+
}
55+
56+
impl<D: FixedOutputDirty + Reset> FixedOutput for D {
57+
type OutputSize = D::OutputSize;
58+
59+
#[inline]
60+
fn finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
61+
self.finalize_into_dirty(out);
62+
}
63+
64+
#[inline]
65+
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
66+
self.finalize_into_dirty(out);
67+
self.reset();
68+
}
69+
}

digest/src/lib.rs

+7-262
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,21 @@ pub mod dev;
3333
mod digest;
3434
mod dyn_digest;
3535
mod errors;
36+
mod fixed;
37+
mod variable;
38+
mod xof;
3639

3740
pub use crate::digest::{Digest, Output};
3841
pub use crate::errors::InvalidOutputSize;
42+
pub use crate::fixed::{FixedOutput, FixedOutputDirty};
43+
pub use crate::variable::{VariableOutput, VariableOutputDirty};
44+
pub use crate::xof::{ExtendableOutput, ExtendableOutputDirty, XofReader};
3945
pub use generic_array::{self, typenum::consts};
4046

4147
#[cfg(feature = "alloc")]
42-
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
4348
pub use dyn_digest::DynDigest;
4449

45-
use generic_array::{ArrayLength, GenericArray};
46-
47-
#[cfg(feature = "alloc")]
48-
use alloc::boxed::Box;
50+
use generic_array::ArrayLength;
4951

5052
/// Trait for updating digest state with input data.
5153
pub trait Update {
@@ -74,263 +76,6 @@ pub trait BlockInput {
7476
type BlockSize: ArrayLength<u8>;
7577
}
7678

77-
/// Trait for returning digest result with the fixed size
78-
pub trait FixedOutput {
79-
/// Output size for fixed output digest
80-
type OutputSize: ArrayLength<u8>;
81-
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-
///
111-
/// Usage of this trait in user code is discouraged. Instead use the
112-
/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`]
113-
/// methods.
114-
///
115-
/// Types which impl this trait along with [`Reset`] will receive a blanket
116-
/// impl of [`FixedOutput`].
117-
pub trait FixedOutputDirty {
118-
/// Output size for fixed output digest
119-
type OutputSize: ArrayLength<u8>;
120-
121-
/// Retrieve result into provided buffer and leave hasher in a dirty state.
122-
///
123-
/// Implementations should panic if this is called twice without resetting.
124-
fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, Self::OutputSize>);
125-
}
126-
127-
impl<D: FixedOutputDirty + Reset> FixedOutput for D {
128-
type OutputSize = D::OutputSize;
129-
130-
#[inline]
131-
fn finalize_into(mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
132-
self.finalize_into_dirty(out);
133-
}
134-
135-
#[inline]
136-
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
137-
self.finalize_into_dirty(out);
138-
self.reset();
139-
}
140-
}
141-
142-
/// Trait for returning digest result with the variable size
143-
pub trait VariableOutput: Sized {
144-
/// Create new hasher instance with the given output size.
145-
///
146-
/// It will return `Err(InvalidOutputSize)` in case if hasher can not return
147-
/// specified output size. It will always return an error if output size
148-
/// equals to zero.
149-
fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
150-
151-
/// Get output size of the hasher instance provided to the `new` method
152-
fn output_size(&self) -> usize;
153-
154-
/// Retrieve result via closure and consume hasher.
155-
///
156-
/// Closure is guaranteed to be called, length of the buffer passed to it
157-
/// will be equal to `output_size`.
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]));
165-
166-
/// Retrieve result into a boxed slice and consume hasher.
167-
///
168-
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
169-
/// they have size of 2 and 3 words respectively.
170-
#[cfg(feature = "alloc")]
171-
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
172-
fn finalize_boxed(self) -> Box<[u8]> {
173-
let n = self.output_size();
174-
let mut buf = vec![0u8; n].into_boxed_slice();
175-
self.finalize_variable(|res| buf.copy_from_slice(res));
176-
buf
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-
}
238-
}
239-
240-
/// Trait for describing readers which are used to extract extendable output
241-
/// from XOF (extendable-output function) result.
242-
pub trait XofReader {
243-
/// Read output into the `buffer`. Can be called an unlimited number of times.
244-
fn read(&mut self, buffer: &mut [u8]);
245-
246-
/// Read output into a boxed slice of the specified size.
247-
///
248-
/// Can be called an unlimited number of times in combination with `read`.
249-
///
250-
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
251-
/// they have size of 2 and 3 words respectively.
252-
#[cfg(feature = "alloc")]
253-
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
254-
fn read_boxed(&mut self, n: usize) -> Box<[u8]> {
255-
let mut buf = vec![0u8; n].into_boxed_slice();
256-
self.read(&mut buf);
257-
buf
258-
}
259-
}
260-
261-
/// Trait which describes extendable-output functions (XOF).
262-
pub trait ExtendableOutput: Sized {
263-
/// Reader
264-
type Reader: XofReader;
265-
266-
/// Retrieve XOF reader and consume hasher instance.
267-
fn finalize_xof(self) -> Self::Reader;
268-
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.
274-
///
275-
/// `Box<[u8]>` is used instead of `Vec<u8>` to save stack space, since
276-
/// they have size of 2 and 3 words respectively.
277-
#[cfg(feature = "alloc")]
278-
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
279-
fn finalize_boxed(self, n: usize) -> Box<[u8]> {
280-
let mut buf = vec![0u8; n].into_boxed_slice();
281-
self.finalize_xof().read(&mut buf);
282-
buf
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-
}
332-
}
333-
33479
/// Trait for resetting hash instances
33580
pub trait Reset {
33681
/// Reset hasher instance to its initial state and return current state.

0 commit comments

Comments
 (0)