Skip to main content

🔧 What is Ratcheting?

The Concept Behind Forward Secrecy

In 15 minutes: Understand why the Double Ratchet provides forward secrecy
Prerequisite: X3DH (already have shared secret S)


🎯 The Simple Story

Alice and Bob have a shared secret S from X3DH.

Problem: If Eve steals S, she can decrypt ALL past messages!

Solution: Ratcheting! Update S for every message.

  1. Alice sends message 1 to Bob, uses key K1 → Delete K1
  2. Alice sends message 2 to Bob, uses key K2 → Delete K2
  3. Alice sends message 3 to Bob, uses key K3 → Delete K3
  4. ...

Each message uses a NEW key, OLD keys are DELETED!

Like a ratchet wrench: Only moves forward (K1 → K2 → K3), never backwards!


🧠 Mental Model

Hold this picture in your head:

Without Ratcheting (Traditional):

Alice and Bob share secret S

Message 1: Encrypt with S → Decrypt with S
Message 2: Encrypt with S → Decrypt with S
Message 3: Encrypt with S → Decrypt with S
...

Problem: If Eve steals S at message 10,
she can decrypt messages 1-10!

With Ratcheting (Double Ratchet):

Alice and Bob have root key RK from S (via X3DH)

Message 1:
RK → Chain Key CK_A (sending) → Message Key K1
RK → Chain Key CK_B (receiving) → Message Key K1 (Bob's K1 matches Alice's)
Encrypt with K1 → Decrypt with K1
Delete K1, K1 can't be used again!

Message 2:
CK_A → Next Chain Key CK_A → Message Key K2
Encrypt with K2, Delete K2
CK_B → Next Chain Key CK_B → Message Key K2
Decrypt with K2, Delete K2

...

If Eve steals state at message 10:
- Can she decrypt messages 1-9? NO! Keys K1-K9 deleted!
- Can she decrypt message 10? Yes (has current state)
- Can she decrypt messages 11+? NO! Future messages need new DH ops!

📊 See It Happen

The ratchet creates a sequence of message keys K1, K2, K3, etc. Each key is used once then deleted, ensuring forward secrecy.

Alice and Bob have root key RK from X3DH

Message 1:
RK → Chain Key CK_A (sending) → Message Key K1
RK → Chain Key CK_B (receiving) → Message Key K1
Encrypt with K1, delete K1

Message 2:
CK_A → Next Chain Key → Message Key K2
CK_B → Next Chain Key → Message Key K2
Encrypt with K2, delete K2

If Eve steals state at message 10:
Messages 1-9: K1-K9 deleted - can't decrypt
Message 10: Current state - can decrypt
Messages 11+: Need new DH - can't decrypt

🎭 The Story: The Compromise

Alice and Bob have been talking for months using the Signal Protocol.

How they do it:

  1. X3DH gives them shared secret S
  2. They derive root key RK = KDF(S)
  3. For each message, they derive a new message key from RK
  4. After encrypting/decrypting, they delete that message key
  5. Root key evolves (chains to new chain keys)

Eve's attack:

Eve steals Alice's phone during message 10.

On the phone:

  • Eve finds cryptostate (RK, current chain keys, etc.)

What can Eve read?

Messages 1-9: Eve can't decrypt! Message keys K1-K9 are already deleted.

Message 10: Eve can decrypt (has current state).

Messages 11+: Eve can't decrypt! Future messages need Diffie-Hellman ratchet (new keys).

Result: Eve compromised message 10, but can't read past or future messages!

Without ratcheting (what would happen)

Eve steals shared secret S:

  • Can decrypt all messages (1 through 10+)
  • All conversations compromised!

With ratcheting (what actually happens)

Eve steals current state at message 10:

  • Can only decrypt message 10 (current)
  • Can't read 1-9 (keys deleted)
  • Can't read 11+ (need new DH ratchet)

⚙️ Ratchet Wrench Metaphor

Think of a ratchet wrench:

             🔧 Ratchet Wrench

Forward steps (can do):
K1 → K2 → K3 → K4 → K5 → ...

Backward steps (can't do):
K5 ← K4 ← K3 ← K2 ← K1 ← ...

Can't go back!

Analogy:

  • Forward: Deriving K2 from K1, K3 from K2, etc. (one-way)
  • Backward: Recovering K1 from K2 (impossible!)

Cryptographic version:

K1 = KDF(RK, message_number=1)
K2 = KDF(RK, message_number=2)
K3 = KDF(RK, message_number=3)

Given K2, Eve can't find K1 (discrete logarithm problem + KDF reversibility)


🎭 The Ratchet in Practice

Message Encryption Flow

Alice sends message 1:

Step 1: Alice has root key RK (from X3DH)

Step 2: Chain key derivation
CK_A1 = KDFR → CK (sending chain)
CK_B1 = KDFR → CK (receiving chain)

Step 3: Message key derivation
K1 = KDFCK (CK_A1 || message_number=1)

Step 4: Encrypt
Ciphertext = Encrypt("Hello Bob", K1)
MAC = MAC(Ciphertext, K1)

Step 5: Delete K1
K1 = NULL (gone forever)

Step 6: Send
Send(Ciphertext, MAC) to Bob

Step 7: Advance ratchet CK
CK_A2 = KDF(CK_A1) (next sending chain key)

Bob receives message 1:

Step 1: Bob has root key RK

Step 2: Chain key derivation
CK_B1 = KDFR → CK (receiving chain)

Step 3: Message key derivation
K1 = KDFCK (CK_B1 || message_number=1)

Step 4: Decrypt
Verify MAC
Decrypt(Ciphertext, K1)

Step 5: Delete K1
K1 = NULL (gone forever)

Step 6: Advance ratchet CK
CK_B2 = KDF(CK_B1) (next receiving chain key)

💡 Why Ratcheting?

Forward Secrecy Definition

Forward secrecy: Compromise of long-term keys doesn't compromise past messages.

In Signal Protocol terms:

  • Compromise of cryptostate at message N
  • Allows decryption of message N only
  • Does not allow decryption of messages 1 to N-1
  • Does not allow decryption of messages N+1 (need new DH)

Ratchet vs No Ratchet

PropertyNo RatchetWith Ratchet
Keys per messageSame key SNew key per message
Key storageKeep S foreverDelete key after use
Compromise at NMessages 1..NMessage N only
Past messagesCompromisedSafe
Future messagesCompromisedSafe (need new DH)

✅ Quick Check

Can you explain ratcheting?

Definition:

Ratcheting = One-way key evolution.

Root key RK → Chain key CK → Message key K[N]

K[N] used once, then deleted. Can't recover K[N] from K[N+1].

Forward secrecy: Compromise limits to current message.

Why forward secrecy matters?

Example:

Alice sends Bob her password (message 1). Eve steals phone at message 10.

No forward secrecy: Eve reads password (has key K1). Forward secrecy: Eve can't read password (K1 deleted).


📋 Key Takeaways

Ratcheting = One-way key evolution (like ratchet wrench)
Forward secrecy = Compromise doesn't expose past messages
Per message keys = K1, K2, K3 used once then deleted
Root key RK = Derived from X3DH shared secret
Chain keys = CK_A (sending), CK_B (receiving) from RK
Message keys = new keys from CK, used then deleted
Compromise limits: Current message only
Symmetric ratchet = Every message new key from chain keys
DH ratchet = New root key from DH exchange (we'll learn next!)


🎉 What You'll Learn Next

Now you understand ratcheting! Next, we'll learn about the symmetric key ratchet (creating keys per message).

⛓️ Continue: Key Chains

We'll learn how to derive message keys from chain keys, per message!


Ratcheting concept explained! Next: Symmetric key ratchet (how to derive keys per message)