🤝 What is X3DH?
Extended Triple Diffie-Hellman Explained
In 10 minutes: Understand X3DH - the initial handshake for Signal Protocol
Prerequisite: Diffie-Hellman + Signatures
🎯 The Simple Story
Alice wants to send a message to Bob, but Bob is offline.
Problem: Alice has never met Bob. How can she trust Bob's keys?
Solution: X3DH - Extended Triple Diffie-Hellman (actually four Diffie-Hellman operations!)
- Bob publishes keys to a server (while offline)
- Alice downloads Bob's public keys
- Alice sends an initial message
- Four Diffie-Hellman operations combine to create a shared secret
- Alice and Bob both derive the same secret!
Even if Eve watches, she can't compute the same secret!
🧠 Mental Model
Hold this picture in your head:
X3DH = Extended Triple Diffie-Hellman
Actually uses FOUR Diffie-Hellman operations:
DH1 = Alice_Identity × Bob_SignedPrekey
DH2 = Alice_Ephemeral × Bob_Identity
DH3 = Alice_Ephemeral × Bob_SignedPrekey
DH4 = Alice_Ephemeral × Bob_OneTimePrekey
Shared Secret = KDF(DH1 || DH2 || DH3 || DH4)
Alice computes all 4 → gets S
Bob computes all 4 → gets S
Eve watches everything, still can't compute S!
Think of it like:
🤝 Four-handshake agreement (Four layers of security)
🔐 Quad-lock security (Need to unlock 4 doors)
⚔️ Four-shield protection (Aim for 4 weaknesses to break)
📊 See It Happen
Let's watch the X3DH handshake:
🎭 The Story: Alice and Sleeping Beauty
Bob is always busy. He sleeps for months at a time (goes offline).
Alice needs to message Bob secretly. But Alice never met Bob!
Step 1: Bob prepares before sleeping
Bob creates keys:
- Identity key (permanent)
- Signed pre-key (changes every week)
- One-time pre-key (used once then deleted)
- Signature of signed pre-key
Bob uploads all to a server, then powers down his computer (offline).
Step 2: Six months later, Alice needs to message Bob
Alice wakes up and realizes: "I need to send Bob a secret!"
Alice downloads Bob's public keys from the server.
Alice verifies: Is this really Bob's signed pre-key? (Checks signature)
Alice generates: alice_ephemeral (temporary key, only for this message)
Step 3: Alice computes 4 DH operations
Alice computes:
- DH1 = alice_identity × bob_signed_prekey
- DH2 = alice_ephemeral × bob_identity
- DH3 = alice_ephemeral × bob_signed_prekey
- DH4 = alice_ephemeral × bob_one_time_prekey
Alice derives: S = KDF(DH1 || DH2 || DH3 || DH4) (shared secret)
Step 4: Alice sends initial message
Alice sends encrypted initial message + alice_ephemeral to Bob's server.
Server holds it until Bob comes online.
Step 5: Bob wakes up!
Bob receives Alice's message, extracts alice_ephemeral.
Bob computes the SAME 4 DH operations:
- DH1: bob_signed_prekey × alice_identity (same as Alice's, just reversed)
- DH2: bob_identity × alice_ephemeral (same)
- DH3: bob_signed_prekey × alice_ephemeral (same)
- DH4: bob_one_time_prekey × alice_ephemeral (same)
Bob derives: S = KDF(DH1 || DH2 || DH3 || DH4) (same S as Alice!)
Step 6: Both Alice and Bob have S!
Now they can use S for the Double Ratchet (forward secrecy encryption).
Eve's problem: Eve watched all keys except... Alice's ephemeral! Alice hasn't even created it when Bob uploaded his keys. So Eve can't compute DH2, DH3, DH4!
Result: Alice and Bob share a secret, Eve can't compute it!
🎮 Try It Yourself
Question 1: Why does X3DH need FOUR Diffie-Hellman operations? Why not just one?
Show Answer
Because each DH operation provides a different type of security!
- DH1 (Alice_Identity × Bob_SignedPrekey): Long-term security
- DH2 (Alice_Ephemeral × Bob_Identity): Forward secrecy property
- DH3 (Alice_Ephemeral × Bob_SignedPrekey): Mixes into entropy
- DH4 (Alice_Ephemeral × Bob_OneTimePrekey): Deniability + extra security
Each operation:
- Adds more entropy (randomness)
- Covers different compromise scenarios
- Creates a stronger shared secret than any single DH
One DH operation would be vulnerable to:
- Compromise of Alice's identity key
- Compromise of Bob's identity key
- Replay attacks
Four operations cover all these cases and more!
Answer: Each DH adds different security properties, combined provide stronger security
Question 2: What if Eve steals Alice's ephemeral key after Alice sends the message?
Show Answer
Eve still can't compute the shared secret!
Why? Because Alice's ephemeral key was created AFTER Bob uploaded his keys!
Eve didn't have:
- Alice_ephemeral when Bob uploaded keys
- So Eve couldn't precompute: alice_ephemeral × Bob's keys
By the time Eve gets alice_ephemeral from Alice's message:
- Alice already used Bob's one-time pre-key (it's deleted)
- Eve can't recompute DH4 (Bob's one-time pre-key is gone if Eve tries to impersonate Alice to Bob)
Each one-time pre-key is used once then deleted!
Answer: Bob's one-time pre-key is used once then deleted, Eve can't compute DH4
Question 3: Why is the "Triple" DH actually FOUR diffie-hellman operations?
Show Answer
Historical naming! The protocol evolved:
- Original: Triple DH (3 operations)
- Later: Added DH4 (ephemeral × one-time pre-key) for extra properties
- Name stayed "Triple DH" but operation count is 4!
DH4 provides:
- Deniability (Alice can deny sending the message)
- Extra security against compromise
- Better forward secrecy
Answer: Historical name, but protocol evolved to 4 DH operations
🔢 The Math
X3DH Step-by-Step
Setup (Bob uploads to server):
Bob creates:
- IK_B (Identity Key Bob) = public/private key pair
- SPK_B (Signed Pre-Key Bob) = public/private key pair
- OPK_B (One-Time Pre-Key Bob) = public/private key (optional, deleted after use)
Bob signs: SIG_B = Sign(SPK_B, IK_B) (signature of signed pre-key with identity key)
Bob uploads to server:
- pk(IK_B), pk(SPK_B), pk(OPK_B), SIG_B
Alice downloads from server:
Alice downloads:
- pk(IK_B), pk(SPK_B), pk(OPK_B), SIG_B
Alice verifies:
Alice checks: Is SIG_B valid for pk(SPK_B) using pk(IK_B)?
- If yes: Bob's keys, proceed
- If no: Eve replaced keys, reject!
Alice generates ephemeral:
Alice creates:
- EK_A (Ephemeral Key Alice) = public/private key pair
Alice computes 4 DH operations:
DH1 = DH(sk(IK_A), pk(SPK_B)) ← Alice_identity × Bob_signed_prekey
DH2 = DH(sk(EK_A), pk(IK_B)) ← Alice_ephemeral × Bob_identity
DH3 = DH(sk(EK_A), pk(SPK_B)) ← Alice_ephemeral × Bob_signed_prekey
DH4 = DH(sk(EK_A), pk(OPK_B)) ← Alice_ephemeral × Bob_one_time_prekey
Shared Secret:
SK = KDF(DH1 || DH2 || DH3 || DH4)
Alice sends:
Alice sends encrypted message + pk(EK_A) to Bob
Bob receives and computes:
Bob extracts: pk(EK_A) from Alice's message
Bob computes DH1, DH2, DH3, DH4 (using his private keys)
Bob derives: SK = KDF(DH1 || DH2 || DH3 || DH4)
Both now have the same shared secret SK!
💡 Why We Care
Why X3DH Matters
Without X3DH:
- Alice can't establish trust with offline Bob
- No secure way to start a conversation
- Eve could replace Bob's keys with hers
With X3DH:
- Alice can message offline Bob securely
- Four layers of DH operations ensure security
- Each one-time pre-key used once (deleted after)
- Eve can't compute shared secret (missing ephemeral keys at key upload time)
Signal Protocol Flow
X3DH (Initial Handshake):
Alice downloads Bob's keys
Alice verifies signatures
Alice generates ephemeral
Alice computes 4 DH → Shared secret SK
Alice sends initial message
Bob receives message
Bob extracts ephemeral
Bob computes 4 DH → Shared secret SK
Alice and Bob both have SK!
Double Ratchet (Ongoing conversation):
Use SK to derive root key (RK)
Use RK to derive chain keys and message keys
Encrypt messages with new key each time
Delete keys after use (forward secrecy)
We'll learn Double Ratchet next!
✅ Quick Check
Can you explain X3DH to a 5-year-old?
Try saying this out loud:
"Bob leaves his keys in a mailbox while he's sleeping. Alice comes along and wants to leave him a secret. She takes his keys, adds her own secret key, and creates a special lock. Bob wakes up, uses his key and Alice's key, and opens the same secret. Both have the same secret, but a bad person watching can't figure it out!"
Why four DH operations?
Four benefits:
- DH1: Long-term identity security
- DH2: Forward secrecy
- DH3: Extra entropy
- DH4: Deniability + one-time use
Combined = Maximum security!
📋 Key Takeaways
✅ X3DH = Extended Triple Diffie-Hellman (actually 4 DH operations)
✅ Purpose: Establish initial shared secret with offline user
✅ Four DH: Identity × signed-prekey, ephemeral × identity, ephemeral × signed-prekey, ephemeral × one-time
✅ One-time pre-key: Used once then deleted
✅ Shared secret: Derived from combining all 4 DH results
✅ Alice's role: Generate ephemeral, download Bob's keys, compute 4 DH
✅ Bob's role: Uses ephemeral from Alice, computes same 4 DH
✅ Next: Use shared secret for Double Ratchet
🎉 What You'll Learn Next
Now you understand X3DH! Next, we'll learn about the different types of keys X3DH uses.
🗝️ Continue: Four Types of Keys
We'll explore identity keys, signed pre-keys, one-time pre-keys, and ephemeral keys - what each does and why!
X3DH explained! Now let's learn about the four types of keys used in X3DH.