devolutions_crypto/ciphertext/
mod.rs

1//! Module for symmetric/asymmetric encryption/decryption.
2//!
3//! This module contains everything related to encryption. You can use it to encrypt and decrypt data using either a shared key of a keypair.
4//! Either way, the encryption will give you a `Ciphertext`, which has a method to decrypt it.
5//!
6//! ### Symmetric
7//!
8//! ```rust
9//! use devolutions_crypto::utils::generate_key;
10//! use devolutions_crypto::ciphertext::{ encrypt, CiphertextVersion, Ciphertext };
11//!
12//! let key: Vec<u8> = generate_key(32);
13//!
14//! let data = b"somesecretdata";
15//!
16//! let encrypted_data: Ciphertext = encrypt(data, &key, CiphertextVersion::Latest).expect("encryption shouldn't fail");
17//!
18//! let decrypted_data = encrypted_data.decrypt(&key).expect("The decryption shouldn't fail");
19//!
20//! assert_eq!(decrypted_data, data);
21//! ```
22//!
23//! ### Asymmetric
24//! Here, you will need a `PublicKey` to encrypt data and the corresponding
25//! `PrivateKey` to decrypt it. You can generate them by using `generate_keypair`
26//! in the [Key module](#key).
27//!
28//! ```rust
29//! use devolutions_crypto::key::{generate_keypair, KeyVersion, KeyPair};
30//! use devolutions_crypto::ciphertext::{ encrypt_asymmetric, CiphertextVersion, Ciphertext };
31//!
32//! let keypair: KeyPair = generate_keypair(KeyVersion::Latest);
33//!
34//! let data = b"somesecretdata";
35//!
36//! let encrypted_data: Ciphertext = encrypt_asymmetric(data, &keypair.public_key, CiphertextVersion::Latest).expect("encryption shouldn't fail");
37//!
38//! let decrypted_data = encrypted_data.decrypt_asymmetric(&keypair.private_key).expect("The decryption shouldn't fail");
39//!
40//! assert_eq!(decrypted_data, data);
41//! ```
42
43mod ciphertext_v1;
44mod ciphertext_v2;
45
46use super::CiphertextSubtype;
47pub use super::CiphertextVersion;
48use super::DataType;
49use super::Error;
50use super::Header;
51use super::HeaderType;
52use super::Result;
53
54use super::key::{PrivateKey, PublicKey};
55
56use ciphertext_v1::CiphertextV1;
57use ciphertext_v2::{CiphertextV2Asymmetric, CiphertextV2Symmetric};
58
59use std::borrow::Borrow;
60use std::convert::TryFrom;
61
62#[cfg(feature = "fuzz")]
63use arbitrary::Arbitrary;
64
65/// A versionned ciphertext. Can be either symmetric or asymmetric.
66#[derive(Clone, Debug)]
67#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
68pub struct Ciphertext {
69    pub(crate) header: Header<Ciphertext>,
70    payload: CiphertextPayload,
71}
72
73impl HeaderType for Ciphertext {
74    type Version = CiphertextVersion;
75    type Subtype = CiphertextSubtype;
76
77    fn data_type() -> DataType {
78        DataType::Ciphertext
79    }
80}
81
82#[derive(Clone, Debug)]
83#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
84enum CiphertextPayload {
85    V1(CiphertextV1),
86    V2Symmetric(CiphertextV2Symmetric),
87    V2Asymmetric(CiphertextV2Asymmetric),
88}
89
90/// Returns an `Ciphertext` from cleartext data and a key.
91/// # Arguments
92///  * `data` - The data to encrypt.
93///  * `key` - The key to use. The recommended size is 32 bytes.
94///  * `version` - Version of the library to encrypt with. Use `CiphertTextVersion::Latest` if you're not dealing with shared data.
95/// # Returns
96/// Returns a `Ciphertext` containing the encrypted data.
97/// # Example
98/// ```rust
99/// use devolutions_crypto::ciphertext::{ encrypt, CiphertextVersion };
100///
101/// let data = b"somesecretdata";
102/// let key = b"somesecretkey";
103///
104/// let encrypted_data = encrypt(data, key, CiphertextVersion::Latest).unwrap();
105/// ```
106pub fn encrypt(data: &[u8], key: &[u8], version: CiphertextVersion) -> Result<Ciphertext> {
107    encrypt_with_aad(data, key, [].as_slice(), version)
108}
109
110/// Returns an `Ciphertext` from cleartext data and a key.
111/// # Arguments
112///  * `data` - The data to encrypt.
113///  * `key` - The key to use. The recommended size is 32 bytes.
114///  * `aad` - Additionnal data to authenticate alongside the ciphertext.
115///  * `version` - Version of the library to encrypt with. Use `CiphertTextVersion::Latest` if you're not dealing with shared data.
116/// # Returns
117/// Returns a `Ciphertext` containing the encrypted data, which also authenticates the `aad` argument.
118/// # Example
119/// ```rust
120/// use devolutions_crypto::ciphertext::{ encrypt_with_aad, CiphertextVersion };
121///
122/// let data = b"somesecretdata";
123/// let key = b"somesecretkey";
124/// let aad = b"somepublicdata";
125///
126/// let encrypted_data = encrypt_with_aad(data, key, aad, CiphertextVersion::Latest).unwrap();
127/// ```
128pub fn encrypt_with_aad(
129    data: &[u8],
130    key: &[u8],
131    aad: &[u8],
132    version: CiphertextVersion,
133) -> Result<Ciphertext> {
134    let mut header = Header::default();
135
136    header.data_subtype = CiphertextSubtype::Symmetric;
137
138    let payload = match version {
139        CiphertextVersion::V1 => {
140            header.version = CiphertextVersion::V1;
141            CiphertextPayload::V1(CiphertextV1::encrypt(data, key, aad, &header)?)
142        }
143        CiphertextVersion::V2 | CiphertextVersion::Latest => {
144            header.version = CiphertextVersion::V2;
145            CiphertextPayload::V2Symmetric(CiphertextV2Symmetric::encrypt(data, key, aad, &header)?)
146        } //_ => return Err(DevoCryptoError::UnknownVersion),
147    };
148
149    Ok(Ciphertext { header, payload })
150}
151
152/// Returns an `Ciphertext` from cleartext data and a `PublicKey`.
153/// You will need the corresponding `PrivateKey` to decrypt it.
154/// # Arguments
155///  * `data` - The data to encrypt.
156///  * `public_key` - The `PublicKey` to use. Use `generate_keypair` to generate a keypair.
157///  * `version` - Version of the library to encrypt with. Use `CiphertTextVersion::Latest` if you're not dealing with shared data.
158/// # Returns
159/// Returns a `Ciphertext` containing the encrypted data.
160/// # Example
161/// ```rust
162/// use devolutions_crypto::ciphertext::{ encrypt_asymmetric, CiphertextVersion };
163/// use devolutions_crypto::key::{ generate_keypair, KeyVersion };
164///
165/// let data = b"somesecretdata";
166/// let keypair = generate_keypair(KeyVersion::Latest);
167///
168/// let encrypted_data = encrypt_asymmetric(data, &keypair.public_key, CiphertextVersion::Latest).unwrap();
169/// ```
170pub fn encrypt_asymmetric(
171    data: &[u8],
172    public_key: &PublicKey,
173    version: CiphertextVersion,
174) -> Result<Ciphertext> {
175    encrypt_asymmetric_with_aad(data, public_key, [].as_slice(), version)
176}
177
178/// Returns an `Ciphertext` from cleartext data and a `PublicKey`.
179/// You will need the corresponding `PrivateKey` to decrypt it.
180/// # Arguments
181///  * `data` - The data to encrypt.
182///  * `public_key` - The `PublicKey` to use. Use `generate_keypair` to generate a keypair.
183///  * `aad` - Additionnal data to authenticate alongside the ciphertext.
184///  * `version` - Version of the library to encrypt with. Use `CiphertTextVersion::Latest` if you're not dealing with shared data.
185/// # Returns
186/// Returns a `Ciphertext` containing the encrypted data.
187/// # Example
188/// ```rust
189/// use devolutions_crypto::ciphertext::{ encrypt_asymmetric_with_aad, CiphertextVersion };
190/// use devolutions_crypto::key::{ generate_keypair, KeyVersion };
191///
192/// let data = b"somesecretdata";
193/// let aad = b"somepublicdata";
194/// let keypair = generate_keypair(KeyVersion::Latest);
195///
196/// let encrypted_data = encrypt_asymmetric_with_aad(data, &keypair.public_key, aad, CiphertextVersion::Latest).unwrap();
197/// ```
198pub fn encrypt_asymmetric_with_aad(
199    data: &[u8],
200    public_key: &PublicKey,
201    aad: &[u8],
202    version: CiphertextVersion,
203) -> Result<Ciphertext> {
204    let mut header = Header::default();
205
206    header.data_subtype = CiphertextSubtype::Asymmetric;
207
208    let payload = match version {
209        CiphertextVersion::V2 | CiphertextVersion::Latest => {
210            header.version = CiphertextVersion::V2;
211            CiphertextPayload::V2Asymmetric(CiphertextV2Asymmetric::encrypt(
212                data, public_key, aad, &header,
213            )?)
214        }
215        _ => return Err(Error::UnknownVersion),
216    };
217
218    Ok(Ciphertext { header, payload })
219}
220
221impl Ciphertext {
222    /// Decrypt the data blob using a key.
223    /// # Arguments
224    ///  * `key` - Key to use. The recommended size is 32 bytes.
225    /// # Returns
226    /// Returns the decrypted data.
227    /// # Example
228    /// ```rust
229    /// use devolutions_crypto::ciphertext::{ encrypt, CiphertextVersion};
230    ///
231    /// let data = b"somesecretdata";
232    /// let key = b"somesecretkey";
233    ///
234    /// let encrypted_data = encrypt(data, key, CiphertextVersion::Latest).unwrap();
235    /// let decrypted_data = encrypted_data.decrypt(key).unwrap();
236    ///
237    /// assert_eq!(data.to_vec(), decrypted_data);
238    ///```
239    pub fn decrypt(&self, key: &[u8]) -> Result<Vec<u8>> {
240        self.decrypt_with_aad(key, [].as_slice())
241    }
242
243    /// Decrypt the data blob using a key.
244    /// # Arguments
245    ///  * `key` - Key to use. The recommended size is 32 bytes.
246    ///  * `aad` - Additionnal data to authenticate alongside the ciphertext.
247    /// # Returns
248    /// Returns the decrypted data.
249    /// # Example
250    /// ```rust
251    /// use devolutions_crypto::ciphertext::{ encrypt_with_aad, CiphertextVersion};
252    ///
253    /// let data = b"somesecretdata";
254    /// let key = b"somesecretkey";
255    /// let aad = b"somepublicdata";
256    ///
257    /// let encrypted_data = encrypt_with_aad(data, key, aad, CiphertextVersion::Latest).unwrap();
258    /// let decrypted_data = encrypted_data.decrypt_with_aad(key, aad).unwrap();
259    ///
260    /// assert_eq!(data.to_vec(), decrypted_data);
261    ///```
262    pub fn decrypt_with_aad(&self, key: &[u8], aad: &[u8]) -> Result<Vec<u8>> {
263        match &self.payload {
264            CiphertextPayload::V1(x) => x.decrypt(key, aad, &self.header),
265            CiphertextPayload::V2Symmetric(x) => x.decrypt(key, aad, &self.header),
266            _ => Err(Error::InvalidDataType),
267        }
268    }
269
270    /// Decrypt the data blob using a `PrivateKey`.
271    /// # Arguments
272    ///  * `private_key` - Key to use. Must be the one in the same keypair as the `PublicKey` used for encryption.
273    /// # Returns
274    /// Returns the decrypted data.
275    /// # Example
276    /// ```rust
277    /// use devolutions_crypto::ciphertext::{ encrypt_asymmetric, CiphertextVersion };
278    /// use devolutions_crypto::key::{ generate_keypair, KeyVersion };
279    ///
280    /// let data = b"somesecretdata";
281    /// let keypair = generate_keypair(KeyVersion::Latest);
282    ///
283    /// let encrypted_data = encrypt_asymmetric(data, &keypair.public_key, CiphertextVersion::Latest).unwrap();
284    /// let decrypted_data = encrypted_data.decrypt_asymmetric(&keypair.private_key).unwrap();
285    ///
286    /// assert_eq!(decrypted_data, data);
287    ///```
288    pub fn decrypt_asymmetric(&self, private_key: &PrivateKey) -> Result<Vec<u8>> {
289        self.decrypt_asymmetric_with_aad(private_key, [].as_slice())
290    }
291
292    /// Decrypt the data blob using a `PrivateKey`.
293    /// # Arguments
294    ///  * `private_key` - Key to use. Must be the one in the same keypair as the `PublicKey` used for encryption.
295    ///  * `aad` - Additionnal data to authenticate alongside the ciphertext.
296    /// # Returns
297    /// Returns the decrypted data.
298    /// # Example
299    /// ```rust
300    /// use devolutions_crypto::ciphertext::{ encrypt_asymmetric_with_aad, CiphertextVersion };
301    /// use devolutions_crypto::key::{ generate_keypair, KeyVersion };
302    ///
303    /// let data = b"somesecretdata";
304    /// let keypair = generate_keypair(KeyVersion::Latest);
305    /// let aad = b"somepublicdata";
306    ///
307    /// let encrypted_data = encrypt_asymmetric_with_aad(data, &keypair.public_key, aad, CiphertextVersion::Latest).unwrap();
308    /// let decrypted_data = encrypted_data.decrypt_asymmetric_with_aad(&keypair.private_key, aad).unwrap();
309    ///
310    /// assert_eq!(decrypted_data, data);
311    ///```
312    pub fn decrypt_asymmetric_with_aad(
313        &self,
314        private_key: &PrivateKey,
315        aad: &[u8],
316    ) -> Result<Vec<u8>> {
317        match &self.payload {
318            CiphertextPayload::V2Asymmetric(x) => x.decrypt(private_key, aad, &self.header),
319            CiphertextPayload::V1(_) => Err(Error::UnknownVersion),
320            _ => Err(Error::InvalidDataType),
321        }
322    }
323}
324
325impl From<Ciphertext> for Vec<u8> {
326    /// Serialize the structure into a `Vec<u8>`, for storage, transmission or use in another language.
327    fn from(data: Ciphertext) -> Self {
328        let mut header: Self = data.header.borrow().into();
329        let mut payload: Self = data.payload.into();
330        header.append(&mut payload);
331        header
332    }
333}
334
335impl TryFrom<&[u8]> for Ciphertext {
336    type Error = Error;
337
338    /// Parses the data. Can return an Error of the data is invalid or unrecognized.
339    fn try_from(data: &[u8]) -> Result<Self> {
340        if data.len() < Header::len() {
341            return Err(Error::InvalidLength);
342        };
343
344        let header = Header::try_from(&data[0..Header::len()])?;
345
346        let payload = match header.version {
347            CiphertextVersion::V1 => {
348                CiphertextPayload::V1(CiphertextV1::try_from(&data[Header::len()..])?)
349            }
350            CiphertextVersion::V2 => match header.data_subtype {
351                CiphertextSubtype::Symmetric | CiphertextSubtype::None => {
352                    CiphertextPayload::V2Symmetric(CiphertextV2Symmetric::try_from(
353                        &data[Header::len()..],
354                    )?)
355                }
356                CiphertextSubtype::Asymmetric => CiphertextPayload::V2Asymmetric(
357                    CiphertextV2Asymmetric::try_from(&data[Header::len()..])?,
358                ),
359            },
360            _ => return Err(Error::UnknownVersion),
361        };
362
363        Ok(Self { header, payload })
364    }
365}
366
367impl From<CiphertextPayload> for Vec<u8> {
368    fn from(data: CiphertextPayload) -> Self {
369        match data {
370            CiphertextPayload::V1(x) => x.into(),
371            CiphertextPayload::V2Symmetric(x) => x.into(),
372            CiphertextPayload::V2Asymmetric(x) => x.into(),
373        }
374    }
375}
376
377#[test]
378fn encrypt_decrypt_test() {
379    let key = "0123456789abcdefghijkl".as_bytes();
380    let data = "This is a very complex string of character that we need to encrypt".as_bytes();
381
382    let encrypted = encrypt(data, key, CiphertextVersion::Latest).unwrap();
383
384    let encrypted: Vec<u8> = encrypted.into();
385
386    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
387    let decrypted = encrypted.decrypt(key).unwrap();
388
389    assert_eq!(decrypted, data);
390}
391
392#[test]
393fn encrypt_decrypt_aad_test() {
394    let key = b"0123456789abcdefghijkl";
395    let data = b"This is a very complex string of character that we need to encrypt";
396    let aad = b"This is some public data that we want to authenticate";
397    let wrong_aad = b"this is some public data that we want to authenticate";
398
399    let encrypted = encrypt_with_aad(data, key, aad, CiphertextVersion::Latest).unwrap();
400
401    let encrypted: Vec<u8> = encrypted.into();
402
403    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
404    let decrypted = encrypted.decrypt_with_aad(key, aad).unwrap();
405
406    assert_eq!(decrypted, data);
407
408    let decrypted = encrypted.decrypt_with_aad(key, wrong_aad);
409
410    assert!(decrypted.is_err());
411
412    let decrypted = encrypted.decrypt(key);
413
414    assert!(decrypted.is_err());
415}
416
417#[test]
418fn encrypt_decrypt_v1_test() {
419    let key = "0123456789abcdefghijkl".as_bytes();
420    let data = "This is a very complex string of character that we need to encrypt".as_bytes();
421
422    let encrypted = encrypt(data, key, CiphertextVersion::V1).unwrap();
423
424    assert_eq!(encrypted.header.version, CiphertextVersion::V1);
425    let encrypted: Vec<u8> = encrypted.into();
426
427    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
428    let decrypted = encrypted.decrypt(key).unwrap();
429
430    assert_eq!(decrypted, data);
431}
432
433#[test]
434fn encrypt_decrypt_aad_v1_test() {
435    let key = b"0123456789abcdefghijkl";
436    let data = b"This is a very complex string of character that we need to encrypt";
437    let aad = b"This is some public data that we want to authenticate";
438    let wrong_aad = b"this is some public data that we want to authenticate";
439
440    let encrypted = encrypt_with_aad(data, key, aad, CiphertextVersion::V1).unwrap();
441
442    let encrypted: Vec<u8> = encrypted.into();
443
444    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
445    let decrypted = encrypted.decrypt_with_aad(key, aad).unwrap();
446
447    assert_eq!(decrypted, data);
448
449    let decrypted = encrypted.decrypt_with_aad(key, wrong_aad);
450
451    assert!(decrypted.is_err());
452
453    let decrypted = encrypted.decrypt(key);
454
455    assert!(decrypted.is_err());
456}
457
458#[test]
459fn encrypt_decrypt_v2_test() {
460    let key = "0123456789abcdefghijkl".as_bytes();
461    let data = "This is a very complex string of character that we need to encrypt".as_bytes();
462
463    let encrypted = encrypt(data, key, CiphertextVersion::V2).unwrap();
464
465    assert_eq!(encrypted.header.version, CiphertextVersion::V2);
466    let encrypted: Vec<u8> = encrypted.into();
467
468    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
469    let decrypted = encrypted.decrypt(key).unwrap();
470
471    assert_eq!(decrypted, data);
472}
473
474#[test]
475fn encrypt_decrypt_aad_v2_test() {
476    let key = b"0123456789abcdefghijkl";
477    let data = b"This is a very complex string of character that we need to encrypt";
478    let aad = b"This is some public data that we want to authenticate";
479    let wrong_aad = b"this is some public data that we want to authenticate";
480
481    let encrypted = encrypt_with_aad(data, key, aad, CiphertextVersion::V2).unwrap();
482
483    let encrypted: Vec<u8> = encrypted.into();
484
485    let encrypted = Ciphertext::try_from(encrypted.as_slice()).unwrap();
486    let decrypted = encrypted.decrypt_with_aad(key, aad).unwrap();
487
488    assert_eq!(decrypted, data);
489
490    let decrypted = encrypted.decrypt_with_aad(key, wrong_aad);
491
492    assert!(decrypted.is_err());
493
494    let decrypted = encrypted.decrypt(key);
495
496    assert!(decrypted.is_err());
497}
498
499#[test]
500fn asymmetric_test() {
501    use super::key::{generate_keypair, KeyVersion};
502
503    let test_plaintext = b"this is a test data";
504
505    let keypair = generate_keypair(KeyVersion::Latest);
506
507    let encrypted_data = encrypt_asymmetric(
508        test_plaintext,
509        &keypair.public_key,
510        CiphertextVersion::Latest,
511    )
512    .unwrap();
513
514    let encrypted_data_vec: Vec<u8> = encrypted_data.into();
515
516    assert_ne!(encrypted_data_vec.len(), 0);
517
518    let encrypted_data = Ciphertext::try_from(encrypted_data_vec.as_slice()).unwrap();
519
520    let decrypted_data = encrypted_data
521        .decrypt_asymmetric(&keypair.private_key)
522        .unwrap();
523
524    assert_eq!(decrypted_data, test_plaintext);
525}
526
527#[test]
528fn asymmetric_aad_test() {
529    use super::key::{generate_keypair, KeyVersion};
530
531    let test_plaintext = b"this is a test data";
532    let aad = b"This is some public data that we want to authenticate";
533    let wrong_aad = b"this is some public data that we want to authenticate";
534
535    let keypair = generate_keypair(KeyVersion::Latest);
536
537    let encrypted_data = encrypt_asymmetric_with_aad(
538        test_plaintext,
539        &keypair.public_key,
540        aad,
541        CiphertextVersion::Latest,
542    )
543    .unwrap();
544
545    let encrypted_data_vec: Vec<u8> = encrypted_data.into();
546
547    assert_ne!(encrypted_data_vec.len(), 0);
548
549    let encrypted_data = Ciphertext::try_from(encrypted_data_vec.as_slice()).unwrap();
550
551    let decrypted_data = encrypted_data
552        .decrypt_asymmetric_with_aad(&keypair.private_key, aad)
553        .unwrap();
554
555    assert_eq!(decrypted_data, test_plaintext);
556
557    let decrypted = encrypted_data.decrypt_asymmetric_with_aad(&keypair.private_key, wrong_aad);
558
559    assert!(decrypted.is_err());
560
561    let decrypted = encrypted_data.decrypt_asymmetric(&keypair.private_key);
562
563    assert!(decrypted.is_err());
564}
565
566#[test]
567fn asymmetric_test_v2() {
568    use super::key::{generate_keypair, KeyVersion};
569
570    let test_plaintext = b"this is a test data";
571
572    let keypair = generate_keypair(KeyVersion::V1);
573
574    let encrypted_data =
575        encrypt_asymmetric(test_plaintext, &keypair.public_key, CiphertextVersion::V2).unwrap();
576
577    assert_eq!(encrypted_data.header.version, CiphertextVersion::V2);
578    let encrypted_data_vec: Vec<u8> = encrypted_data.into();
579
580    assert_ne!(encrypted_data_vec.len(), 0);
581
582    let encrypted_data = Ciphertext::try_from(encrypted_data_vec.as_slice()).unwrap();
583
584    let decrypted_data = encrypted_data
585        .decrypt_asymmetric(&keypair.private_key)
586        .unwrap();
587
588    assert_eq!(decrypted_data, test_plaintext);
589}
590
591#[test]
592fn asymmetric_aad_test_v2() {
593    use super::key::{generate_keypair, KeyVersion};
594
595    let test_plaintext = b"this is a test data";
596    let aad = b"This is some public data that we want to authenticate";
597    let wrong_aad = b"this is some public data that we want to authenticate";
598
599    let keypair = generate_keypair(KeyVersion::V1);
600
601    let encrypted_data = encrypt_asymmetric_with_aad(
602        test_plaintext,
603        &keypair.public_key,
604        aad,
605        CiphertextVersion::V2,
606    )
607    .unwrap();
608
609    let encrypted_data_vec: Vec<u8> = encrypted_data.into();
610
611    assert_ne!(encrypted_data_vec.len(), 0);
612
613    let encrypted_data = Ciphertext::try_from(encrypted_data_vec.as_slice()).unwrap();
614
615    let decrypted_data = encrypted_data
616        .decrypt_asymmetric_with_aad(&keypair.private_key, aad)
617        .unwrap();
618
619    assert_eq!(decrypted_data, test_plaintext);
620
621    let decrypted = encrypted_data.decrypt_asymmetric_with_aad(&keypair.private_key, wrong_aad);
622
623    assert!(decrypted.is_err());
624
625    let decrypted = encrypted_data.decrypt_asymmetric(&keypair.private_key);
626
627    assert!(decrypted.is_err());
628}