logo
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Low-level traits operating on blocks and wrappers around them.
//!
//! Usage of traits in this module in user code is discouraged. Instead use
//! core algorithm wrapped by the wrapper types, which implement the
//! higher-level traits.
use crate::InvalidOutputSize;

pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset};

use block_buffer::{BlockBuffer, BufferKind};
use crypto_common::{
    typenum::{IsLess, Le, NonZero, U256},
    Output,
};

mod ct_variable;
mod rt_variable;
mod wrapper;
mod xof_reader;

pub use ct_variable::CtVariableCoreWrapper;
pub use rt_variable::RtVariableCoreWrapper;
pub use wrapper::{CoreProxy, CoreWrapper};
pub use xof_reader::XofReaderCoreWrapper;

/// Buffer type used by type which implements [`BufferKindUser`].
pub type Buffer<S> =
    BlockBuffer<<S as BlockSizeUser>::BlockSize, <S as BufferKindUser>::BufferKind>;

/// Types which consume data in blocks.
pub trait UpdateCore: BlockSizeUser {
    /// Update state using the provided data blocks.
    fn update_blocks(&mut self, blocks: &[Block<Self>]);
}

/// Types which use [`BlockBuffer`] functionality.
pub trait BufferKindUser: BlockSizeUser {
    /// Block buffer kind over which type operates.
    type BufferKind: BufferKind;
}

/// Core trait for hash functions with fixed output size.
pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser
where
    Self::BlockSize: IsLess<U256>,
    Le<Self::BlockSize, U256>: NonZero,
{
    /// Finalize state using remaining data stored in the provided block buffer,
    /// write result into provided array and leave `self` in a dirty state.
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
}

/// Core trait for hash functions with extendable (XOF) output size.
pub trait ExtendableOutputCore: UpdateCore + BufferKindUser
where
    Self::BlockSize: IsLess<U256>,
    Le<Self::BlockSize, U256>: NonZero,
{
    /// XOF reader core state.
    type ReaderCore: XofReaderCore;

    /// Retrieve XOF reader using remaining data stored in the block buffer
    /// and leave hasher in a dirty state.
    fn finalize_xof_core(&mut self, buffer: &mut Buffer<Self>) -> Self::ReaderCore;
}

/// Core reader trait for extendable-output function (XOF) result.
pub trait XofReaderCore: BlockSizeUser {
    /// Read next XOF block.
    fn read_block(&mut self) -> Block<Self>;
}

/// Core trait for hash functions with variable output size.
///
/// Maximum output size is equal to [`OutputSizeUser::OutputSize`].
/// Users are expected to truncate result returned by the
/// [`finalize_variable_core`] to `output_size` passed to the [`new`] method
/// during construction. Truncation side is defined by the [`TRUNC_SIDE`]
/// associated constant.
///
/// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core
/// [`new`]: VariableOutputCore::new
/// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized
where
    Self::BlockSize: IsLess<U256>,
    Le<Self::BlockSize, U256>: NonZero,
{
    /// Side which should be used in a truncated result.
    const TRUNC_SIDE: TruncSide;

    /// Initialize hasher state for given output size.
    ///
    /// Returns [`InvalidOutputSize`] if `output_size` is not valid for
    /// the algorithm, e.g. if it's bigger than the [`OutputSize`]
    /// associated type.
    ///
    /// [`OutputSize`]: OutputSizeUser::OutputSize
    fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;

    /// Finalize hasher and write full hashing result into the `out` buffer.
    ///
    /// The result must be truncated to `output_size` used during hasher
    /// construction. Truncation side is defined by the [`TRUNC_SIDE`]
    /// associated constant.
    ///
    /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE
    fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>);
}

/// Type which used for defining truncation side in the [`VariableOutputCore`]
/// trait.
#[derive(Copy, Clone, Debug)]
pub enum TruncSide {
    /// Truncate left side, i.e. `&out[..n]`.
    Left,
    /// Truncate right side, i.e. `&out[m..]`.
    Right,
}