use crate::NBitKeccakState; use core::hash::Hasher; use core::ops::{BitAnd, BitAndAssign, BitOr, BitXor, BitXorAssign, Not, Sub}; use rs_hasher_ctx::{ByteArrayWrapper, GenericHasher, HasherContext}; use rs_internal_hasher::HashAlgorithm; use rs_internal_state::ExtendedOutputFunction; use rs_n_bit_words::{LittleEndianBytes, NBitWord, Rotate, TSize}; /// `NBitKeccakHasher` is a type that provides the Keccak-nBits hashing algorithm in RustyShield. /// /// A "Hasher" in the context of cryptographic hashing refers to the object that manages the process of converting input /// data into a fixed-size sequence of bytes. The Hasher is responsible for maintaining the internal state of the /// hashing process and providing methods to add more data and retrieve the resulting hash. /// /// The `NBitKeccakHasher` struct adheres to Rust's `Hasher` trait, enabling you to use it interchangeably with other /// hashers in Rust. It can be used anywhere a type implementing `Hasher` is required. /// /// ## Examples /// /// The following examples demonstrate using `NBitKeccakHasher` with both `Hash` and `Hasher`, and from where the /// difference comes from: /// ///```rust /// # use std::hash::{BuildHasher, Hash, Hasher}; /// # use rs_keccak_nbits::NBitKeccakHasher; /// let data = b"hello"; /// /// // Using Hash /// let mut keccakhasher = NBitKeccakHasher::::default(); /// data.hash(&mut keccakhasher); /// let result_via_hash = keccakhasher.finish(); /// /// // Using Hasher /// let mut keccakhasher = NBitKeccakHasher::::default(); /// keccakhasher.write(data); /// let result_via_hasher = keccakhasher.finish(); /// /// // Simulating the Hash inners /// let mut keccakhasher = NBitKeccakHasher::::default(); /// keccakhasher.write_usize(data.len()); /// keccakhasher.write(data); /// let simulated_hash_result = keccakhasher.finish(); /// /// assert_ne!(result_via_hash, result_via_hasher); /// assert_eq!(result_via_hash, simulated_hash_result); ///``` #[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct NBitKeccakHasher( GenericHasher, OUTPUT_SIZE>, ) where T: BitAnd + BitAndAssign + BitOr, Output = NBitWord> + BitXor + BitXorAssign + Copy + Default + Not, NBitWord: From + LittleEndianBytes + Not> + Rotate + TSize, u32: Sub, Output = NBitWord>; impl From> for NBitKeccakState where T: Copy + Default + BitAnd + BitAndAssign + BitOr, Output = NBitWord> + BitXor + BitXorAssign + Not, NBitWord: From + LittleEndianBytes + Not> + Rotate + TSize, u32: Sub, Output = NBitWord>, { fn from(value: NBitKeccakHasher) -> Self { value.0.state } } impl From> for NBitKeccakHasher where T: Copy + Default + BitAnd + BitAndAssign + BitOr, Output = NBitWord> + BitXor + BitXorAssign + Not, NBitWord: From + LittleEndianBytes + Not> + Rotate + TSize, u32: Sub, Output = NBitWord>, { fn from(value: NBitKeccakState) -> Self { Self(GenericHasher { padding: as HashAlgorithm>::Padding::default(), state: value, }) } } impl Hasher for NBitKeccakHasher where T: BitAnd + BitAndAssign + BitOr, Output = NBitWord> + BitXor + BitXorAssign + Copy + Default + Not, NBitWord: From + LittleEndianBytes + Not> + Rotate + TSize, u32: Sub, Output = NBitWord>, { fn finish(&self) -> u64 { Hasher::finish(&self.0) } fn write(&mut self, bytes: &[u8]) { self.0.write(bytes) } } impl HasherContext for NBitKeccakHasher where T: BitAnd + BitAndAssign + BitOr, Output = NBitWord> + BitXor + BitXorAssign + Copy + Default + Not, NBitWord: From + LittleEndianBytes + Not> + Rotate + TSize, u32: Sub, Output = NBitWord>, { type Output = ByteArrayWrapper; fn finish(&mut self) -> Self::Output { HasherContext::finish(&mut self.0).squeeze().into() } }