04 — Symmetric Cryptography
Same key for encrypt and decrypt. Categorized into block ciphers (operate on fixed-size blocks) and stream ciphers (operate bitbyte by bitbyte). Modes of operation apply block ciphers to arbitrary messages. AEAD combines encryption + authentication.
1. Block ciphers — principles
A block cipher is a pair \((E, D)\) such that \(E_k: \{0,1\}^n \to \{0,1\}^n\) is a permutation for each key \(k \in \{0,1\}^\kappa\). Notation: \(n\) = block size in bits, \(\kappa\) = key size in bits.
Structures
Feistel network (Horst Feistel, IBM ~1971):
- Splits the block into two halves \(L, R\).
- Each round: \(L' = R\), \(R' = L \oplus F(R, k_i)\) where \(F\) is any function (it need not even be invertible).
- Decryption = the same operations with round keys in reverse order.
- Examples: DES, 3DES, Blowfish, Twofish, CAST, Camellia, GOST 28147-89.
Substitution-Permutation Network (SPN):
- Each round: AddRoundKey → SubBytes (S-box) → Permutation/Mix.
- The ciphers must be invertible (bijective S-box; invertible permutation).
- Examples: AES, Serpent, PRESENT, SM4.
ARX (Add-Rotate-XOR):
- Operations: addition mod 2^n, bit rotation, XOR.
- Constant-time by design (no table lookup).
- Examples: ChaCha20, Salsa20, Speck, Threefish.
2. DES (Data Encryption Standard) — 1977
FIPS 46 (1977), derived from IBM's Lucifer (Feistel + Coppersmith). 64-bit block, 56-bit key (8 parity bits), 16 Feistel rounds.
Breaks:
- 1990: Eli Biham + Adi Shamir discover differential cryptanalysis (the NSA already knew of it in 1974 — DES was designed to resist it, S-boxes tuned accordingly).
- 1993: Mitsuru Matsui — linear cryptanalysis, 2^43 plaintexts.
- 1997: distributed.net breaks DES Challenge I in 96 days.
- 1998: EFF Deep Crack — US$ 250k of hardware breaks DES in 22 hours.
- 1999: DES Challenge III in 22 hours (Deep Crack + distributed.net).
Status: 56-bit key infeasible. Deprecated by NIST.
3DES (Triple DES)
\(C = E_{k_3}(D_{k_2}(E_{k_1}(P)))\) — EDE for compatibility with single DES (\(k_1 = k_2 = k_3\)).
- 3-key 3DES: 168-bit key, 112 bits of effective security (due to meet-in-the-middle).
- 2-key 3DES: 112 bits, ~80 bits effective.
Status: deprecated by NIST after 2023 (SP 800-131A); prohibited in FIPS 140-3 starting 2024. Vulnerable to Sweet32 (CVE-2016-2183) due to the 64-bit block in CBC/CTR modes with >32 GB of traffic.
3. AES (Advanced Encryption Standard) — 2001
NIST FIPS 197 (Nov 2001). Underlying algorithm = Rijndael (Joan Daemen + Vincent Rijmen, winner of the AES competition 1997–2000 against Serpent, Twofish, RC6, MARS).
Block: 128 bits. Keys: 128 / 192 / 256 bits. Rounds: 10 / 12 / 14. Structure: SPN with 4 operations per round:
- SubBytes — 8×8 S-box (inversion in GF(2^8) + affine transformation).
- ShiftRows — cyclic rotation of each row of the 4×4 state.
- MixColumns — matrix multiplication in GF(2^8) (omitted in the last round).
- AddRoundKey — XOR with the round key (expanded from the master via the key schedule).
Security
- No practical attack against full-round AES after 25 years of public cryptanalysis.
- Best known attack: biclique cryptanalysis (Bogdanov, Khovratovich, Rechberger 2011) — a factor of \(\sim 4\) better than brute force; impractical.
- Side-channel: cache-timing (Bernstein 2005, Tromer-Osvik-Shamir 2005) — mitigated by AES-NI (Intel Westmere 2010), constant-time S-box (bitslicing).
Performance
- AES-NI: ~1 cyclebyte on a modern CPU (IntelAMD since 2010).
- AArch64 Crypto Extensions: similar on ARM (Cortex-A57+).
- Software fallback (T-tables or bitsliced): 10–30 cycles/byte.
Implementations
- Reference C in the FIPS 197 appendix.
- OpenSSL EVPaes*_* with AES-NI auto-detect.
- mbedTLS AES with a hardware backend.
- BoringSSL aesni_* asm files.
Applications
- TLS 1.2/1.3 with cipher suites
_AES_128_GCM_/_AES_256_GCM_. - IPsec ESP
AES-GCM-16(RFC 4106). - LUKS2 default
aes-xts-plain64. - BitLocker, FileVault, dm-crypt, eCryptfs.
- WPA3 and WPA2 with CCMP.
4. Other relevant block ciphers
| Cipher | Block / Key | Designer | Notes |
|---|---|---|---|
| Serpent | 128 / 128–256 | Anderson + Biham + Knudsen, 1998 | AES finalist; 32 rounds; conservative, slower than AES. |
| Twofish | 128 / 128–256 | Schneier + Kelsey + Whiting + Wagner + Hall + Ferguson, 1998 | AES finalist; Feistel with key-dependent S-boxes. |
| Blowfish | 64 / 32–448 | Schneier, 1993 | Free, popular legacy; broken for large volumes (Sweet32). Successor Twofish. |
| RC5 / RC6 | variable | Rivest, 1994/1998 | RC6 was an AES finalist. |
| CAST-128 / CAST-256 | 64 / 40–128 or 128 / 128–256 | Adams + Tavares | Used in PGP. |
| IDEA | 64 / 128 | Lai + Massey, 1991 | Used in PGP 2.x; patented until 2012. |
| Camellia | 128 / 128–256 | NTT + Mitsubishi, 2000 | ISO 18033-3 standard; JP/EU adoption. |
| ARIA | 128 / 128–256 | Korean standard, 2003 | |
| SM4 | 128 / 128 | Chinese GM/T 0002-2012 | Mandatory in Chinese GB. |
| Kuznyechik | 128 / 256 | Russian GOST R 34.12-2015 | Successor of GOST 28147. |
| PRESENT | 64 / 80–128 | Bogdanov et al. 2007 | Lightweight, ISO 29192-2. |
| SPECK / SIMON | variable | NSA 2013 | Lightweight; controversial due to NSA origin. |
| Threefish | 2565121024 / same | Schneier et al., 2008 | Block of the Skein hash. ARX. Tweakable. |
| ASCON | 128 / 128 | Dobraunig et al. 2014 | NIST lightweight crypto winner 2023. |
5. Modes of operation for block ciphers
A block cipher only encrypts one block. A mode applies it to an arbitrary message.
ECB (Electronic Codebook) ❌
Each block is encrypted independently: \(C_i = E_k(P_i)\).
Catastrophic:
- Identical plaintexts produce identical ciphertexts — leaks patterns. Famous meme: the ECB-encrypted Tux penguin still shows its silhouette.
- No integrity.
- Do not use. Legitimate coverage: deriving a unique key / KDF building block.
CBC (Cipher Block Chaining) — 1976
\(C_i = E_k(P_i \oplus C_{i-1})\) with \(C_0 = \text{IV}\).
- The IV must be unpredictable (not merely unique). Predictable IV → BEAST (2011).
- Not parallelizable in encryption (serial); parallelizable in decryption.
- Padding required (PKCS#7 padding). Padding attacks: POODLE (2014), Lucky 13 (2013).
- No integrity. Vulnerable to tampering.
- Use only with a MAC on top (Encrypt-then-MAC).
CTR (Counter Mode) — 1979
\(C_i = P_i \oplus E_k(\text{nonce} \\\| i)\).
- Stream-like — no padding required.
- Parallelizable in encrypt and decrypt.
- Random access (decrypts any block).
- Nonce reuse = catastrophic: \(C_1 \oplus C_2 = P_1 \oplus P_2\).
- No integrity — use with a MAC.
OFB / CFB
Historical variants, rarely used in new designs. CFB is self-syncing (resistant to byte loss in transmission); OFB is stream-cipher-like.
XTS (XEX-based Tweaked-codebook with Ciphertext Stealing) — 2007
IEEE P1619. For disk encryption. Each sector is a tweak. Encrypt-only (no MAC because the disk has no extra space).
- Rearranged plaintext or tamper: detectable only by the application (not by XTS).
- Same key + same sector + same plaintext = same ciphertext (deterministic).
- Used in LUKS2, BitLocker, FileVault, Veracrypt.
- Do not use for messages; only for storage.
6. AEAD — Authenticated Encryption with Associated Data
AEAD = encryption + integrity + authentication + extra authenticated data.
Canonical interface:
encrypt(key, nonce, plaintext, associated_data) → ciphertext, tag
decrypt(key, nonce, ciphertext, associated_data, tag) → plaintext or ⊥associated_data (AD) is not encrypted but is authenticated — useful for protocol headers.
GCM (Galois/Counter Mode) — 2007
NIST SP 800-38D. AES-GCM is the standard in TLS 1.2/1.3, IPsec, SSH.
- Encrypt: AES-CTR.
- Authenticate: GHASH (multiplication in GF(2^128)).
- 128-bit tag (or truncated, with care).
- Hardware acceleration: PCLMULQDQ (Intel Westmere+).
Nonce reuse = catastrophic: reveals the authentication key (subkey \(H\)). Limit: 2^32 messages with the same key (96-bit nonce); birthday bound in GHASH.
Recommended: random 96-bit nonce, OK up to ~2^32 messages; or a 96-bit counter for deterministic ordering.
CCM (Counter with CBC-MAC) — 2003
NIST SP 800-38C. Encrypt = CTR; MAC = CBC-MAC. Slower than GCM (not parallelizable; two passes). Used in WPA2 (CCMP), Zigbee, Bluetooth LE.
ChaCha20-Poly1305 — RFC 8439 (2018; previously RFC 7539)
DJB design. The standard in TLS 1.3 (mandatory), WireGuard, the Signal Protocol.
- ChaCha20 stream cipher (ARX, 20 rounds).
- Poly1305 MAC (carry-save adders in GF(2^130 − 5)).
- No hardware acceleration needed — fast on any CPU.
- 96-bit nonce (XChaCha20 variants with a 192-bit nonce — random-safe).
- Constant-time by design.
AES-GCM-SIV — RFC 8452 (2019)
Gueron + Lindell 2015. Nonce-misuse-resistant: if a nonce repeats, it only leaks the equality of plaintexts (not the entire key). Useful in scenarios where nonce uniqueness is hard to guarantee (distributed state, replay).
OCB3 — RFC 7253 (2014)
Rogaway. Single-pass AEAD, ~1.05 × CTR speed. Patent released for free use in 2013. Little used due to its patent history; technically excellent.
SIV (Synthetic IV) — RFC 5297 (2008)
Rogaway. Slower (two passes) but deterministic (encrypt(P) = encrypt(P) — useful for key envelopes, key wrapping).
AEGIS — 2014
Wu + Preneel. Stream AEAD using the AES round function. Winner of the CAESAR competition (together with ASCON, COLM, MORUS, ACORN, Deoxys-II) in 2018. Standardized as an RFC draft in 2024.
7. Stream ciphers
Generate a keystream XORed with the plaintext. Implementation: shift registers, ARX, or a block cipher mode (CTR is stream-like).
RC4 ❌ — 1987 (broken)
Rivest 1987 (proprietary; leaked to the Cypherpunks in 1994). A simple stream cipher, it was the SSL/TLS standard for decades.
Breaks:
- Fluhrer, Mantin, Shamir (2001) — IV vulnerability used in WEP.
- AlFardan et al. (2013) — biases recover plaintexts across millions of TLS connections.
- NOMORE (2015) — practical biases in ~75 hours of capture.
Status: removed from TLS (RFC 7465, 2015). Do not use under any circumstances.
Salsa20 / ChaCha20 — DJB 2005 / 2008
Bernstein. ARX, 20 rounds (Salsa20), 20 rounds (ChaCha20).
- Salsa20: eSTREAM portfolio winner (software profile).
- ChaCha20: a refinement, better diffusion, used in TLS 1.3 / WireGuard.
- XSalsa20 / XChaCha20: variants with a 192-bit nonce (random-safe).
- HChaCha20: a hash-like construct used for the X-variants.
Snow 3G / Snow-V
3GPP uses Snow 3G in LTE/4G UEA2, UIA2. Snow-V was proposed for 5G; it lost to the other family.
Trivium / Grain
eSTREAM hardware profile winners. Trivium has a 288-bit state and is extremely simple — used in IoT.
KCipher-2
Standardized in Japan. Little global use.
8. Key derivation, key wrap, key management
Key Wrap (KW, KWP)
NIST SP 800-38F. Encrypt a key with a key. Uses AES in a specific construction. Deterministic (uses no IV), AEAD-like.
- AES-KW: input must be a multiple of 8 bytes.
- AES-KWP: padding for arbitrary length.
Use: HSMs, KMS, envelope encryption (cloud key management).
Key derivation from a key
HKDF (RFC 5869) — extract-then-expand based on HMAC. The modern standard.
prk = HMAC(salt, ikm)
okm = HMAC(prk, info \\\| 0x01) \\\| HMAC(prk, okm[0] \\\| info \\\| 0x02) \\\| …Key derivation from a password
See 06-hash-and-mac.md §KDFs. (Argon2id, scrypt, bcrypt, PBKDF2.)
9. Practical recommendations 2026
| Need | Use |
|---|---|
| General symmetric encryption | ChaCha20-Poly1305 (universal) or AES-256-GCM (with AES-NI) |
| Disk encryption | AES-256-XTS (LUKS2 default) |
| Deterministic encryption (envelope) | AES-GCM-SIV |
| Hardware without AES-NI | ChaCha20-Poly1305 |
| Very long streaming | XChaCha20-Poly1305 (random nonce safe) |
| TLS handshake | TLS 1.3 with ChaCha20-Poly1305 or AES-128-GCM |
| E2E messaging | ChaCha20-Poly1305 (Signal, WireGuard use it) |
| Lightweight / IoT | ASCON-128a (NIST LWC) |
| Post-quantum symmetric | Use AES-256 (Grover only gives 128 bits of security) |
Anti-patterns
❌ ECB never. ❌ CBC without a MAC (Encrypt-then-MAC mandatory). ❌ Reusing a GCM nonce with the same key. ❌ Padding oracles in CBC (always give a generic error on decrypt failure). ❌ Truncating GCM tags below 96 bits without analysis. ❌ Using the same key for encryption and MAC (use HKDF to split). ❌ RC4, DES, 3DES, RC2, IDEA-with-a-weak-key. ❌ Hardcoded key in the code.
Canonical sizes
| Component | Bits |
|---|---|
| AES key | 256 |
| ChaCha20 key | 256 |
| GCM nonce | 96 |
| ChaCha20 nonce | 96 (or 192 for XChaCha20) |
| GCM/Poly1305 tag | 128 |
| HKDF salt | 256 |
| Master key | 256 |
10. Audited libraries
- libsodium — DJB-school primitives; misuse-resistant APIs.
- BoringSSL / OpenSSL EVP — TLS-grade primitives.
- age (Filippo Valsorda) — file encryption with X25519 + ChaCha20-Poly1305 + scrypt.
- Tink (Google) — high-level, versioned keysets.
- Themis (Cossack Labs) — high-level, multi-language.
- rustcrypto/aes-gcm, rustcrypto/chacha20poly1305 — Rust constant-time.
- PyNaCl, cryptography (pyca) — Python.
11. Cross-reference
- Hash and MAC:
06-hash-and-mac.md. - Protocols that apply them (TLS, SSH, IPsec):
07-protocols.md. - Specific attacks (BEAST, POODLE, Lucky13, Sweet32):
11-attacks.md. - People (Daemen, Rijmen, DJB, Schneier, Rivest):
12-people.md. - Koder Stack usage:
14-koder-applied.md.