Revision control
Copy as Markdown
Other Tools
use super::*;
use libcrux_hacl_rs::prelude::*;
use libcrux_traits::Digest;
/// The different Sha2 algorithms.
#[derive(Clone, Copy, Debug)]
pub enum Algorithm {
Sha224,
Sha256,
Sha384,
Sha512,
}
impl Algorithm {
// The length of the digest by algorithm.
pub const fn hash_len(&self) -> usize {
match self {
Algorithm::Sha224 => SHA224_LENGTH,
Algorithm::Sha256 => SHA256_LENGTH,
Algorithm::Sha384 => SHA384_LENGTH,
Algorithm::Sha512 => SHA512_LENGTH,
}
}
}
impl Algorithm {
/// Sha2
///
/// Write the Sha2 hash of `payload` into `digest`.
pub fn hash(&self, payload: &[u8], digest: &mut [u8]) {
match self {
Algorithm::Sha224 => Sha224::hash(digest, payload),
Algorithm::Sha256 => Sha256::hash(digest, payload),
Algorithm::Sha384 => Sha384::hash(digest, payload),
Algorithm::Sha512 => Sha512::hash(digest, payload),
}
}
}
/// SHA2 224
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
pub fn sha224(payload: &[u8]) -> [u8; SHA224_LENGTH] {
let mut digest = [0u8; SHA224_LENGTH];
Sha224::hash(&mut digest, payload);
digest
}
/// SHA2 256
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
pub fn sha256(payload: &[u8]) -> [u8; SHA256_LENGTH] {
let mut digest = [0u8; SHA256_LENGTH];
Sha256::hash(&mut digest, payload);
digest
}
/// SHA2 384
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
pub fn sha384(payload: &[u8]) -> [u8; SHA384_LENGTH] {
let mut digest = [0u8; SHA384_LENGTH];
Sha384::hash(&mut digest, payload);
digest
}
/// SHA2 512
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
pub fn sha512(payload: &[u8]) -> [u8; SHA512_LENGTH] {
let mut digest = [0u8; SHA512_LENGTH];
Sha512::hash(&mut digest, payload);
digest
}
// Streaming API - This is the recommended one.
// For implementations based on hacl_rs (over hacl-c)
macro_rules! impl_hash {
($name:ident, $digest_size:literal, $state:ty, $malloc:expr, $reset:expr, $update:expr, $finish:expr, $copy:expr, $hash:expr) => {
#[allow(non_camel_case_types)]
pub struct $name {
state: $state,
}
impl $name {
/// Initialize a new digest state for streaming use.
pub fn new() -> $name {
$name { state: $malloc() }
}
}
impl libcrux_traits::Digest<$digest_size> for $name {
/// Return the digest for the given input byte slice, in immediate mode.
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
fn hash(digest: &mut [u8], payload: &[u8]) {
debug_assert!(digest.len() == $digest_size);
let payload_len = payload.len().try_into().unwrap();
$hash(digest, payload, payload_len)
}
/// Add the `payload` to the digest.
/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can
/// process it.
#[inline(always)]
fn update(&mut self, payload: &[u8]) {
let payload_len = payload.len().try_into().unwrap();
$update(self.state.as_mut(), payload, payload_len);
}
/// Get the digest.
///
/// Note that the digest state can be continued to be used, to extend the
/// digest.
#[inline(always)]
fn finish(&self, digest: &mut [u8; $digest_size]) {
$finish(self.state.as_ref(), digest);
}
/// Reset the digest state.
#[inline(always)]
fn reset(&mut self) {
$reset(self.state.as_mut());
}
}
impl Default for $name {
#[inline(always)]
fn default() -> Self {
Self::new()
}
}
impl Clone for $name {
#[inline(always)]
fn clone(&self) -> Self {
Self {
state: $copy(self.state.as_ref()),
}
}
}
};
}
impl_hash!(
Sha256,
32,
Box<[libcrux_hacl_rs::streaming_types::state_32]>,
crate::hacl::malloc_256,
crate::hacl::reset_256,
crate::hacl::update_256,
crate::hacl::digest_256,
crate::hacl::copy_256,
crate::hacl::hash_256
);
impl_hash!(
Sha224,
28,
Box<[libcrux_hacl_rs::streaming_types::state_32]>,
crate::hacl::malloc_224,
crate::hacl::reset_224,
crate::hacl::update_224,
crate::hacl::digest_224,
crate::hacl::copy_256,
crate::hacl::hash_224
);
impl_hash!(
Sha512,
64,
Box<[libcrux_hacl_rs::streaming_types::state_64]>,
crate::hacl::malloc_512,
crate::hacl::reset_512,
crate::hacl::update_512,
crate::hacl::digest_512,
crate::hacl::copy_512,
crate::hacl::hash_512
);
impl_hash!(
Sha384,
48,
Box<[libcrux_hacl_rs::streaming_types::state_64]>,
crate::hacl::malloc_384,
crate::hacl::reset_384,
crate::hacl::update_384,
crate::hacl::digest_384,
crate::hacl::copy_512,
crate::hacl::hash_384
);