Building a Secure Messenger From Scratch
Part 2 of 6. Diffie–Hellman, key derivation, authenticated encryption, and the ratchets that protect past and future messages.
Outline — prose not written
This is a protocol-level outline, not a complete description of Signal. Signal-specific prekeys and identity authentication belong in Part 3.
Throughline
Each layer solves the problem left by the previous one: agree on a secret, turn it into keys, protect ciphertext integrity, then replace compromised keys.
1. Agreeing on a secret
- Introduce a cyclic group of prime order with generator .
- Keep the hardness hierarchy precise:
A discrete-log solver breaks CDH and DDH; the reverse implications are not known in general.
- Walk through Diffie–Hellman:
- Mention ElGamal as Diffie–Hellman turned into public-key encryption.
Reference: Katz–Lindell §9.3; Boneh–Shoup §15.1–15.3
2. Deriving usable keys
- Explain why is not used directly: it has structure, the wrong format, and one key should not serve multiple purposes.
- Use HKDF to extract uniform key material and expand labeled subkeys:
- State the rule: separate keys by purpose and direction.
Reference: Boneh–Shoup §8.7.2, §8.10.5
3. Authenticating ciphertexts
Compare the three generic compositions:
| Composition | Problem |
|---|---|
| Encrypt-and-MAC | The plaintext MAC may leak equality or other information. |
| MAC-then-Encrypt | Decryption happens before authentication; generic CCA security does not follow. |
| Encrypt-then-MAC | Verify before decrypting; CPA encryption plus strong unforgeability gives generic CCA security. |
- Use padding-oracle attacks as the concrete MAC-then-encrypt failure mode.
- Keep the lesson: secure primitives do not guarantee secure composition.
Reference: Katz–Lindell §5.1–5.3
4. Ratcheting keys
- Ask what happens when today's device state leaks.
- Define:
- Forward secrecy: current compromise does not expose deleted past keys.
- Post-compromise security: fresh secret input lets the conversation recover.
- Separate the two ratchets:
- Symmetric-key ratchet: derive and delete one message key per message.
- Diffie–Hellman ratchet: mix in a fresh DH secret when the sending direction changes.
- Walk one exchange: Bob sends ; both sides mix into the root chain and delete superseded keys.
- Mention skipped-message keys and bounded out-of-order delivery.
Reference: Signal's Double Ratchet specification
5. Implementation notes
- Use the chained-CBC near-miss to show that passing round-trip tests does not imply a secure construction.
- Record C++ and library friction:
- nonce and IV ownership
- byte/string conversions
- key separation
- key deletion
- which mistakes types catch versus which need adversarial tests
Assumptions introduced
- Discrete logarithm, CDH, and DDH hardness in the selected group.
- Secure KDF, encryption, and MAC primitives.
Go deeper
- Katz–Lindell ch. 5 and §9.3
- Boneh–Shoup §9 and §15.1–15.3
- Signal's Double Ratchet specification
- Scribed applied cryptography notes, §3.3–5.3
Cryptography is About Definitions, Not Secrets
Part 1 of 6. Encryption syntax, security parameters, perfect and semantic security, IND-CPA, and the reduction from a definition to a construction.
Who Are You Talking To?
Part 3 of 6. Man-in-the-middle attacks, signatures, certificate chains, passwords, and second factors.