diff --git a/ciphers/src/subtle/chacha20poly1305_ietf.rs b/ciphers/src/subtle/chacha20poly1305_ietf.rs index d988ff2..59f6a5c 100644 --- a/ciphers/src/subtle/chacha20poly1305_ietf.rs +++ b/ciphers/src/subtle/chacha20poly1305_ietf.rs @@ -14,12 +14,12 @@ pub const TAG_LEN: usize = typenum2const! { ::TagSize }; pub const NONCE_LEN: usize = typenum2const! { ::NonceSize }; /// Encrypts using ChaCha20Poly1305 as implemented in [RustCrypto](https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305). -/// `key` and `nonce` MUST be chosen (pseudo-)randomly. The `key` slice MUST have a length of -/// [KEY_LEN]. The `nonce` slice MUST have a length of [NONCE_LEN]. The last [TAG_LEN] bytes -/// written in `ciphertext` are the tag guaranteeing integrity. +/// `key` MUST be chosen (pseudo-)randomly and `nonce` MOST NOT be reused. The `key` slice MUST have +/// a length of [KEY_LEN]. The `nonce` slice MUST have a length of [NONCE_LEN]. The last [TAG_LEN] bytes +/// written in `ciphertext` are the tag guaranteeing integrity. `ciphertext` MUST have a capacity of +/// `plaintext.len()` + [TAG_LEN]. /// /// # Examples -/// ///```rust /// # use rosenpass_ciphers::subtle::chacha20poly1305_ietf::{encrypt, TAG_LEN, KEY_LEN, NONCE_LEN}; /// @@ -29,7 +29,7 @@ pub const NONCE_LEN: usize = typenum2const! { ::NonceSize /// let key: &[u8] = &[0u8; KEY_LEN]; // THIS IS NOT A SECURE KEY /// let nonce: &[u8] = &[0u8; NONCE_LEN]; // THIS IS NOT A SECURE NONCE /// let additional_data: &[u8] = "the encrypted message is very important".as_bytes(); -/// let mut ciphertext_buffer = [0u8; PLAINTEXT_LEN + TAG_LEN]; +/// let mut ciphertext_buffer = [0u8;PLAINTEXT_LEN + TAG_LEN]; /// /// let res: anyhow::Result<()> = encrypt(&mut ciphertext_buffer, key, nonce, additional_data, plaintext); /// assert!(res.is_ok()); @@ -59,7 +59,7 @@ pub fn encrypt( /// `ad`. using ChaCha20Poly1305 as implemented in [RustCrypto](https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305). /// /// The `key` slice MUST have a length of [KEY_LEN]. The `nonce` slice MUST have a length of -/// [NONCE_LEN]. +/// [NONCE_LEN]. The plaintext buffer must have a capacity of `ciphertext.len()` - [TAG_LEN]. /// /// # Examples ///```rust diff --git a/ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs b/ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs index 0bc14b4..2f6b9f2 100644 --- a/ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs +++ b/ciphers/src/subtle/chacha20poly1305_ietf_libcrux.rs @@ -13,7 +13,8 @@ pub const NONCE_LEN: usize = 12; /// Encrypts using ChaCha20Poly1305 as implemented in [libcrux](https://github.com/cryspen/libcrux). /// Key and nonce MUST be chosen (pseudo-)randomly. The `key` slice MUST have a length of /// [KEY_LEN]. The `nonce` slice MUST have a length of [NONCE_LEN]. The last [TAG_LEN] bytes -/// written in `ciphertext` are the tag guaranteeing integrity. +/// written in `ciphertext` are the tag guaranteeing integrity. `ciphertext` MUST have a capacity of +/// `plaintext.len()` + [TAG_LEN]. /// /// # Examples ///```rust @@ -66,7 +67,7 @@ pub fn encrypt( /// `ad`. using ChaCha20Poly1305 as implemented in [libcrux](https://github.com/cryspen/libcrux). /// /// The `key` slice MUST have a length of [KEY_LEN]. The `nonce` slice MUST have a length of -/// [NONCE_LEN]. +/// [NONCE_LEN]. The plaintext buffer must have a capacity of `ciphertext.len()` - [TAG_LEN]. /// /// # Examples ///```rust diff --git a/ciphers/src/subtle/xchacha20poly1305_ietf.rs b/ciphers/src/subtle/xchacha20poly1305_ietf.rs index b9eb21e..12a8ed8 100644 --- a/ciphers/src/subtle/xchacha20poly1305_ietf.rs +++ b/ciphers/src/subtle/xchacha20poly1305_ietf.rs @@ -6,10 +6,41 @@ use chacha20poly1305::aead::generic_array::GenericArray; use chacha20poly1305::XChaCha20Poly1305 as AeadImpl; use chacha20poly1305::{AeadCore, AeadInPlace, KeyInit, KeySizeUser}; +/// The key length is 32 bytes or 256 bits. pub const KEY_LEN: usize = typenum2const! { ::KeySize }; +/// The MAC tag length is 16 bytes or 128 bits. pub const TAG_LEN: usize = typenum2const! { ::TagSize }; +/// The nonce length is 24 bytes or 192 bits. pub const NONCE_LEN: usize = typenum2const! { ::NonceSize }; +/// Encrypts using XChaCha20Poly1305 as implemented in [RustCrypto](https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305). +/// `key` and `nonce` MUST be chosen (pseudo-)randomly. The `key` slice MUST have a length of +/// [KEY_LEN]. The `nonce` slice MUST have a length of [NONCE_LEN]. +/// In contrast to [chacha20poly1305_ietf::encrypt](crate::subtle::chacha20poly1305_ietf::encrypt) and +/// [chacha20poly1305_ietf_libcrux::encrypt](crate::subtle::chacha20poly1305_ietf_libcrux::encrypt), +/// `nonce` is also written into `ciphertext` and therefore ciphertext MUST have a length +/// of at least [NONCE_LEN] + `plaintext.len()` + [TAG_LEN]. +/// +/// # Examples +///```rust +/// # use rosenpass_ciphers::subtle::xchacha20poly1305_ietf::{encrypt, TAG_LEN, KEY_LEN, NONCE_LEN}; +/// const PLAINTEXT_LEN: usize = 43; +/// let plaintext = "post-quantum cryptography is very important".as_bytes(); +/// assert_eq!(PLAINTEXT_LEN, plaintext.len()); +/// let key: &[u8] = &[0u8; KEY_LEN]; // THIS IS NOT A SECURE KEY +/// let nonce: &[u8] = &[0u8; NONCE_LEN]; // THIS IS NOT A SECURE NONCE +/// let additional_data: &[u8] = "the encrypted message is very important".as_bytes(); +/// let mut ciphertext_buffer = [0u8; NONCE_LEN + PLAINTEXT_LEN + TAG_LEN]; +/// +/// +/// let res: anyhow::Result<()> = encrypt(&mut ciphertext_buffer, key, nonce, additional_data, plaintext); +/// # assert!(res.is_ok()); +/// # let expected_ciphertext: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/// # 0, 0, 0, 0, 8, 241, 229, 253, 200, 81, 248, 30, 183, 149, 134, 168, 149, 87, 109, 49, 159, 108, +/// # 206, 89, 51, 232, 232, 197, 163, 253, 254, 208, 73, 76, 253, 13, 247, 162, 133, 184, 177, 44, +/// # 73, 138, 176, 193, 61, 248, 61, 183, 164, 192, 214, 168, 4, 1, 62, 243, 36, 48, 149, 164, 6]; +/// # assert_eq!(expected_ciphertext, &ciphertext_buffer); +///``` #[inline] pub fn encrypt( ciphertext: &mut [u8], @@ -28,6 +59,38 @@ pub fn encrypt( Ok(()) } +/// Decrypts a `ciphertext` and verifies the integrity of the `ciphertext` and the additional data +/// `ad`. using XChaCha20Poly1305 as implemented in [RustCrypto](https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305). +/// +/// The `key` slice MUST have a length of [KEY_LEN]. The `nonce` slice MUST have a length of +/// [NONCE_LEN]. The plaintext buffer must have a capacity of `ciphertext.len()` - [TAG_LEN] - [NONCE_LEN]. +/// +/// In contrast to [chacha20poly1305_ietf::decrypt](crate::subtle::chacha20poly1305_ietf::decrypt) and +/// [chacha20poly1305_ietf_libcrux::decrypt](crate::subtle::chacha20poly1305_ietf_libcrux::decrypt), +/// `ciperhtext` MUST include the as it is not given otherwise. +/// +/// # Examples +///```rust +/// # use rosenpass_ciphers::subtle::xchacha20poly1305_ietf::{decrypt, TAG_LEN, KEY_LEN, NONCE_LEN}; +/// let ciphertext: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/// # 0, 0, 0, 0, 8, 241, 229, 253, 200, 81, 248, 30, 183, 149, 134, 168, 149, 87, 109, 49, 159, 108, +/// # 206, 89, 51, 232, 232, 197, 163, 253, 254, 208, 73, 76, 253, 13, 247, 162, 133, 184, 177, 44, +/// # 73, 138, 176, 193, 61, 248, 61, 183, 164, 192, 214, 168, 4, 1, 62, 243, 36, 48, 149, 164, 6]; +/// // this is the ciphertext generated by the example for the encryption +/// const PLAINTEXT_LEN: usize = 43; +/// assert_eq!(PLAINTEXT_LEN + TAG_LEN + NONCE_LEN, ciphertext.len()); +/// +/// let key: &[u8] = &[0u8; KEY_LEN]; // THIS IS NOT A SECURE KEY +/// let nonce: &[u8] = &[0u8; NONCE_LEN]; // THIS IS NOT A SECURE NONCE +/// let additional_data: &[u8] = "the encrypted message is very important".as_bytes(); +/// let mut plaintext_buffer = [0u8; PLAINTEXT_LEN]; +/// +/// let res: anyhow::Result<()> = decrypt(&mut plaintext_buffer, key, additional_data, ciphertext); +/// assert!(res.is_ok()); +/// let expected_plaintext = "post-quantum cryptography is very important".as_bytes(); +/// assert_eq!(expected_plaintext, plaintext_buffer); +/// +///``` #[inline] pub fn decrypt( plaintext: &mut [u8],