use crate::{constants::CONTEXT_MAX_LEN, hash_functions, SigningError, VerificationError};
pub(crate) const PRE_HASH_OID_LEN: usize = 11;
pub(crate) type PreHashOID = [u8; PRE_HASH_OID_LEN];
pub(crate) trait PreHash {
fn oid() -> PreHashOID;
fn hash<Shake128: hash_functions::shake128::Xof>(message: &[u8], output: &mut [u8]);
}
#[allow(non_camel_case_types)]
pub(crate) struct SHAKE128_PH();
const SHAKE128_OID: PreHashOID = [
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0b,
];
impl PreHash for SHAKE128_PH {
fn oid() -> PreHashOID {
SHAKE128_OID
}
#[inline(always)]
fn hash<Shake128: hash_functions::shake128::Xof>(message: &[u8], output: &mut [u8]) {
#[cfg(not(eurydice))]
debug_assert_eq!(output.len(), 32);
Shake128::shake128(message, output);
}
}
pub(crate) struct DomainSeparationContext<'a> {
context: &'a [u8],
pre_hash_oid: Option<PreHashOID>,
}
pub(crate) enum DomainSeparationError {
ContextTooLongError,
}
pub(crate) type PreHashResult<'a> = Result<DomainSeparationContext<'a>, DomainSeparationError>;
impl<'a> DomainSeparationContext<'a> {
pub(crate) fn new(context: &'a [u8], pre_hash_oid: Option<PreHashOID>) -> PreHashResult<'a> {
if context.len() > CONTEXT_MAX_LEN {
return Err(DomainSeparationError::ContextTooLongError);
}
Ok(Self {
context,
pre_hash_oid,
})
}
pub fn context(&self) -> &[u8] {
self.context
}
pub fn pre_hash_oid(&self) -> &Option<PreHashOID> {
&self.pre_hash_oid
}
}
impl From<DomainSeparationError> for SigningError {
fn from(e: DomainSeparationError) -> SigningError {
match e {
DomainSeparationError::ContextTooLongError => SigningError::ContextTooLongError,
}
}
}
impl From<DomainSeparationError> for VerificationError {
fn from(e: DomainSeparationError) -> VerificationError {
match e {
DomainSeparationError::ContextTooLongError => {
VerificationError::VerificationContextTooLongError
}
}
}
}