use alloc::vec::Vec;
use digest::{
CustomizedInit,
Digest,
ExtendableOutput,
ExtendableOutputReset,
Update,
XofReader,
};
use lib_q_core::{
Error,
Hash,
Result,
};
use crate::utils::MAX_SP800185_FIXED_OUTPUT_BYTES;
use crate::{
CShake128,
CShake256,
Keccak224,
Keccak256,
Keccak384,
Keccak512,
Kmac128,
Kmac256,
Kt128,
Kt256,
ParallelHash128,
ParallelHash256,
Sha3_224,
Sha3_256,
Sha3_384,
Sha3_512,
Shake128,
Shake256,
TupleHash128,
TupleHash256,
TurboShake128,
TurboShake256,
};
#[derive(Debug, Clone)]
pub struct CShake128Hash(CShake128);
#[derive(Debug, Clone)]
pub struct CShake256Hash(CShake256);
#[derive(Debug, Clone)]
pub struct Shake128Hash(Shake128);
#[derive(Debug, Clone)]
pub struct Shake256Hash(Shake256);
#[derive(Debug, Clone)]
pub struct Sha3_224Hash(Sha3_224);
#[derive(Debug, Clone)]
pub struct Sha3_256Hash(Sha3_256);
#[derive(Debug, Clone)]
pub struct Sha3_384Hash(Sha3_384);
#[derive(Debug, Clone)]
pub struct Sha3_512Hash(Sha3_512);
#[derive(Debug, Clone)]
pub struct Kt128Hash(Kt128<'static>);
#[derive(Debug, Clone)]
pub struct Kt256Hash(Kt256<'static>);
#[derive(Debug, Clone)]
pub struct Keccak224Hash(Keccak224);
#[derive(Debug, Clone)]
pub struct Keccak256Hash(Keccak256);
#[derive(Debug, Clone)]
pub struct Keccak384Hash(Keccak384);
#[derive(Debug, Clone)]
pub struct Keccak512Hash(Keccak512);
#[derive(Debug, Clone)]
pub struct Kmac128Hash(Kmac128);
#[derive(Debug, Clone)]
pub struct Kmac256Hash(Kmac256);
#[derive(Debug, Clone)]
pub struct TupleHash128Hash(TupleHash128);
#[derive(Debug, Clone)]
pub struct TupleHash256Hash(TupleHash256);
#[derive(Debug, Clone)]
pub struct ParallelHash128Hash(ParallelHash128);
#[derive(Debug, Clone)]
pub struct ParallelHash256Hash(ParallelHash256);
#[derive(Debug, Clone)]
pub struct TurboShake128Hash(TurboShake128<0x1F>);
#[derive(Debug, Clone)]
pub struct TurboShake256Hash(TurboShake256<0x1F>);
impl CShake128Hash {
pub fn new() -> Self {
Self(CShake128::default())
}
pub fn new_customized(customization: &[u8]) -> Self {
Self(CShake128::new_customized(customization))
}
pub fn new_with_function_name(function_name: &[u8], customization: &[u8]) -> Self {
Self(CShake128::new_with_function_name(
function_name,
customization,
))
}
}
impl CShake256Hash {
pub fn new() -> Self {
Self(CShake256::default())
}
pub fn new_customized(customization: &[u8]) -> Self {
Self(CShake256::new_customized(customization))
}
pub fn new_with_function_name(function_name: &[u8], customization: &[u8]) -> Self {
Self(CShake256::new_with_function_name(
function_name,
customization,
))
}
}
impl Shake128Hash {
pub fn new() -> Self {
Self(Shake128::default())
}
}
impl Shake256Hash {
pub fn new() -> Self {
Self(Shake256::default())
}
}
impl Sha3_224Hash {
pub fn new() -> Self {
Self(Sha3_224::default())
}
}
impl Sha3_256Hash {
pub fn new() -> Self {
Self(Sha3_256::default())
}
}
impl Sha3_384Hash {
pub fn new() -> Self {
Self(Sha3_384::default())
}
}
impl Sha3_512Hash {
pub fn new() -> Self {
Self(Sha3_512::default())
}
}
impl Kt128Hash {
pub fn new() -> Self {
Self(Kt128::new(b""))
}
pub fn new_customized(customization: &'static [u8]) -> Self {
Self(Kt128::new(customization))
}
}
impl Kt256Hash {
pub fn new() -> Self {
Self(Kt256::new(b""))
}
pub fn new_customized(customization: &'static [u8]) -> Self {
Self(Kt256::new(customization))
}
}
impl Keccak224Hash {
pub fn new() -> Self {
Self(Keccak224::default())
}
}
impl Keccak256Hash {
pub fn new() -> Self {
Self(Keccak256::default())
}
}
impl Keccak384Hash {
pub fn new() -> Self {
Self(Keccak384::default())
}
}
impl Keccak512Hash {
pub fn new() -> Self {
Self(Keccak512::default())
}
}
impl TurboShake128Hash {
pub fn new() -> Self {
Self(TurboShake128::<0x1F>::default())
}
}
impl TurboShake256Hash {
pub fn new() -> Self {
Self(TurboShake256::<0x1F>::default())
}
}
impl Hash for CShake128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 16];
hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for CShake256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 32];
hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for Shake128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 16];
hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for Shake256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 32];
hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for Sha3_224Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
28
}
}
impl Hash for Sha3_256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for Sha3_384Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
48
}
}
impl Hash for Sha3_512Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
64
}
}
impl Hash for Kt128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 32];
let mut reader = hasher.finalize_xof();
reader.read(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for Kt256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 64];
let mut reader = hasher.finalize_xof();
reader.read(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
64
}
}
impl Hash for Keccak224Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
28
}
}
impl Hash for Keccak256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for Keccak384Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
48
}
}
impl Hash for Keccak512Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let result = hasher.finalize();
Ok(result.to_vec())
}
fn output_size(&self) -> usize {
64
}
}
impl Default for CShake128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for CShake256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Shake128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Shake256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Sha3_224Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Sha3_256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Sha3_384Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Sha3_512Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Kt128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Kt256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Keccak224Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Keccak256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Keccak384Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Keccak512Hash {
fn default() -> Self {
Self::new()
}
}
impl Kmac128Hash {
pub fn new() -> Self {
Self(Kmac128::new(b"", b""))
}
pub fn new_with_key_and_custom(key: &[u8], custom: &[u8]) -> Self {
Self(Kmac128::new(key, custom))
}
}
impl Kmac256Hash {
pub fn new() -> Self {
Self(Kmac256::new(b"", b""))
}
pub fn new_with_key_and_custom(key: &[u8], custom: &[u8]) -> Self {
Self(Kmac256::new(key, custom))
}
}
impl TupleHash128Hash {
pub fn new() -> Self {
Self(TupleHash128::new(b""))
}
pub fn new_with_custom(custom: &[u8]) -> Self {
Self(TupleHash128::new(custom))
}
}
impl TupleHash256Hash {
pub fn new() -> Self {
Self(TupleHash256::new(b""))
}
pub fn new_with_custom(custom: &[u8]) -> Self {
Self(TupleHash256::new(custom))
}
}
impl ParallelHash128Hash {
pub fn new() -> Self {
Self(ParallelHash128::new(b"", 8192))
}
pub fn new_with_custom_and_block_size(custom: &[u8], block_size: usize) -> Self {
Self(ParallelHash128::new(custom, block_size))
}
}
impl ParallelHash256Hash {
pub fn new() -> Self {
Self(ParallelHash256::new(b"", 8192))
}
pub fn new_with_custom_and_block_size(custom: &[u8], block_size: usize) -> Self {
Self(ParallelHash256::new(custom, block_size))
}
}
impl Hash for Kmac128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
hasher.update(data);
let result = hasher
.finalize_with_length(16)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 16,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for Kmac256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
hasher.update(data);
let result = hasher
.finalize_with_length(32)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 32,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for TupleHash128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
let tuple = alloc::vec![data];
hasher.update_tuple(&tuple);
let result = hasher
.finalize_with_length(16)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 16,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for TupleHash256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
let tuple = alloc::vec![data];
hasher.update_tuple(&tuple);
let result = hasher
.finalize_with_length(32)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 32,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for ParallelHash128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
hasher.update(data);
let result = hasher
.finalize_with_length(16)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 16,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for ParallelHash256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
hasher.update(data);
let result = hasher
.finalize_with_length(32)
.ok_or(Error::InvalidMessageSize {
max: MAX_SP800185_FIXED_OUTPUT_BYTES,
actual: 32,
})?;
Ok(result)
}
fn output_size(&self) -> usize {
32
}
}
impl Hash for TurboShake128Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 16]; hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
16
}
}
impl Hash for TurboShake256Hash {
fn hash(&self, data: &[u8]) -> Result<Vec<u8>> {
let mut hasher = self.0.clone();
Update::update(&mut hasher, data);
let mut output = [0u8; 32]; hasher.finalize_xof_reset_into(&mut output);
Ok(output.to_vec())
}
fn output_size(&self) -> usize {
32
}
}
impl Default for Kmac128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for Kmac256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for TupleHash128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for TupleHash256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for ParallelHash128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for ParallelHash256Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for TurboShake128Hash {
fn default() -> Self {
Self::new()
}
}
impl Default for TurboShake256Hash {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod hash_type_tests {
use super::*;
use crate::Hash;
fn assert_hash<H: Hash>(h: &H, data: &[u8]) {
let n = h.output_size();
let out = h.hash(data).expect("hash");
assert_eq!(out.len(), n);
}
#[test]
fn wrapper_constructors_hash_and_default() {
let data = b"lib-q-hash hash_types coverage";
assert_hash(&CShake128Hash::new(), data);
assert_hash(&CShake128Hash::new_customized(b"app"), data);
assert_hash(
&CShake128Hash::new_with_function_name(b"fn", b"custom"),
data,
);
assert_hash(&CShake128Hash::default(), data);
assert_hash(&CShake256Hash::new(), data);
assert_hash(&CShake256Hash::new_customized(b"app"), data);
assert_hash(
&CShake256Hash::new_with_function_name(b"fn", b"custom"),
data,
);
assert_hash(&CShake256Hash::default(), data);
assert_hash(&Shake128Hash::new(), data);
assert_hash(&Shake128Hash::default(), data);
assert_hash(&Shake256Hash::new(), data);
assert_hash(&Shake256Hash::default(), data);
assert_hash(&Sha3_224Hash::new(), data);
assert_hash(&Sha3_224Hash::default(), data);
assert_hash(&Sha3_256Hash::new(), data);
assert_hash(&Sha3_256Hash::default(), data);
assert_hash(&Sha3_384Hash::new(), data);
assert_hash(&Sha3_384Hash::default(), data);
assert_hash(&Sha3_512Hash::new(), data);
assert_hash(&Sha3_512Hash::default(), data);
assert_hash(&Kt128Hash::new(), data);
assert_hash(&Kt128Hash::new_customized(b"custom"), data);
assert_hash(&Kt128Hash::default(), data);
assert_hash(&Kt256Hash::new(), data);
assert_hash(&Kt256Hash::new_customized(b"custom"), data);
assert_hash(&Kt256Hash::default(), data);
assert_hash(&Keccak224Hash::new(), data);
assert_hash(&Keccak224Hash::default(), data);
assert_hash(&Keccak256Hash::new(), data);
assert_hash(&Keccak256Hash::default(), data);
assert_hash(&Keccak384Hash::new(), data);
assert_hash(&Keccak384Hash::default(), data);
assert_hash(&Keccak512Hash::new(), data);
assert_hash(&Keccak512Hash::default(), data);
assert_hash(&TurboShake128Hash::new(), data);
assert_hash(&TurboShake128Hash::default(), data);
assert_hash(&TurboShake256Hash::new(), data);
assert_hash(&TurboShake256Hash::default(), data);
assert_hash(&Kmac128Hash::new(), data);
assert_hash(&Kmac128Hash::new_with_key_and_custom(b"key", b"cust"), data);
assert_hash(&Kmac128Hash::default(), data);
assert_hash(&Kmac256Hash::new(), data);
assert_hash(&Kmac256Hash::new_with_key_and_custom(b"key", b"cust"), data);
assert_hash(&Kmac256Hash::default(), data);
assert_hash(&TupleHash128Hash::new(), data);
assert_hash(&TupleHash128Hash::new_with_custom(b"c"), data);
assert_hash(&TupleHash128Hash::default(), data);
assert_hash(&TupleHash256Hash::new(), data);
assert_hash(&TupleHash256Hash::new_with_custom(b"c"), data);
assert_hash(&TupleHash256Hash::default(), data);
assert_hash(&ParallelHash128Hash::new(), data);
assert_hash(
&ParallelHash128Hash::new_with_custom_and_block_size(b"c", 1024),
data,
);
assert_hash(&ParallelHash128Hash::default(), data);
assert_hash(&ParallelHash256Hash::new(), data);
assert_hash(
&ParallelHash256Hash::new_with_custom_and_block_size(b"c", 1024),
data,
);
assert_hash(&ParallelHash256Hash::default(), data);
}
}