Reading — step 1 of 5
Read
~1 min readFoundations: X3DH
Identity / Signed / One-Time Keys
Each Signal user has multiple key types:
- Identity Key (IK): long-lived. Curve25519 keypair. Identifies the user across all sessions.
- Signed Pre-Key (SPK): medium-lived (rotated weekly/monthly). Signed by IK to prove ownership.
- One-Time Pre-Keys (OPK): bag of fresh keypairs. Each one used once and deleted.
Why three types?
- IK alone: leak of IK = total compromise. We want forward secrecy.
- IK + SPK: forward secrecy if SPK rotates. But long-lived IK signature proves SPK ownership.
- IK + SPK + OPK: each session also includes a unique OPK → strong forward secrecy even if SPK key leaks later.
Server stores per-user:
{
user: alice
ik_pub: <bytes>
spk_pub: <bytes>
spk_signature: <ik signs spk_pub>
opk_bag: [opk_1, opk_2, ..., opk_n] // each used once
}
When Bob wants to message Alice, the server gives him:
- Alice's IK_pub
- Alice's SPK_pub + SPK signature (Bob verifies with IK_pub)
- One OPK_pub from the bag (server pops it)
Bob runs X3DH with his ephemeral key + Alice's three keys, derives a shared root key, encrypts a first message, and uploads.
Alice (when next online) downloads, runs her side of X3DH to derive the same key, decrypts.
Key rotation:
- IK: rotated rarely (re-verify via QR/safety number).
- SPK: weekly/monthly. Old SPKs deleted from server; old sessions still work via stored derived keys.
- OPK: each used once; replenished when bag low.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…