use std::marker::PhantomData;
use crate::{
api::AuthenticatedAead,
core::hub::{DecryptData, Kyber, KyberSizeVariant, MlKem1024},
error::CryptError,
markers::{Data, Decryption, XChaCha20Poly1305},
protocol::Envelope,
};
pub struct MissingSecretKey;
pub struct WithSecretKey;
pub struct Decryptor<K = MlKem1024, A = XChaCha20Poly1305>(PhantomData<(K, A)>)
where
K: KyberSizeVariant,
A: AuthenticatedAead;
impl<K, A> Decryptor<K, A>
where
K: KyberSizeVariant,
A: AuthenticatedAead,
{
#[allow(clippy::new_ret_no_self)]
pub fn new() -> DecryptorBuilder<MissingSecretKey, K, A> {
DecryptorBuilder::new()
}
}
pub struct DecryptorBuilder<S, K = MlKem1024, A = XChaCha20Poly1305>
where
K: KyberSizeVariant,
A: AuthenticatedAead,
{
secret_key: Option<Vec<u8>>,
_state: PhantomData<(S, K, A)>,
}
impl<K, A> DecryptorBuilder<MissingSecretKey, K, A>
where
K: KyberSizeVariant,
A: AuthenticatedAead,
{
pub fn new() -> Self {
Self {
secret_key: None,
_state: PhantomData,
}
}
pub fn secret_key(self, secret_key: Vec<u8>) -> DecryptorBuilder<WithSecretKey, K, A> {
DecryptorBuilder {
secret_key: Some(secret_key),
_state: PhantomData,
}
}
}
impl<K, A> DecryptorBuilder<WithSecretKey, K, A>
where
K: KyberSizeVariant,
A: AuthenticatedAead,
Kyber<Decryption, K, Data, A>: DecryptData,
{
pub fn open(self, envelope: &Envelope) -> Result<Vec<u8>, CryptError> {
let secret_key = self.secret_key.ok_or(CryptError::MissingSecretKey)?;
let kyber = Kyber::<Decryption, K, Data, A>::new(secret_key, None)?;
kyber.decrypt_data(&envelope.ciphertext, "", envelope)
}
}
impl<K, A> Default for DecryptorBuilder<MissingSecretKey, K, A>
where
K: KyberSizeVariant,
A: AuthenticatedAead,
{
fn default() -> Self {
Self::new()
}
}