vitaminc_encrypt/
lib.rs

1#![deny(clippy::unwrap_used, clippy::todo, unsafe_code, unused_imports)]
2#![doc = include_str!("../README.md")]
3mod cipher;
4mod key;
5
6pub use cipher::Aes256Cipher;
7pub use key::{EncryptedKey, Key};
8
9// Re-exports
10pub use vitaminc_aead::{
11    Aad, Cipher, Decrypt, Encrypt, IntoAad, LocalCipherText, Nonce, Unspecified,
12};
13
14/// Encrypt the given plaintext using the provided key.
15/// Any type that implements the [`Encrypt`] trait can be used.
16///
17/// # Return type
18///
19/// The return type is the encrypted form of the plaintext, which is determined by the
20/// `Encrypt` trait implementation for the type of `plaintext`.
21///
22/// # Errors
23///
24/// If the encryption fails, an [`Unspecified`] error is returned.
25/// Specific errors may reveal information about the failure, such as key length issues or nonce generation problems
26/// which can lead to security vulnerabilities so they are not detailed here.
27///
28/// See also [`decrypt`].
29///
30/// # Example
31///
32/// ```rust
33/// use vitaminc_encrypt::Key;
34/// use vitaminc_aead::Encrypt;
35/// let key = Key::from([0u8; 32]);
36/// let encrypted = vitaminc_encrypt::encrypt(&key, "message").unwrap();
37/// ```
38///
39pub fn encrypt<T>(key: &Key, plaintext: T) -> Result<T::Encrypted, Unspecified>
40where
41    T: Encrypt,
42{
43    Aes256Cipher::new(key).and_then(|cipher| plaintext.encrypt(&cipher))
44}
45
46/// Encrypt the given plaintext using the provided key and additional authenticated data (AAD).
47///
48/// # Additional Authenticated Data (AAD)
49///
50/// AAD is optional data that is authenticated but not encrypted.
51/// Decrypting the ciphertext requires the same AAD to be provided.
52///
53/// Any type that implements the [`IntoAad`] trait can be used to provide AAD.
54///
55/// See also [`decrypt_with_aad`] and [`vitaminc_aead::Aad`].
56///
57/// # Example
58///
59/// ```rust
60/// use vitaminc_encrypt::Key;
61/// use vitaminc_aead::Encrypt;
62/// let key = Key::from([0u8; 32]);
63/// let encrypted = vitaminc_encrypt::encrypt_with_aad(&key, "message", "additional-data").unwrap();
64/// ```
65///
66pub fn encrypt_with_aad<'a, T, A>(
67    key: &Key,
68    plaintext: T,
69    aad: A,
70) -> Result<T::Encrypted, Unspecified>
71where
72    T: Encrypt + 'a,
73    A: IntoAad<'a>,
74{
75    Aes256Cipher::new(key).and_then(|cipher| plaintext.encrypt_with_aad(&cipher, aad))
76}
77
78/// Decrypt the given ciphertext using the provided key.
79/// Any type that implements the [`Decrypt`] trait can be used so long as the value was encrypted with the same key.
80///
81/// # CipherText type
82///
83/// The type of `ciphertext` must match the `Encrypted` type defined in the [`Decrypt`] trait implementation for `T`.
84///
85/// # Example
86///
87/// ```rust
88/// use vitaminc_encrypt::Key;
89/// use vitaminc_aead::Decrypt;
90/// let key = Key::from([0u8; 32]);
91/// let ciphertext = vitaminc_encrypt::encrypt(&key, "message").unwrap();
92/// let decrypted: String = vitaminc_encrypt::decrypt(&key, ciphertext).unwrap();
93/// assert_eq!(decrypted, "message");
94/// ```
95pub fn decrypt<T>(key: &Key, ciphertext: T::Encrypted) -> Result<T, Unspecified>
96where
97    T: Decrypt,
98{
99    Aes256Cipher::new(key).and_then(|cipher| T::decrypt(ciphertext, &cipher))
100}
101
102/// Decrypt the given ciphertext using the provided key and additional authenticated data (AAD).
103/// This is the reversed operation of [`encrypt_with_aad`].
104///
105/// See also [`encrypt_with_aad`] and [`vitaminc_aead::Aad`].
106///
107/// # Example
108///
109/// ```rust
110/// use vitaminc_encrypt::Key;
111/// use vitaminc_aead::Decrypt;
112/// let key = Key::from([0u8; 32]);
113/// let ciphertext = vitaminc_encrypt::encrypt_with_aad(&key, "message", "additional-data").unwrap();
114/// let decrypted: String = vitaminc_encrypt::decrypt_with_aad(&key, ciphertext, "additional-data").unwrap();
115/// assert_eq!(decrypted, "message");
116/// ```
117///
118/// ## Incorrect AAD will fail
119///
120/// If the AAD does not match the one used during encryption, decryption will fail with an [`Unspecified`] error.
121///
122/// ```rust
123/// # use vitaminc_encrypt::Key;
124/// # use vitaminc_aead::Decrypt;
125/// # let key = Key::from([0u8; 32]);
126/// let ciphertext = vitaminc_encrypt::encrypt_with_aad(&key, "message", "additional-data").unwrap();
127/// let result = vitaminc_encrypt::decrypt_with_aad::<String, _>(&key, ciphertext, "wrong-data");
128/// assert!(result.is_err());
129/// ```
130///
131pub fn decrypt_with_aad<'a, T, A>(
132    key: &Key,
133    ciphertext: T::Encrypted,
134    aad: A,
135) -> Result<T, Unspecified>
136where
137    T: Decrypt,
138    A: IntoAad<'a>,
139{
140    Aes256Cipher::new(key).and_then(|cipher| T::decrypt_with_aad(ciphertext, &cipher, aad))
141}