rsa/oaep/
encrypting_key.rs1use super::encrypt_digest;
2use crate::{traits::RandomizedEncryptor, Result, RsaPublicKey};
3use alloc::{boxed::Box, vec::Vec};
4use core::marker::PhantomData;
5use digest::{Digest, FixedOutputReset};
6use rand_core::CryptoRng;
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15pub struct EncryptingKey<D, MGD = D>
16where
17 D: Digest,
18 MGD: Digest + FixedOutputReset,
19{
20 inner: RsaPublicKey,
21 label: Option<Box<[u8]>>,
22 phantom: PhantomData<D>,
23 mg_phantom: PhantomData<MGD>,
24}
25
26impl<D, MGD> EncryptingKey<D, MGD>
27where
28 D: Digest,
29 MGD: Digest + FixedOutputReset,
30{
31 pub fn new(key: RsaPublicKey) -> Self {
33 Self {
34 inner: key,
35 label: None,
36 phantom: Default::default(),
37 mg_phantom: Default::default(),
38 }
39 }
40
41 pub fn new_with_label<S: Into<Box<[u8]>>>(key: RsaPublicKey, label: S) -> Self {
43 Self {
44 inner: key,
45 label: Some(label.into()),
46 phantom: Default::default(),
47 mg_phantom: Default::default(),
48 }
49 }
50}
51
52impl<D, MGD> RandomizedEncryptor for EncryptingKey<D, MGD>
53where
54 D: Digest,
55 MGD: Digest + FixedOutputReset,
56{
57 fn encrypt_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> Result<Vec<u8>> {
58 encrypt_digest::<_, D, MGD>(rng, &self.inner, msg, self.label.clone())
59 }
60}
61
62impl<D, MGD> PartialEq for EncryptingKey<D, MGD>
63where
64 D: Digest,
65 MGD: Digest + FixedOutputReset,
66{
67 fn eq(&self, other: &Self) -> bool {
68 self.inner == other.inner && self.label == other.label
69 }
70}
71
72#[cfg(test)]
73mod tests {
74
75 #[test]
76 #[cfg(all(feature = "hazmat", feature = "serde"))]
77 fn test_serde() {
78 use super::*;
79 use rand::rngs::ChaCha8Rng;
80 use rand_core::SeedableRng;
81 use serde_test::{assert_tokens, Configure, Token};
82
83 let mut rng = ChaCha8Rng::from_seed([42; 32]);
84 let priv_key =
85 crate::RsaPrivateKey::new_unchecked(&mut rng, 64).expect("failed to generate key");
86 let encrypting_key = EncryptingKey::<sha2::Sha256>::new(priv_key.to_public_key());
87
88 let tokens = [
89 Token::Struct {
90 name: "EncryptingKey",
91 len: 4,
92 },
93 Token::Str("inner"),
94 Token::Str(
95 "3024300d06092a864886f70d01010105000313003010020900ab240c3361d02e370203010001",
96 ),
97 Token::Str("label"),
98 Token::None,
99 Token::Str("phantom"),
100 Token::UnitStruct {
101 name: "PhantomData",
102 },
103 Token::Str("mg_phantom"),
104 Token::UnitStruct {
105 name: "PhantomData",
106 },
107 Token::StructEnd,
108 ];
109 assert_tokens(&encrypting_key.readable(), &tokens);
110 }
111}