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::InvalidOutputSize;
7
8pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset};
9
10use block_buffer::{BlockBuffer, BufferKind};
11use crypto_common::{
12 typenum::{IsLess, Le, NonZero, U256},
13 Output,
14};
15
16mod ct_variable;
17mod rt_variable;
18mod wrapper;
19mod xof_reader;
20
21pub use ct_variable::CtVariableCoreWrapper;
22pub use rt_variable::RtVariableCoreWrapper;
23pub use wrapper::{CoreProxy, CoreWrapper};
24pub use xof_reader::XofReaderCoreWrapper;
25
26/// Buffer type used by type which implements [`BufferKindUser`].
27pub type Buffer<S> =
28 BlockBuffer<<S as BlockSizeUser>::BlockSize, <S as BufferKindUser>::BufferKind>;
29
30/// Types which consume data in blocks.
31pub trait UpdateCore: BlockSizeUser {
32 /// Update state using the provided data blocks.
33 fn update_blocks(&mut self, blocks: &[Block<Self>]);
34}
35
36/// Types which use [`BlockBuffer`] functionality.
37pub trait BufferKindUser: BlockSizeUser {
38 /// Block buffer kind over which type operates.
39 type BufferKind: BufferKind;
40}
41
42/// Core trait for hash functions with fixed output size.
43pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser
44where
45 Self::BlockSize: IsLess<U256>,
46 Le<Self::BlockSize, U256>: NonZero,
47{
48 /// Finalize state using remaining data stored in the provided block buffer,
49 /// write result into provided array and leave `self` in a dirty state.
50 fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
51}
52
53/// Core trait for hash functions with extendable (XOF) output size.
54pub trait ExtendableOutputCore: UpdateCore + BufferKindUser
55where
56 Self::BlockSize: IsLess<U256>,
57 Le<Self::BlockSize, U256>: NonZero,
58{
59 /// XOF reader core state.
60 type ReaderCore: XofReaderCore;
61
62 /// Retrieve XOF reader using remaining data stored in the block buffer
63 /// and leave hasher in a dirty state.
64 fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore;
65}
66
67/// Core reader trait for extendable-output function (XOF) result.
68pub trait XofReaderCore: BlockSizeUser {
69 /// Read next XOF block.
70 fn read_block(&mut self) -> Block<Self>;
71}
72
73/// Core trait for hash functions with variable output size.
74///
75/// Maximum output size is equal to [`OutputSizeUser::OutputSize`].
76/// Users are expected to truncate result returned by the
77/// [`finalize_variable_core`] to `output_size` passed to the [`new`] method
78/// during construction. Truncation side is defined by the [`TRUNC_SIDE`]
79/// associated constant.
80///
81/// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core
82/// [`new`]: VariableOutputCore::new
83/// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
84pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized
85where
86 Self::BlockSize: IsLess<U256>,
87 Le<Self::BlockSize, U256>: NonZero,
88{
89 /// Side which should be used in a truncated result.
90 const TRUNC_SIDE: TruncSide;
91
92 /// Initialize hasher state for given output size.
93 ///
94 /// Returns [`InvalidOutputSize`] if `output_size` is not valid for
95 /// the algorithm, e.g. if it's bigger than the [`OutputSize`]
96 /// associated type.
97 ///
98 /// [`OutputSize`]: OutputSizeUser::OutputSize
99 fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
100
101 /// Finalize hasher and write full hashing result into the `out` buffer.
102 ///
103 /// The result must be truncated to `output_size` used during hasher
104 /// construction. Truncation side is defined by the [`TRUNC_SIDE`]
105 /// associated constant.
106 ///
107 /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
108 fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
109}
110
111/// Type which used for defining truncation side in the [`VariableOutputCore`]
112/// trait.
113#[derive(Copy, Clone, Debug)]
114pub enum TruncSide {
115 /// Truncate left side, i.e. `&out[..n]`.
116 Left,
117 /// Truncate right side, i.e. `&out[m..]`.
118 Right,
119}
120