use super::encrypt_digest;
use crate::{traits::RandomizedEncryptor, Result, RsaPublicKey};
use core::marker::PhantomData;
use digest::{Digest, FixedOutputReset};
use rand_core::CryptoRngCore;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::oaep::Label;
use crate::traits::UnsignedModularInt;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct EncryptingKey<T, D, MGD = D>
where
D: Digest,
MGD: Digest + FixedOutputReset,
T: UnsignedModularInt,
{
inner: RsaPublicKey<T>,
label: Option<Label>, phantom: PhantomData<D>,
mg_phantom: PhantomData<MGD>,
}
impl<T, D, MGD> EncryptingKey<T, D, MGD>
where
D: Digest,
MGD: Digest + FixedOutputReset,
T: UnsignedModularInt,
{
pub fn new(key: RsaPublicKey<T>) -> Self {
Self {
inner: key,
label: None,
phantom: Default::default(),
mg_phantom: Default::default(),
}
}
pub fn new_with_label<S: AsRef<str>>(key: RsaPublicKey<T>, label: S) -> Self {
Self {
inner: key,
label: None,
phantom: Default::default(),
mg_phantom: Default::default(),
}
}
}
impl<T, D, MGD> RandomizedEncryptor for EncryptingKey<T, D, MGD>
where
D: Digest,
MGD: Digest + FixedOutputReset,
T: UnsignedModularInt,
{
fn encrypt_with_rng<'a, R: CryptoRngCore + ?Sized>(
&self,
rng: &mut R,
msg: &[u8],
storage: &'a mut [u8],
) -> Result<&'a [u8]> {
encrypt_digest::<T, _, D, MGD>(rng, &self.inner, msg, self.label.as_ref().cloned(), storage)
}
}
impl<T, D, MGD> PartialEq for EncryptingKey<T, D, MGD>
where
D: Digest,
MGD: Digest + FixedOutputReset,
T: UnsignedModularInt,
{
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner && self.label == other.label
}
}
#[cfg(test)]
mod tests {
#[test]
#[cfg(feature = "serde")]
fn test_serde() {
use super::*;
use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
use serde_test::{assert_tokens, Configure, Token};
let mut rng = ChaCha8Rng::from_seed([42; 32]);
}
}