Skip to main content
This is unreleased documentation for the main (development) branch of crypto-glue.

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}