| 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 | |