digest/block_api.rs
1//! Low-level traits operating on blocks and wrappers around them.
2//!
3//! Usage of traits in this module in user code is discouraged. Instead use
4//! core algorithm wrapped by the wrapper types, which implement the
5//! higher-level traits.
6use crate::{Digest, HashMarker, InvalidOutputSize};
7
8pub use block_buffer::{Eager, Lazy};
9pub use common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset};
10
11use block_buffer::{BlockBuffer, BufferKind};
12use common::Output;
13
14mod ct_variable;
15pub use ct_variable::CtOutWrapper;
16
17/// Buffer type used by type which implements [`BufferKindUser`].
18pub type Buffer<S> =
19 BlockBuffer<<S as BlockSizeUser>::BlockSize, <S as BufferKindUser>::BufferKind>;
20
21/// Types which consume data in blocks.
22pub trait UpdateCore: BlockSizeUser {
23 /// Update state using the provided data blocks.
24 fn update_blocks(&mut self, blocks: &[Block<Self>]);
25}
26
27/// Types which use [`BlockBuffer`] functionality.
28pub trait BufferKindUser: BlockSizeUser {
29 /// Block buffer kind over which type operates.
30 type BufferKind: BufferKind;
31}
32
33/// Trait implemented by eager hashes which expose their block-level core.
34pub trait EagerHash: BlockSizeUser + Digest {
35 /// Block-level core type of the hash.
36 type Core: HashMarker
37 + UpdateCore
38 + FixedOutputCore
39 + BlockSizeUser<BlockSize = <Self as BlockSizeUser>::BlockSize>
40 + BufferKindUser<BufferKind = Eager>
41 + Default
42 + Clone;
43}
44
45impl<T> EagerHash for T
46where
47 T: CoreProxy + BlockSizeUser + Digest,
48 <T as CoreProxy>::Core: HashMarker
49 + UpdateCore
50 + FixedOutputCore
51 + BlockSizeUser<BlockSize = <Self as BlockSizeUser>::BlockSize>
52 + BufferKindUser<BufferKind = Eager>
53 + Default
54 + Clone,
55{
56 type Core = T::Core;
57}
58
59/// Core trait for hash functions with fixed output size.
60pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser {
61 /// Finalize state using remaining data stored in the provided block buffer,
62 /// write result into provided array and leave `self` in a dirty state.
63 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
64}
65
66/// Core trait for hash functions with extendable (XOF) output size.
67pub trait ExtendableOutputCore: UpdateCore + BufferKindUser {
68 /// XOF reader core state.
69 type ReaderCore: XofReaderCore;
70
71 /// Retrieve XOF reader using remaining data stored in the block buffer
72 /// and leave hasher in a dirty state.
73 fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore;
74}
75
76/// Core reader trait for extendable-output function (XOF) result.
77pub trait XofReaderCore: BlockSizeUser {
78 /// Read next XOF block.
79 fn read_block(&mut self) -> Block<Self>;
80}
81
82/// Core trait for hash functions with variable output size.
83///
84/// Maximum output size is equal to [`OutputSizeUser::OutputSize`].
85/// Users are expected to truncate result returned by the
86/// [`finalize_variable_core`] to `output_size` passed to the [`new`] method
87/// during construction. Truncation side is defined by the [`TRUNC_SIDE`]
88/// associated constant.
89///
90/// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core
91/// [`new`]: VariableOutputCore::new
92/// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
93pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized {
94 /// Side which should be used in a truncated result.
95 const TRUNC_SIDE: TruncSide;
96
97 /// Initialize hasher state for given output size.
98 ///
99 /// Returns [`InvalidOutputSize`] if `output_size` is not valid for
100 /// the algorithm, e.g. if it's bigger than the [`OutputSize`]
101 /// associated type.
102 ///
103 /// [`OutputSize`]: OutputSizeUser::OutputSize
104 fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
105
106 /// Finalize hasher and write full hashing result into the `out` buffer.
107 ///
108 /// The result must be truncated to `output_size` used during hasher
109 /// construction. Truncation side is defined by the [`TRUNC_SIDE`]
110 /// associated constant.
111 ///
112 /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
113 fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
114}
115
116/// Trait adding customization string to hash functions with variable output.
117pub trait VariableOutputCoreCustomized: VariableOutputCore {
118 /// Create new hasher instance with the given customization string and output size.
119 fn new_customized(customization: &[u8], output_size: usize) -> Self;
120}
121
122/// Type which used for defining truncation side in the [`VariableOutputCore`]
123/// trait.
124#[derive(Copy, Clone, Debug)]
125pub enum TruncSide {
126 /// Truncate left side, i.e. `&out[..n]`.
127 Left,
128 /// Truncate right side, i.e. `&out[m..]`.
129 Right,
130}
131
132/// A proxy trait to the core block-level type.
133pub trait CoreProxy {
134 /// Core block-level type.
135 type Core: BufferKindUser;
136
137 /// Create `Self` from core and buffer.
138 fn compose(core: Self::Core, buffer: Buffer<Self::Core>) -> Self;
139 /// Decompose `self` into core and buffer.
140 fn decompose(self) -> (Self::Core, Buffer<Self::Core>);
141}