QERYX COMING SOON
OBSERVATORY

Research Messenger

protocol-spec

The Hybrid Handshake: SP 800-227 Combiner and Entangled Session v1

Version
v1.0
Category
protocol-spec
Published
Last updated
Authors
QERYX Research
Primitives X25519 ML-KEM-1024 ML-DSA-87 HKDF-SHA-512
What changed v1.0
  1. v1.0 First publication of the hybrid combiner and ESv1 wire formats, verification rules, and the outstanding KEX-binding audit item.
Contents
  1. §1 Two interlocking layers
  2. §2 The hybrid combiner
  3. §3 Entangled Session v1
  4. §4 Verification on receive
  5. §5 Key derivation and rotation
  6. §6 The outstanding audit item
  7. §7 References

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 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 info input 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, in the library's decapsulation wrapper: an invalid ciphertext is indistinguishable from a valid one by timing, foreclosing the KyberSlash class at this layer. The combiner is X-Wing-shaped, re-instantiated at ML-KEM-1024; QERYX does not claim the X-Wing IND-CCA2 proof, which is specific to the -768 parameter set — the disclaimer sits in the source header.

Entangled Session v1

Four goals, each carried by a wire field:

  • The handshake salt commits to the responder's exact key bundle and both key-exchange halves, so the derived secret is pinned to this pairing and neither side unilaterally controls it.
  • Each leg is signed with ML-DSA-87 under its own context — QERYX-ES-INIT-v1 for the initiator, QERYX-ES-RESP-v1 for the responder — so a signature from one direction cannot replay in the other.
  • 32-byte nonces drawn from the operating system's CSPRNG, 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. Keys come from the operating system's CSPRNG; the server-relayed pool is conditioned in as defense in depth and never relied on alone.

The signed initiator message concatenates version, both public keys, the 64-byte seed 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

StepResponder checks (init)Initiator checks (response)
1protocol version = 1nonce echo, compared constant-time
2timestamp within 300 sprotocol version = 1
3signature under QERYX-ES-INIT-v1signature under QERYX-ES-RESP-v1
4encapsulate to initiator's ML-KEM keydecapsulate the ciphertext
5derive keys, state → Activederive 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

// Messaging bootstrap — the 1:1 schedule
root    = HKDF-SHA-512(x25519_dh || ml_kem_ss,
                       salt = recipient_fp || SHA-256(eph_pk || ml_kem_ct),
                       info = "QERYX_SESSION_v4_ROOT", 32)
chain_a = HKDF-SHA-512(root, salt, info = "QERYX_SESSION_v1_CHAIN_A", 32)
chain_b = HKDF-SHA-512(root, salt, info = "QERYX_SESSION_v1_CHAIN_B", 32)

// Call bootstrap — where both peers' seed contributions do enter the key
ikm     = hybrid_ss || initiator_seed || responder_seed
send    = HKDF-SHA-512(ikm, salt = "ENTANGLED-SESSION-v2", info = "esp-send-key", 32)
recv    = HKDF-SHA-512(ikm, salt = "ENTANGLED-SESSION-v2", info = "esp-recv-key", 32)

The messaging bootstrap deliberately keeps the seed out of the root derivation — the seed rides the wire signed and bound into the AEAD's associated data, so a tampered seed fails Poly1305 rather than silently splitting the two chains.

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; the open item is defense-in-depth against a relay that also tries to precompute. It is tracked in Known Limitations §1.

References

  1. QERYX Protocol Specification §5 — docs/SPEC/03-handshake-and-session.md; implementation crypto-core/src/hybrid.rs, crypto-core/src/session.rs.
  2. NIST SP 800-227 — Recommendations for Key-Encapsulation Mechanisms, §6.2.
  3. NIST FIPS 203 (ML-KEM), FIPS 204 (ML-DSA §5.2 context framing).
  4. RFC 7748 — Elliptic Curves for Security (X25519).
  5. X-Wing KEM combiner proof — IACR ePrint 2024/039 (parameter-set caveat in body).
  6. Understand the Handshake — the plain-language companion to this chapter.