use crate::{aead::Aead, kdf::Kdf as KdfTrait, kem::Kem as KemTrait, HpkeError, Serializable};
pub(crate) type KemSuiteId = [u8; 5];
pub(crate) type FullSuiteId = [u8; 10];
#[rustfmt::skip]
pub(crate) fn write_u16_be(buf: &mut [u8], n: u16) {
assert_eq!(buf.len(), 2);
buf[0] = ((n & 0xff00) >> 8) as u8;
buf[1] = (n & 0x00ff) as u8;
}
#[rustfmt::skip]
pub(crate) fn write_u64_be(buf: &mut [u8], n: u64) {
assert_eq!(buf.len(), 8);
buf[0] = ((n & 0xff00000000000000) >> 56) as u8;
buf[1] = ((n & 0x00ff000000000000) >> 48) as u8;
buf[2] = ((n & 0x0000ff0000000000) >> 40) as u8;
buf[3] = ((n & 0x000000ff00000000) >> 32) as u8;
buf[4] = ((n & 0x00000000ff000000) >> 24) as u8;
buf[5] = ((n & 0x0000000000ff0000) >> 16) as u8;
buf[6] = ((n & 0x000000000000ff00) >> 8) as u8;
buf[7] = (n & 0x00000000000000ff) as u8;
}
pub(crate) fn full_suite_id<A, Kdf, Kem>() -> FullSuiteId
where
A: Aead,
Kdf: KdfTrait,
Kem: KemTrait,
{
let mut suite_id = *b"HPKEXXYYZZ";
write_u16_be(&mut suite_id[4..6], Kem::KEM_ID);
write_u16_be(&mut suite_id[6..8], Kdf::KDF_ID);
write_u16_be(&mut suite_id[8..10], A::AEAD_ID);
suite_id
}
pub(crate) fn kem_suite_id<Kem: KemTrait>() -> KemSuiteId {
let mut suite_id = *b"KEMXX";
write_u16_be(&mut suite_id[3..5], Kem::KEM_ID);
suite_id
}
macro_rules! count {
() => (0usize);
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
}
macro_rules! concat_with_known_maxlen {
( $maxlen:expr, $( $slice:expr ),* ) => {{
const BUFLEN: usize = count!($($slice)*) * $maxlen;
let mut buf = [0u8; BUFLEN];
let mut unused_space = &mut buf[..];
$(
unused_space = crate::util::write_to_buf(unused_space, $slice);
)*
let num_bytes_written = BUFLEN - unused_space.len();
(buf, num_bytes_written)
}};
}
pub(crate) fn write_to_buf<'a>(buf: &'a mut [u8], to_write: &[u8]) -> &'a mut [u8] {
buf[..to_write.len()].copy_from_slice(to_write);
&mut buf[to_write.len()..]
}
pub(crate) fn enforce_equal_len(expected_len: usize, given_len: usize) -> Result<(), HpkeError> {
if given_len != expected_len {
Err(HpkeError::IncorrectInputLength(expected_len, given_len))
} else {
Ok(())
}
}
pub(crate) fn enforce_outbuf_len<T: Serializable>(buf: &[u8]) {
let size = T::size();
let buf_len = buf.len();
assert!(
size == buf_len,
"write_exact(): serialized size ({}) does not equal buffer length ({})",
size,
buf_len,
);
}