Expand description
The ChaCha family of stream ciphers and AEADs.
§Stream ciphers vs AEADs
A stream cipher (ChaCha, XChaCha) generates a keystream from a key and nonce and XORs it
with plaintext to produce ciphertext. It provides confidentiality but no integrity or
authentication. An attacker can modify the ciphertext and produce garbage on decryption.
Use a stream cipher when you only need secrecy and are handling authentication
separately.
An AEAD (Authenticated Encryption with Associated Data) wraps a stream cipher with a MAC to
provide confidentiality + integrity in a single primitive. This crate offers three AEAD
constructions built on ChaCha20: ChaCha20Blake3 (encrypt-then-MAC with BLAKE3),
ChaCha20Poly1305 (RFC 8439), and XChaCha20Poly1305 (extended-nonce variant).
§ChaChaDjb vs ChaChaIetf
The original ChaCha design by Daniel J. Bernstein uses a 64-bit counter and a 64-bit nonce
(8 bytes). These are the Djb variants (ChaCha8Djb, ChaCha12Djb, ChaCha20Djb).
The IETF variant (RFC 8439) uses a 32-bit counter and a 96-bit nonce (12 bytes). This is
ChaCha20Ietf. The IETF layout is required by TLS 1.3 and is used as the inner cipher for
the ChaCha20Poly1305 AEAD.
XChaCha20 extends the nonce to 24 bytes by deriving a subkey with hchacha20, then encrypting
with the IETF variant of ChaCha20. This allows random nonces with negligible collision probability.
§Examples
§AEAD usage (e.g. ChaCha20Blake3)
use crypto::{Aead, chacha::ChaCha20Blake3};
let key = [0xab; 32]; // WARNING: don't use static values here
let nonce = [0xcd; 32];
let aad = b"associated data";
let plaintext = b"hello world";
let cipher = ChaCha20Blake3::new(&key);
let mut buf = plaintext.to_vec();
let tag = cipher.encrypt_in_place(&mut buf, &nonce, aad);
cipher.decrypt_in_place(&mut buf, &nonce, aad, tag.as_ref())
.expect("decryption failed");
assert_eq!(&buf, plaintext);§Stream cipher usage (e.g. ChaCha20Djb)
use crypto::{StreamCipher, chacha::ChaCha20Djb};
let key = [0xab; 32];
let nonce = [0xcd; 8];
let mut plaintext = *b"hello world";
let mut cipher = ChaCha20Djb::new(&key, &nonce);
cipher.xor_keystream(&mut plaintext);
// plaintext is now encrypted
cipher.set_counter(0);
cipher.xor_keystream(&mut plaintext);
// plaintext is back to "hello world" (XOR is its own inverse)
assert_eq!(&plaintext, b"hello world");Structs§
- ChaCha
- ChaCha stream cipher.
- ChaCha8
Poly1305 - The ChaCha8-Poly1305 AEAD, derived from ChaCha20-Poly1305 as standardized in RFC 8439 but with a reduced number of ChaCha rounds for embedded platforms.
- ChaCha20
Blake3 - ChaCha20-BLAKE3 AEAD (encrypt-then-MAC).
- ChaCha20
Poly1305 - ChaCha20-Poly1305 AEAD as specified in RFC 8439.
- XChaCha
- XChaCha20 stream cipher with 24-byte (192-bit) nonce (draft-irtf-cfrg-xchacha-03).
- XCha
Cha20 Poly1305 - XChaCha20-Poly1305 AEAD (draft-irtf-cfrg-xchacha-03).
Functions§
- hchacha20
- HChaCha20 is a hash function derived from ChaCha20.