Skip to main content

⛓️ 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!

  1. RK → Chain Key CK (sending/receiving)
  2. CK → Message Key K1 → Use → Delete
  3. CK → New CK (KDF of old CK)
  4. New CK → Message Key K2 → Use → Delete
  5. ...

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:

  1. One-way: Given output, can't find input
  2. Pseudorandom: Output looks random input
  3. 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.