use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
use crate::constants::HPKE_MIN_PSK_LEN;
use crate::error::HpkeError;
use crate::identifiers::HpkeSuite;
pub struct HpkePskRef<'a> {
bytes: &'a [u8],
}
impl<'a> HpkePskRef<'a> {
pub fn new(bytes: &'a [u8]) -> Result<Self, HpkeError> {
if bytes.len() < HPKE_MIN_PSK_LEN {
return Err(HpkeError::InvalidPsk);
}
Ok(Self { bytes })
}
pub fn as_slice(&self) -> &[u8] {
self.bytes
}
}
pub struct HpkePskIdRef<'a> {
bytes: &'a [u8],
}
impl<'a> HpkePskIdRef<'a> {
pub fn new(bytes: &'a [u8]) -> Result<Self, HpkeError> {
if bytes.is_empty() {
return Err(HpkeError::InvalidPskIdentifier);
}
Ok(Self { bytes })
}
pub fn as_slice(&self) -> &[u8] {
self.bytes
}
}
pub struct HpkeSealRequest<'a> {
pub suite: HpkeSuite,
pub recipient_public_key: &'a [u8],
pub info: &'a [u8],
pub aad: &'a [u8],
pub plaintext: &'a [u8],
}
pub struct HpkeOpenRequest<'a> {
pub suite: HpkeSuite,
pub encapsulated_key: &'a [u8],
pub recipient_private_key: &'a [u8],
pub info: &'a [u8],
pub aad: &'a [u8],
pub ciphertext: &'a [u8],
}
pub struct HpkePskSealRequest<'a> {
pub suite: HpkeSuite,
pub recipient_public_key: &'a [u8],
pub info: &'a [u8],
pub aad: &'a [u8],
pub plaintext: &'a [u8],
pub psk: &'a [u8],
pub psk_id: &'a [u8],
}
pub struct HpkePskOpenRequest<'a> {
pub suite: HpkeSuite,
pub encapsulated_key: &'a [u8],
pub recipient_private_key: &'a [u8],
pub info: &'a [u8],
pub aad: &'a [u8],
pub ciphertext: &'a [u8],
pub psk: &'a [u8],
pub psk_id: &'a [u8],
}
pub struct HpkeSenderExportRequest<'a> {
pub suite: HpkeSuite,
pub recipient_public_key: &'a [u8],
pub info: &'a [u8],
pub exporter_context: &'a [u8],
pub output_length: usize,
}
pub struct HpkeReceiverExportRequest<'a> {
pub suite: HpkeSuite,
pub encapsulated_key: &'a [u8],
pub recipient_private_key: &'a [u8],
pub info: &'a [u8],
pub exporter_context: &'a [u8],
pub output_length: usize,
}
pub struct HpkeSealOutput {
pub encapsulated_key: Vec<u8>,
pub ciphertext: Vec<u8>,
}
pub struct HpkeOpenOutput {
pub plaintext: Zeroizing<Vec<u8>>,
}
pub struct HpkeSenderExportOutput {
pub encapsulated_key: Vec<u8>,
exporter_secret: Zeroizing<Vec<u8>>,
}
impl HpkeSenderExportOutput {
#[cfg(feature = "backend-native")]
pub(crate) fn new(encapsulated_key: Vec<u8>, exporter_secret: Zeroizing<Vec<u8>>) -> Self {
Self {
encapsulated_key,
exporter_secret,
}
}
pub fn exporter_secret(&self) -> &[u8] {
self.exporter_secret.as_slice()
}
pub fn into_exporter_secret(mut self) -> Zeroizing<Vec<u8>> {
Zeroizing::new(core::mem::take(&mut *self.exporter_secret))
}
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct HpkeExporterSecret {
bytes: Vec<u8>,
}
impl HpkeExporterSecret {
#[cfg(feature = "backend-native")]
pub(crate) fn new(mut bytes: Zeroizing<Vec<u8>>) -> Self {
Self {
bytes: core::mem::take(&mut *bytes),
}
}
pub fn as_slice(&self) -> &[u8] {
&self.bytes
}
}
pub struct HpkeKeyPair {
pub public_key: Vec<u8>,
private_key: HpkePrivateKeyBytes,
}
impl HpkeKeyPair {
#[cfg(feature = "backend-native")]
pub(crate) fn new(public_key: Vec<u8>, private_key: HpkePrivateKeyBytes) -> Self {
Self {
public_key,
private_key,
}
}
pub fn private_key(&self) -> &[u8] {
self.private_key.as_slice()
}
pub fn into_private_key(self) -> HpkePrivateKeyBytes {
self.private_key
}
}
#[cfg(feature = "test-vectors")]
pub struct HpkeDerandSealRequest<'a> {
pub suite: HpkeSuite,
pub recipient_public_key: &'a [u8],
pub encapsulation_randomness: &'a [u8],
pub info: &'a [u8],
pub aad: &'a [u8],
pub plaintext: &'a [u8],
}
#[cfg(feature = "test-vectors")]
pub struct HpkeDerandSenderExportRequest<'a> {
pub suite: HpkeSuite,
pub recipient_public_key: &'a [u8],
pub encapsulation_randomness: &'a [u8],
pub info: &'a [u8],
pub exporter_context: &'a [u8],
pub output_length: usize,
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct HpkePrivateKeyBytes {
bytes: Vec<u8>,
}
impl HpkePrivateKeyBytes {
pub fn new(bytes: Vec<u8>) -> Self {
Self { bytes }
}
pub fn as_slice(&self) -> &[u8] {
&self.bytes
}
}