Skip to content
Identity / Signed / One-Time Keys
step 1/5

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…

Identity / Signed / One-Time Keys — Build the Signal Protocol