Session establishment runs two interlocking layers: a NIST SP 800-227
hybrid KEM combiner over X25519 +
ML-KEM-1024, and Entangled Session v1 — the
mutual-authentication handshake in which both peers contribute 64 bytes
of certified-QRNG entropy, sign their legs under distinct FIPS 204
contexts, and echo nonces in constant time. The Q-Ratchet bootstraps
from the result and takes over for every message that follows.
Two interlocking layers
The hybrid combiner is the key-encapsulation core used everywhere a
session-establishment exchange runs. ESv1 is the protocol around it:
identity signatures, entropy contributions, replay protection, and state
transitions. Breaking a session requires breaking both
X25519 and ML-KEM-1024.
The hybrid combiner (SP 800-227)
HybridEncapsulate(pk_X25519, pk_ML-KEM):
1. ek ← X25519.EphemeralKeyGen()
2. ss_X25519 = X25519(ek.secret, pk_X25519) // 32 B
3. (ct, ss_ML-KEM) ← ML-KEM-1024.Encaps(pk_ML-KEM) // FIPS 203
4. ss_hybrid ← HKDF-SHA-512(
IKM = ss_ML-KEM || ss_X25519,
salt = "QERYX-HYBRID-v2-ML-KEM-1024-X25519",
info = pk_X25519 || ct || "QERYX-HYBRID-NIST-SP-800-227-v2",
len = 32)
The construction carries four properties, each by a named mechanism:
- IND-CCA2 if either component holds — the SP 800-227 §6.2 concatenation argument.
- Key binding — the ciphertext-bearing salt.
-
Public-key binding — the
infoinput binds the X25519 public key and the ML-KEM ciphertext, which itself commits to the encapsulation key internally per FIPS 203. - Domain separation — the wire-stable protocol-version suffix.
Decapsulation always runs the full implicit-rejection path: an invalid ciphertext is indistinguishable from a valid one by timing, foreclosing the KyberSlash class at this layer. A separate SHA3-256 hash combiner shaped like the X-Wing draft exists for opt-in protocols; QERYX does not claim the X-Wing IND-CCA2 proof, which is specific to the -768 parameter set — the disclaimer ships in the source header.
Entangled Session v1
Four goals, each carried by a wire field:
- Each peer contributes 64 bytes of certified-QRNG entropy, so neither side can unilaterally control the session secret.
-
Each leg is signed with
ML-DSA-87under its own context —QERYX-ES-INIT-v1for the initiator,QERYX-ES-RESP-v1for the responder — so a signature from one direction cannot replay in the other. - 32-byte QRNG-sourced nonces, echoed inside the responder's signed payload.
- A ±300-second timestamp window on handshake acceptance.
This is not QKD. Not quantum networking. Not quantum teleportation. We do not violate the no-communication theorem. We bind a key-derivation function to a verifiable physical measurement no classical adversary can fabricate in advance.
The signed initiator message concatenates version, both public keys, the QRNG contribution, the little-endian timestamp, and the nonce — in that exact order. The responder's signed message additionally binds the ML-KEM ciphertext and the initiator's nonce echo, which makes the transcript commitment mutual.
Verification on receive
| Step | Responder checks (init) | Initiator checks (response) |
|---|---|---|
| 1 | protocol version = 1 | nonce echo, compared constant-time |
| 2 | timestamp within 300 s | protocol version = 1 |
| 3 | signature under QERYX-ES-INIT-v1 | signature under QERYX-ES-RESP-v1 |
| 4 | encapsulate to initiator's ML-KEM key | decapsulate the ciphertext |
| 5 | derive keys, state → Active | derive keys, state → Active |
The load-bearing replay claim: a captured handshake cannot be relayed to a different responder and still decrypt for the original initiator, because the responder's signature commits to the initiator's nonce echo.
Key derivation and rotation
ikm = initiator_qseed || responder_qseed || ss_ML-KEM
send = HKDF-SHA-512(ikm, salt = "ENTANGLED-SEND", info = "Qeryx-v1", 32)
recv = HKDF-SHA-512(ikm, salt = "ENTANGLED-RECV", info = "Qeryx-v1", 32)
auth = HKDF-SHA-512(ikm, salt = "ENTANGLED-AUTH", info = "Qeryx-v1", 32)
The responder swaps send and receive keys so both sides agree on direction; the input keying material is zeroized on the stack before return. ESv1 keys rotate at 100 messages or 24 hours, whichever comes first — and in practice the Q-Ratchet supersedes them immediately, keeping ESv1 as the bootstrap root only. The message counter advances by checked arithmetic: on exhaustion the session hard-errors and forces a fresh handshake rather than reusing chain state — an external review finding (F-003) closed with exactly this change.
The outstanding audit item — stated, not hidden
One v1.1 hardening item remains open at this spec snapshot:
server-contributed transcript binding for relayed handshakes — a
server-side ephemeral entropy contribution bound into the transcript hash
on both sides. The hybrid combiner already binds every transcript public
key and ciphertext into the HKDF info, which forecloses
cross-protocol replay today; the open item is defense-in-depth against a
relay that also tries to precompute. It is tracked in
Known Limitations §1.
References
-
QERYX Protocol Specification §5 —
docs/SPEC/03-handshake-and-session.md; implementationcrypto-core/src/hybrid.rs,crypto-core/src/session.rs. - NIST SP 800-227 — Recommendations for Key-Encapsulation Mechanisms, §6.2.
- NIST FIPS 203 (ML-KEM), FIPS 204 (ML-DSA §5.2 context framing).
- RFC 7748 — Elliptic Curves for Security (X25519).
- X-Wing KEM combiner proof — IACR ePrint 2024/039 (parameter-set caveat in body).
- Understand the Handshake — the plain-language companion to this chapter.