⛓️ Key Chains
Symmetric Key Ratchet Explained
In 15 minutes: Understand how KDF chains derive message keys
Prerequisite: What is Ratcheting
🎯 The Simple Story
Alice and Bob have a root key RK. How do they get a message key for each message?
KDF Chains!
- RK → Chain Key CK (sending/receiving)
- CK → Message Key K1 → Use → Delete
- CK → New CK (KDF of old CK)
- New CK → Message Key K2 → Use → Delete
- ...
Each step uses a KDF - one-way function. Can't go back!
🧠 Mental Model
Hold this picture in your head:
Root Key RK (from X3DH):
↓
KDF_R (root → chain)
↓
Chain Key CK1
↓
KDF_C (chain → message)
↓
Message Key K1
↓
Encrypt Message 1
↓
Delete K1 (gone!)
↓
CK1 → KDF → CK2 (next chain key)
↓
Chain Key CK2
↓
KDF_C
↓
Message Key K2
↓
Encrypt Message 2
Think of it like:
🎢 Recipe chain (Recipe for recipe for ingredient)
🌳 Family tree (Parent → child → grandchild keys)
🔢 One-way sequence (Can compute K2 from K1, not K1 from K2)
📊 See It Happen
Key derivation flow:
🎯 KDF Definition
What is a KDF?
KDF (Key Derivation Function): Takes input key, produces output key.
Properties:
- One-way: Given output, can't find input
- Pseudorandom: Output looks random input
- Deterministic: Same input → same output
Example KDF: HMAC-SHA256, HKDF
🔢 The Math
Chain Key Derivation
# From root key to chain keys
CK_A (Alice sending) = KDF_R(RK, "sending")
CK_B (Bob receiving) = KDF_R(RK, "receiving")
# Or simpler: just KDF with context
CK_A = KDF(RK)
CK_B = KDF(RK)
Both derive from same RK
Message Key Derivation
# From chain key to message key
K1 = KDF_C(CK_A1)
K2 = KDF_C(CK_A2)
K3 = KDF_C(CK_A3)
Message key depends on chain key
Chain Key Advance
# Derive next chain key
CK_A1 → KDF → CK_A2 → KDF → CK_A3 → ...
One-way: Can't compute CK_A1 from CK_A2
💡 Why KDF Chains?
Why not just:
K1 = KDF(RK, 1)
K2 = KDF(RK, 2)
K3 = KDF(RK, 3)
Because:
- Need to store RK forever
- Need message numbers
- Less elegant
KDF chains:
- More elegant
- Don't need message numbers
- Natural evolution
✅ Quick Check
Why KDFs?
One-way derivation:
K1 = KDF(RK) K2 = KDF(K1) K3 = KDF(K2)
Can't compute K1 from K2 (one-way). Key security!
Chain vs direct derivation?
Chain is more elegant:
Direct: K1 = KDF(RK, 1), K2 = KDF(RK, 2)... Chain: K1 = KDF(RK), K2 = KDF(K1), K3 = KDF(K2)...
Both work, chain is more natural!
📋 Key Takeaways
✅ KDF Chains: One-way key evolution
✅ Root Key RK → Chain Keys CK → Message Keys K
✅ Chain Key: KDF_C derives message key
✅ Message Key: Used then deleted
✅ Chain evolves: CK1 → CK2 → CK3 (KDF)
✅ Can't reverse: KDF is one-way
🎉 What's Next
Symmetric key ratchet explained! Next: DH ratchet.