evidence 0.1.0

Type-level tags for cryptographic primitives
Documentation
//! SHA-3 hash implementations.

use super::DigestPrimitive;
use hybrid_array::{
    Array,
    typenum::{U28, U32, U48, U64},
};
use sha3::Digest as _;

/// SHA3-224 hash primitive (28 bytes).
#[derive(Debug, Clone, Copy)]
pub enum Sha3_224 {}

impl DigestPrimitive for Sha3_224 {
    type Size = U28;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Sha3_224::digest(data);
        Array::try_from(result.as_slice()).expect("sha3-224 output is always 28 bytes")
    }
}

/// SHA3-256 hash primitive (32 bytes).
#[derive(Debug, Clone, Copy)]
pub enum Sha3_256 {}

impl DigestPrimitive for Sha3_256 {
    type Size = U32;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Sha3_256::digest(data);
        Array::try_from(result.as_slice()).expect("sha3-256 output is always 32 bytes")
    }
}

/// SHA3-384 hash primitive (48 bytes).
#[derive(Debug, Clone, Copy)]
pub enum Sha3_384 {}

impl DigestPrimitive for Sha3_384 {
    type Size = U48;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Sha3_384::digest(data);
        Array::try_from(result.as_slice()).expect("sha3-384 output is always 48 bytes")
    }
}

/// SHA3-512 hash primitive (64 bytes).
#[derive(Debug, Clone, Copy)]
pub enum Sha3_512 {}

impl DigestPrimitive for Sha3_512 {
    type Size = U64;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Sha3_512::digest(data);
        Array::try_from(result.as_slice()).expect("sha3-512 output is always 64 bytes")
    }
}

/// Keccak-256 hash primitive (32 bytes).
///
/// This is the Keccak variant used by Ethereum before SHA-3 was standardized.
/// It differs from SHA3-256 in the padding scheme.
#[derive(Debug, Clone, Copy)]
pub enum Keccak256 {}

impl DigestPrimitive for Keccak256 {
    type Size = U32;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Keccak256::digest(data);
        Array::try_from(result.as_slice()).expect("keccak256 output is always 32 bytes")
    }
}

/// Keccak-512 hash primitive (64 bytes).
#[derive(Debug, Clone, Copy)]
pub enum Keccak512 {}

impl DigestPrimitive for Keccak512 {
    type Size = U64;

    #[allow(clippy::expect_used)] // output size is type-level guaranteed
    fn hash(data: &[u8]) -> Array<u8, Self::Size> {
        let result = sha3::Keccak512::digest(data);
        Array::try_from(result.as_slice()).expect("keccak512 output is always 64 bytes")
    }
}