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. |
6 | use crate::InvalidOutputSize; |
7 | |
8 | pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; |
9 | |
10 | use block_buffer::{BlockBuffer, BufferKind}; |
11 | use crypto_common::{ |
12 | typenum::{IsLess, Le, NonZero, U256}, |
13 | Output, |
14 | }; |
15 | |
16 | mod ct_variable; |
17 | mod rt_variable; |
18 | mod wrapper; |
19 | mod xof_reader; |
20 | |
21 | pub use ct_variable::CtVariableCoreWrapper; |
22 | pub use rt_variable::RtVariableCoreWrapper; |
23 | pub use wrapper::{CoreProxy, CoreWrapper}; |
24 | pub use xof_reader::XofReaderCoreWrapper; |
25 | |
26 | /// Buffer type used by type which implements [`BufferKindUser`]. |
27 | pub type Buffer<S> = |
28 | BlockBuffer<<S as BlockSizeUser>::BlockSize, <S as BufferKindUser>::BufferKind>; |
29 | |
30 | /// Types which consume data in blocks. |
31 | pub 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. |
37 | pub 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. |
43 | pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser |
44 | where |
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. |
54 | pub trait ExtendableOutputCore: UpdateCore + BufferKindUser |
55 | where |
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. |
68 | pub 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 |
84 | pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized |
85 | where |
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)] |
114 | pub enum TruncSide { |
115 | /// Truncate left side, i.e. `&out[..n]`. |
116 | Left, |
117 | /// Truncate right side, i.e. `&out[m..]`. |
118 | Right, |
119 | } |
120 | |