#[cfg(feature = "asymmetric-key-agreement")]
use crate::algorithms::asymmetric::key_agreement::KeyAgreementAlgorithm;
use crate::algorithms::hash::HashAlgorithm;
#[cfg(feature = "asymmetric-key-agreement")]
use crate::keys::asymmetric::key_agreement::{
TypedKeyAgreementKeyPair, TypedKeyAgreementPrivateKey, TypedKeyAgreementPublicKey,
};
#[cfg(feature = "asymmetric-signature")]
use crate::keys::asymmetric::signature::{
TypedSignatureKeyPair, TypedSignaturePrivateKey, TypedSignaturePublicKey,
};
#[cfg(feature = "asymmetric-signature")]
use crate::{
algorithms::asymmetric::signature::SignatureAlgorithm,
wrappers::asymmetric::signature::SignatureWrapper,
};
#[cfg(feature = "aead")]
use {
crate::algorithms::aead::AeadAlgorithm,
crate::keys::aead::{AeadKey as UntypedAeadKey, TypedAeadKey},
};
#[cfg(feature = "asymmetric-kem")]
use {
crate::algorithms::asymmetric::kem::KemAlgorithm,
crate::keys::asymmetric::kem::{
EncapsulatedKey, SharedSecret, TypedKemKeyPair, TypedKemPrivateKey, TypedKemPublicKey,
},
};
#[cfg(feature = "kdf")]
use {
crate::algorithms::kdf::key::KdfKeyAlgorithm,
crate::algorithms::kdf::passwd::KdfPasswordAlgorithm,
seal_crypto::secrecy::SecretBox,
};
#[cfg(feature = "xof")]
use {crate::algorithms::xof::XofAlgorithm, crate::wrappers::xof::XofReaderWrapper};
#[cfg(any(
feature = "kdf",
feature = "asymmetric-key-agreement"
))]
use seal_crypto::zeroize::Zeroizing;
use crate::error::Result;
#[allow(unused_macros)]
macro_rules! impl_trait_for_box {
(
@impl,
$trait:ident,
$clone_box_name:ident,
{ }, // no more methods
{ $($impls:tt)* } // accumulated impls
) => {
impl Clone for Box<dyn $trait> {
fn clone(&self) -> Self {
self.$clone_box_name()
}
}
impl $trait for Box<dyn $trait> {
$($impls)*
}
};
(
@impl,
$trait:ident,
$clone_box_name:ident,
{
ref fn $method:ident< $($lt:lifetime),+ >(&self, $($arg:ident: $ty:ty),*) -> $ret:ty;
$($rest:tt)*
},
{ $($impls:tt)* }
) => {
impl_trait_for_box! {
@impl,
$trait,
$clone_box_name,
{ $($rest)* },
{
$($impls)*
fn $method< $($lt),+ >(&self, $($arg: $ty),*) -> $ret {
self.as_ref().$method($($arg),*)
}
}
}
};
(
@impl,
$trait:ident,
$clone_box_name:ident,
{
ref fn $method:ident(&self, $($arg:ident: $ty:ty),*) -> $ret:ty;
$($rest:tt)*
},
{ $($impls:tt)* }
) => {
impl_trait_for_box! {
@impl,
$trait,
$clone_box_name,
{ $($rest)* },
{
$($impls)*
fn $method(&self, $($arg: $ty),*) -> $ret {
self.as_ref().$method($($arg),*)
}
}
}
};
(
@impl,
$trait:ident,
$clone_box_name:ident,
{
self fn $method:ident(self, $($arg:ident: $ty:ty),*) -> $ret:ty { $($body:tt)+ };
$($rest:tt)*
},
{ $($impls:tt)* }
) => {
impl_trait_for_box! {
@impl,
$trait,
$clone_box_name,
{ $($rest)* },
{
$($impls)*
fn $method(self, $($arg: $ty),*) -> $ret {
$($body)+
}
}
}
};
(
@impl,
$trait:ident,
$clone_box_name:ident,
{
self fn $method:ident(self, $($arg:ident: $ty:ty),*) -> $ret:ty;
$($rest:tt)*
},
{ $($impls:tt)* }
) => {
impl_trait_for_box! {
@impl,
$trait,
$clone_box_name,
{ $($rest)* },
{
$($impls)*
fn $method(self, $($arg: $ty),*) -> $ret {
self
}
}
}
};
($trait:ident { $($methods:tt)* }, $clone_box_name:ident) => {
impl_trait_for_box! {
@impl,
$trait,
$clone_box_name,
{ $($methods)* },
{ }
}
};
}
#[cfg(feature = "aead")]
pub trait AeadAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn encrypt(
&self,
plaintext: &[u8],
key: &TypedAeadKey,
nonce: &[u8],
aad: Option<&[u8]>,
) -> Result<Vec<u8>>;
fn encrypt_to_buffer(
&self,
plaintext: &[u8],
output: &mut [u8],
key: &TypedAeadKey,
nonce: &[u8],
aad: Option<&[u8]>,
) -> Result<usize>;
fn decrypt(
&self,
ciphertext: &[u8],
key: &TypedAeadKey,
nonce: &[u8],
aad: Option<&[u8]>,
) -> Result<Vec<u8>>;
fn decrypt_to_buffer(
&self,
ciphertext: &[u8],
output: &mut [u8],
key: &TypedAeadKey,
nonce: &[u8],
aad: Option<&[u8]>,
) -> Result<usize>;
fn generate_typed_key(&self) -> Result<TypedAeadKey>;
fn generate_untyped_key(&self) -> Result<UntypedAeadKey>;
fn algorithm(&self) -> AeadAlgorithm;
fn key_size(&self) -> usize;
fn nonce_size(&self) -> usize;
fn tag_size(&self) -> usize;
fn into_boxed(self) -> Box<dyn AeadAlgorithmTrait>;
fn clone_box(&self) -> Box<dyn AeadAlgorithmTrait>;
}
#[cfg(feature = "aead")]
impl_trait_for_box!(AeadAlgorithmTrait {
ref fn encrypt(&self, plaintext: &[u8], key: &TypedAeadKey, nonce: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>;
ref fn encrypt_to_buffer(&self, plaintext: &[u8], output: &mut [u8], key: &TypedAeadKey, nonce: &[u8], aad: Option<&[u8]>) -> Result<usize>;
ref fn decrypt(&self, ciphertext: &[u8], key: &TypedAeadKey, nonce: &[u8], aad: Option<&[u8]>) -> Result<Vec<u8>>;
ref fn decrypt_to_buffer(&self, ciphertext: &[u8], output: &mut [u8], key: &TypedAeadKey, nonce: &[u8], aad: Option<&[u8]>) -> Result<usize>;
ref fn generate_typed_key(&self,) -> Result<TypedAeadKey>;
ref fn generate_untyped_key(&self,) -> Result<UntypedAeadKey>;
ref fn algorithm(&self,) -> AeadAlgorithm;
ref fn key_size(&self,) -> usize;
ref fn nonce_size(&self,) -> usize;
ref fn tag_size(&self,) -> usize;
self fn into_boxed(self,) -> Box<dyn AeadAlgorithmTrait>;
ref fn clone_box(&self,) -> Box<dyn AeadAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "asymmetric-kem")]
pub trait KemAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn algorithm(&self) -> KemAlgorithm;
fn encapsulate_key(
&self,
public_key: &TypedKemPublicKey,
) -> Result<(SharedSecret, EncapsulatedKey)>;
fn decapsulate_key(
&self,
private_key: &TypedKemPrivateKey,
encapsulated_key: &EncapsulatedKey,
) -> Result<SharedSecret>;
fn generate_keypair(&self) -> Result<TypedKemKeyPair>;
fn clone_box(&self) -> Box<dyn KemAlgorithmTrait>;
fn into_boxed(self) -> Box<dyn KemAlgorithmTrait>;
}
#[cfg(feature = "asymmetric-kem")]
impl_trait_for_box!(KemAlgorithmTrait {
ref fn clone_box(&self,) -> Box<dyn KemAlgorithmTrait>;
ref fn algorithm(&self,) -> KemAlgorithm;
ref fn encapsulate_key(&self, public_key: &TypedKemPublicKey) -> Result<(SharedSecret, EncapsulatedKey)>;
ref fn decapsulate_key(&self, private_key: &TypedKemPrivateKey, encapsulated_key: &EncapsulatedKey) -> Result<SharedSecret>;
ref fn generate_keypair(&self,) -> Result<TypedKemKeyPair>;
self fn into_boxed(self,) -> Box<dyn KemAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "kdf")]
pub trait KdfKeyAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn derive(
&self,
ikm: &[u8],
salt: Option<&[u8]>,
info: Option<&[u8]>,
output_len: usize,
) -> Result<Zeroizing<Vec<u8>>>;
fn algorithm(&self) -> KdfKeyAlgorithm;
fn clone_box(&self) -> Box<dyn KdfKeyAlgorithmTrait>;
fn into_boxed(self) -> Box<dyn KdfKeyAlgorithmTrait>;
}
#[cfg(feature = "kdf")]
impl_trait_for_box!(KdfKeyAlgorithmTrait {
ref fn clone_box(&self,) -> Box<dyn KdfKeyAlgorithmTrait>;
ref fn derive(&self, ikm: &[u8], salt: Option<&[u8]>, info: Option<&[u8]>, output_len: usize) -> Result<Zeroizing<Vec<u8>>>;
ref fn algorithm(&self,) -> KdfKeyAlgorithm;
self fn into_boxed(self,) -> Box<dyn KdfKeyAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "kdf")]
pub trait KdfPasswordAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn derive(
&self,
password: &SecretBox<[u8]>,
salt: &[u8],
output_len: usize,
) -> Result<Zeroizing<Vec<u8>>>;
fn algorithm(&self) -> KdfPasswordAlgorithm;
fn clone_box(&self) -> Box<dyn KdfPasswordAlgorithmTrait>;
fn into_boxed(self) -> Box<dyn KdfPasswordAlgorithmTrait>;
}
#[cfg(feature = "kdf")]
impl_trait_for_box!(KdfPasswordAlgorithmTrait {
ref fn clone_box(&self,) -> Box<dyn KdfPasswordAlgorithmTrait>;
ref fn derive(&self, password: &SecretBox<[u8]>, salt: &[u8], output_len: usize) -> Result<Zeroizing<Vec<u8>>>;
ref fn algorithm(&self,) -> KdfPasswordAlgorithm;
self fn into_boxed(self,) -> Box<dyn KdfPasswordAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "xof")]
pub trait XofAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn reader<'a>(
&self,
ikm: &'a [u8],
salt: Option<&'a [u8]>,
info: Option<&'a [u8]>,
) -> Result<XofReaderWrapper<'a>>;
fn clone_box(&self) -> Box<dyn XofAlgorithmTrait>;
fn algorithm(&self) -> XofAlgorithm;
fn into_boxed(self) -> Box<dyn XofAlgorithmTrait>;
}
#[cfg(feature = "xof")]
impl_trait_for_box!(XofAlgorithmTrait {
ref fn reader<'a>(&self, ikm: &'a [u8], salt: Option<&'a [u8]>, info: Option<&'a [u8]>) -> Result<XofReaderWrapper<'a>>;
ref fn algorithm(&self,) -> XofAlgorithm;
ref fn clone_box(&self,) -> Box<dyn XofAlgorithmTrait>;
self fn into_boxed(self,) -> Box<dyn XofAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "asymmetric-signature")]
pub trait SignatureAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn sign(&self, message: &[u8], key: &TypedSignaturePrivateKey) -> Result<SignatureWrapper>;
fn verify(
&self,
message: &[u8],
key: &TypedSignaturePublicKey,
signature: &SignatureWrapper,
) -> Result<()>;
fn generate_keypair(&self) -> Result<TypedSignatureKeyPair>;
fn clone_box(&self) -> Box<dyn SignatureAlgorithmTrait>;
fn algorithm(&self) -> SignatureAlgorithm;
fn into_boxed(self) -> Box<dyn SignatureAlgorithmTrait>;
}
#[cfg(feature = "asymmetric-signature")]
impl_trait_for_box!(SignatureAlgorithmTrait {
ref fn sign(&self, message: &[u8], key: &TypedSignaturePrivateKey) -> Result<SignatureWrapper>;
ref fn verify(&self, message: &[u8], key: &TypedSignaturePublicKey, signature: &SignatureWrapper) -> Result<()>;
ref fn generate_keypair(&self,) -> Result<TypedSignatureKeyPair>;
ref fn clone_box(&self,) -> Box<dyn SignatureAlgorithmTrait>;
ref fn algorithm(&self,) -> SignatureAlgorithm;
self fn into_boxed(self,) -> Box<dyn SignatureAlgorithmTrait>;
}, clone_box);
#[cfg(feature = "asymmetric-key-agreement")]
pub trait KeyAgreementAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn agree(
&self,
sk: &TypedKeyAgreementPrivateKey,
pk: &TypedKeyAgreementPublicKey,
) -> Result<Zeroizing<Vec<u8>>>;
fn generate_keypair(&self) -> Result<TypedKeyAgreementKeyPair>;
fn clone_box(&self) -> Box<dyn KeyAgreementAlgorithmTrait>;
fn algorithm(&self) -> KeyAgreementAlgorithm;
fn into_boxed(self) -> Box<dyn KeyAgreementAlgorithmTrait>;
}
#[cfg(feature = "asymmetric-key-agreement")]
impl_trait_for_box!(KeyAgreementAlgorithmTrait {
ref fn agree(&self, sk: &TypedKeyAgreementPrivateKey, pk: &TypedKeyAgreementPublicKey) -> Result<Zeroizing<Vec<u8>>>;
ref fn generate_keypair(&self,) -> Result<TypedKeyAgreementKeyPair>;
ref fn clone_box(&self,) -> Box<dyn KeyAgreementAlgorithmTrait>;
ref fn algorithm(&self,) -> KeyAgreementAlgorithm;
self fn into_boxed(self,) -> Box<dyn KeyAgreementAlgorithmTrait>;
}, clone_box);
pub trait HashAlgorithmTrait: Send + Sync + 'static + std::fmt::Debug {
fn hash(&self, data: &[u8]) -> Vec<u8>;
fn hmac(&self, key: &[u8], msg: &[u8]) -> Result<Vec<u8>>;
fn algorithm(&self) -> HashAlgorithm;
fn clone_box(&self) -> Box<dyn HashAlgorithmTrait>;
fn into_boxed(self) -> Box<dyn HashAlgorithmTrait>;
}
impl_trait_for_box!(HashAlgorithmTrait {
ref fn hash(&self, data: &[u8]) -> Vec<u8>;
ref fn hmac(&self, key: &[u8], msg: &[u8]) -> Result<Vec<u8>>;
ref fn algorithm(&self,) -> HashAlgorithm;
ref fn clone_box(&self,) -> Box<dyn HashAlgorithmTrait>;
self fn into_boxed(self,) -> Box<dyn HashAlgorithmTrait>;
}, clone_box);