crypto/chacha/mod.rs
1//! The ChaCha family of stream ciphers and AEADs.
2//!
3//! # Stream ciphers vs AEADs
4//!
5//! A **stream cipher** (`ChaCha`, `XChaCha`) generates a keystream from a key and nonce and XORs it
6//! with plaintext to produce ciphertext. It provides **confidentiality** but *no* integrity or
7//! authentication. An attacker can modify the ciphertext and produce garbage on decryption.
8//! Use a stream cipher when you only need secrecy and are handling authentication
9//! separately.
10//!
11//! An **AEAD** (Authenticated Encryption with Associated Data) wraps a stream cipher with a MAC to
12//! provide **confidentiality + integrity** in a single primitive. This crate offers three AEAD
13//! constructions built on ChaCha20: [`ChaCha20Blake3`] (encrypt-then-MAC with BLAKE3),
14//! [`ChaCha20Poly1305`] (RFC 8439), and [`XChaCha20Poly1305`] (extended-nonce variant).
15//!
16//! # ChaChaDjb vs ChaChaIetf
17//!
18//! The original ChaCha design by Daniel J. Bernstein uses a **64-bit counter** and a **64-bit nonce**
19//! (8 bytes). These are the `Djb` variants (`ChaCha8Djb`, `ChaCha12Djb`, `ChaCha20Djb`).
20//!
21//! The IETF variant (RFC 8439) uses a **32-bit counter** and a **96-bit nonce** (12 bytes). This is
22//! [`ChaCha20Ietf`]. The IETF layout is required by TLS 1.3 and is used as the inner cipher for
23//! the [`ChaCha20Poly1305`] AEAD.
24//!
25//! [`XChaCha20`] extends the nonce to 24 bytes by deriving a subkey with [`hchacha20`], then encrypting
26//! with the IETF variant of ChaCha20. This allows random nonces with negligible collision probability.
27//!
28//! # Examples
29//!
30//! ## AEAD usage (e.g. [`ChaCha20Blake3`])
31//!
32//! ```
33//! use crypto::{Aead, chacha::ChaCha20Blake3};
34//!
35//! let key = [0xab; 32]; // WARNING: don't use static values here
36//! let nonce = [0xcd; 32];
37//! let aad = b"associated data";
38//! let plaintext = b"hello world";
39//!
40//! let cipher = ChaCha20Blake3::new(&key);
41//!
42//! let mut buf = plaintext.to_vec();
43//! let tag = cipher.encrypt_in_place(&mut buf, &nonce, aad);
44//!
45//! cipher.decrypt_in_place(&mut buf, &nonce, aad, tag.as_ref())
46//! .expect("decryption failed");
47//! assert_eq!(&buf, plaintext);
48//! ```
49//!
50//! ## Stream cipher usage (e.g. [`ChaCha20Djb`])
51//!
52//! ```
53//! use crypto::{StreamCipher, chacha::ChaCha20Djb};
54//!
55//! let key = [0xab; 32];
56//! let nonce = [0xcd; 8];
57//! let mut plaintext = *b"hello world";
58//!
59//! let mut cipher = ChaCha20Djb::new(&key, &nonce);
60//! cipher.xor_keystream(&mut plaintext);
61//! // plaintext is now encrypted
62//! cipher.set_counter(0);
63//!
64//! cipher.xor_keystream(&mut plaintext);
65//! // plaintext is back to "hello world" (XOR is its own inverse)
66//! assert_eq!(&plaintext, b"hello world");
67//! ```
68
69// aarch64 assumes that NEON instructions are always present
70#[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
71mod chacha_neon;
72
73// import if the target runtime supports the feature
74#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
75mod chacha_wasm_simd128;
76
77// import if runtime CPU features detection is enabled or if the target CPU supports the feature
78#[cfg(any(
79 all(target_arch = "x86_64", feature = "std"),
80 all(target_arch = "x86_64", target_feature = "avx2")
81))]
82mod chacha_avx2;
83
84// import if runtime CPU features detection is enabled or if the target CPU supports the feature
85#[cfg(any(
86 all(target_arch = "x86_64", feature = "std"),
87 all(target_arch = "x86_64", target_feature = "avx512f")
88))]
89mod chacha_avx512;
90
91/// ChaCha and XChaCha cipher implementations.
92mod chacha;
93
94pub(crate) use chacha::{BLOCK_SIZE, CONSTANT, STATE_WORDS, quarter_round};
95pub use chacha::{ChaCha, ChaCha8Djb, ChaCha12Djb, ChaCha20Djb, ChaCha20Ietf, XChaCha, XChaCha20};
96
97mod chacha20_blake3;
98pub use chacha20_blake3::ChaCha20Blake3;
99
100/// ChaCha20-Poly1305 AEAD construction (RFC 8439) and XChaCha20-Poly1305.
101mod chacha20_poly1305;
102pub use chacha20_poly1305::{ChaCha20Poly1305, XChaCha20Poly1305};
103
104mod chacha8_poly1305;
105pub use chacha8_poly1305::ChaCha8Poly1305;
106
107/// HChaCha20 hash function.
108mod hchacha20;
109pub use hchacha20::hchacha20;