2.1. X3DH parameters
An application using X3DH must decide on several parameters:
| Name | Definition |
|---|---|
| curve | X25519 or X448 |
| hash | A 256 or 512-bit hash function (e.g. SHA-256 or SHA-512) |
| info | An ASCII string identifying the application |
For example, an application could choose curve as X25519, hash as SHA-512, and info as "MyProtocol".
An application must additionally define an encoding function Encode(PK) to encode an X25519 or X448 public key PK into a byte sequence. The recommended encoding consists of some single-byte constant to represent the type of curve, followed by little-endian encoding of the u-coordinate as specified in [1].
2.2. Cryptographic notation
X3DH will use the following notation:
The concatenation of byte sequences X and Y is
X || Y.DH(PK1, PK2)represents a byte sequence which is the shared secret output from an Elliptic Curve Diffie-Hellman function involving the key pairs represented by public keys PK1 and PK2. The Elliptic Curve Diffie-Hellman function will be either the X25519 or X448 function from [1], depending on the curve parameter.Sig(PK, M)represents a byte sequence that is an XEdDSA signature on the byte sequence M and verifies with public key PK, and which was created by signing M with PK's corresponding private key. The signing and verification functions for XEdDSA are specified in [2].KDF(KM)represents 32 bytes of output from the HKDF algorithm [3] with inputs:- HKDF input key material =
F || KM, where KM is an input byte sequence containing secret key material, and F is a byte sequence containing 320xFFbytes if curve is X25519, and 570xFFbytes if curve is X448. F is used for cryptographic domain separation with XEdDSA [2]. - HKDF salt = A zero-filled byte sequence with length equal to the hash output length.
- HKDF info = The info parameter from Section 2.1.
- HKDF input key material =
2.3. Roles
The X3DH protocol involves three parties: Alice, Bob, and a server.
Alice wants to send Bob some initial data using encryption, and also establish a shared secret key which may be used for bidirectional communication.
Bob wants to allow parties like Alice to establish a shared key with him and send encrypted data. However, Bob might be offline when Alice attempts to do this. To enable this, Bob has a relationship with some server.
The server can store messages from Alice to Bob which Bob can later retrieve. The server also lets Bob publish some data which the server will provide to parties like Alice. The amount of trust placed in the server is discussed in Section 4.7.
In some systems the server role might be divided amongst multiple entities, but for simplicity we assume a single server that provides the above functions for Alice and Bob.
2.4. Keys
X3DH uses the following elliptic curve public keys:
| Name | Definition |
|---|---|
| IK_A | Alice's identity key |
| EK_A | Alice's ephemeral key |
| IK_B | Bob's identity key |
| SPK_B | Bob's signed prekey |
| OPK_B | Bob's one-time prekey |
All public keys have a corresponding private key, but to simplify description we will focus on the public keys.
The public keys used within an X3DH protocol run must either all be in X25519 form, or they must all be in X448 form, depending on the curve parameter [1].
Each party has a long-term identity public key (IK_A for Alice, IK_B for Bob).
Bob also has a signed prekey SPK_B, which he will change periodically, and a set of one-time prekeys OPK_B, which are each used in a single X3DH protocol run. ("Prekeys" are so named because they are essentially protocol messages which Bob publishes to the server prior to Alice beginning the protocol run).
During each protocol run, Alice generates a new ephemeral key pair with public key EK_A.
After a successful protocol run Alice and Bob will share a 32-byte secret key SK. This key may be used within some post-X3DH secure communication protocol, subject to the security considerations in Section 4.