[RFC] Post-Quantum Transport Security — phase 0, hybrid key exchange - #429
Open
megonen wants to merge 1 commit into
Open
[RFC] Post-Quantum Transport Security — phase 0, hybrid key exchange#429megonen wants to merge 1 commit into
megonen wants to merge 1 commit into
Conversation
…ybrid post-quantum key exchange Adds a Transport Security section to P2P Network — the first normative statement of the canonical TLS configuration of the stack: TLS 1.3, the AEAD cipher suites, the libp2p peer authentication model, and the key exchange, requiring the hybrid group X25519MLKEM768 alongside the existing X25519. Phase 0 of the post-quantum transition: key exchange only; signatures are named as a later phase. Blend Protocol's Connection Details now follows that section and states the hybrid requirement together with its privacy motivation, replacing the phrase that conflated the identity key with two ephemeral objects.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[RFC] Post-Quantum Transport Security — phase 0, hybrid key exchange
Reviewer Orientation
Read Motivation first — this PR does two things at once, and only one of
them is about post-quantum cryptography. Assumed background: none; apart from
one sentence in the Blend Protocol, the transport handshake has not been
specified before, so there is almost no prior text to reconcile against.
X25519MLKEM768, and prefer it. Check that retainingX25519keeps the network reachable during migration, and that the requirement names no library.Status tracker
Change log
Motivation
Harvest now, decrypt later. An adversary recording traffic today can decrypt
it once a cryptographically-relevant quantum computer exists. The exposure is
accruing now and is only realised later, which is what makes confidentiality
the property with a deadline that has already started. The sharpest consumer of
that property is the Blend Protocol: recorded traffic that becomes decryptable
would retroactively degrade the privacy the mixnet exists to provide.
Authentication does not share that property. A signature cannot be forged
retroactively: an adversary who breaks Ed25519 in the future cannot return to a
completed handshake and impersonate a peer in it. This asymmetry is the whole
basis for phasing the work — key exchange now, signatures later — and it is why
this PR is narrow.
And the transport handshake is almost entirely unspecified. The only
cipher-suite-level statement in the specifications is one sentence in the Blend
Protocol's Connection Details. No specification states the key exchange or the
peer authentication model, so there is no normative statement of what key
exchange Logos nodes perform, and therefore nowhere to change it. Closing that
gap is work this PR has to do first, and is worth doing independently of
post-quantum.
Proposal
Add a Transport Security section to P2P Network, stating the canonical
TLS configuration of the stack — TLS 1.3, the AEAD cipher suites, the libp2p
peer authentication model, and the key exchange — and requiring the hybrid key
exchange group
X25519MLKEM768alongside the existingX25519. Update theBlend Protocol's Connection Details to follow that section and to state the
hybrid requirement together with its privacy motivation.
The placement follows the maintainers' guidance rather than a dedicated TLS
specification: the Blend Protocol is where connection security was already
specified — and a good place for the phase-0 statement, since the phase
addresses Blend's privacy concerns — while the P2P Network specification is
where the configuration of the whole stack belongs, because the transport is
one node-wide libp2p configuration shared by every protocol carried over it.
The change is confined to the key exchange. Signatures — the Ed25519 node
identity and everything derived from it — are unchanged and are named as the
next phase.
Discussion
Why hybrid rather than pure ML-KEM
The hybrid derives its secret from both components, so it is secure unless both
are broken. If ML-KEM-768 is found to be weak, X25519 still provides classical
security; if X25519 falls to a quantum adversary, ML-KEM-768 holds. A pure
post-quantum group would trade one single point of failure for another, against
a primitive with far less deployment history. The cost of carrying both is one
X25519 operation.
Why
X25519MLKEM768specificallyThe parameter set and the classical half were both chosen against measurements
we took ourselves (
reports/pqc), which is what allows the alternatives to bepriced on one basis rather than compared across sources.
Parameter set. All three ML-KEM parameter sets were measured on the
reference Raspberry Pi 5 (liboqs, medians):
The compute differences do not matter at this scale — all three are tens of
microseconds against a handshake measured in milliseconds. The decision is
security level against wire size. ML-KEM-768 is NIST Level 3: 512 is thin for a
protocol constant that will outlive several hardware generations, and 1024 buys
a level nobody is asking for at 480 bytes more per handshake.
Classical half.
SecP256r1MLKEM768exists and is supported by the samestacks.
X25519is what the network deploys today, and the classical half of ahybrid should be the curve already trusted in the deployment rather than a
second one introduced beside it.
Ecosystem.
X25519MLKEM768is the group go-libp2p already advertises andthe one rustls prefers by default, so this is the interoperable choice as well
as the measured one.
Excluded by measurement. Classic McEliece is disqualified on receiver cost,
and on the reference Pi 5 the data is unusually blunt about it: decapsulation
costs 25.7 ms to 136.5 ms against ML-KEM-768's 37 µs, a decoder-to-encoder ratio
of 306–526 against 1.17. Flooding its decapsulator buys roughly four orders of
magnitude more receiver CPU per byte sent than anything else measured. (The gap
is architecture-dependent — a vectorised x86 decoder narrows it substantially —
but the reference platform is the Pi, and the exclusion below stands on any
platform.) BIKE, HQC and NTRU have no TLS codepoint and no stack support, so
they are not deployable here whatever their merits.
Cost
Measured on the reference Raspberry Pi 5, classical against hybrid on the same
stack in the same pass (
reports/pqc):Those are TCP-TLS figures, and QUIC — which is what we actually run — turns
out to be cheaper. Measured on the real quinn + rustls stack, varying the key
exchange group and nothing else
(
tools/benchmarks/pq-transport/quic-handshake, logos-blockchain/research#11):X25519X25519MLKEM768Three results, two of which were not guessable in advance.
No additional round trip. A packet trace shows the flight structure is
identical in both arms — client flight, server flight, client flight — and only
the number of datagrams per flight changes. On a real link, where handshake
latency is set by round-trip time rather than by CPU, the hybrid group therefore
costs approximately nothing in latency.
QUIC absorbs part of the size cost: ×1.47 against TCP-TLS's ×2.49. A QUIC
Initial is padded to at least 1200 bytes whatever it carries, so the classical
handshake is already paying for padding that the hybrid simply fills.
Anti-amplification is not a constraint, and moves in the defender's favour.
A QUIC server may not send more than three times what it has received before
validating the peer's address. The larger client flight raises that allowance
from 3600 to 7200 bytes, against 1338 and 2538 actually sent. Neither arm
approaches the limit, and the hybrid has more headroom than the classical one.
(The wall-clock figure from the QUIC harness is deliberately not quoted here.
On loopback it is dominated by scheduler wakeups, spanning 0.6–2.0 ms across
runs of the same arm on the same machine. The key exchange's CPU cost is small
and is measured properly in the table above.)
Bigger is not only a cost
An attacker floods bandwidth, so what bounds a flood is receiver CPU purchased
per byte sent. On the reference Pi 5, X25519 yields 5.2 µs/byte; ML-KEM-768
yields 34 ns/byte — 150× less. The larger wire objects, normally counted as
the migration's price, are a defensive asset against flooding.
Interoperability and rollout
TLS negotiates the group, so a conforming node and a peer on the current stack
agree on
X25519with no special handling. There is no flag day, no coordinatedupgrade and no version gate. Nodes gain the property as they upgrade, and the
network is protected in proportion to adoption.
This also means the property is obtained per-connection rather than
network-wide, which the Post-Quantum Scope subsection states rather than
leaving implicit.
Why this does not touch the Service Declaration Protocol
Worth setting out explicitly, because "post-quantum transition" invites the
assumption that identities are in scope.
provider_idis an Ed25519 signature key. It is the node identity, it isembedded in every
Locator, it is hashed intodeclaration_id = blake2b(service ‖ provider_id ‖ zk_id ‖ locators), and itsigns SDP messages. This PR changes the key exchange, which in TLS 1.3 is
ephemeral per handshake, is never persisted, and appears in no protocol message
outside the handshake. Nothing SDP-visible moves: not
provider_id, notdeclaration_id, not the locator format, not declaration sizes.Service reward distribution is further removed still — rewards are paid to
zk_id, which never enters the transport handshake at all.The next phase, named but not proposed here
Migrating
provider_idto a post-quantum signature (ML-DSA) is the naturalnext step, and it is a substantially larger change precisely because SDP is in
scope: declaration sizes,
declaration_id, the locator format, and an on-chainmigration for every declared provider. Upstream tracking exists
(rust-libp2p#6462).
Keeping the phases apart is deliberate. "PQ transition" should not read as one
change, and the confidentiality/authentication asymmetry in Motivation is what
justifies doing them in this order rather than together.
Details
1. Key exchange (P2P Network § Transport Security)
Nodes MUST offer
X25519MLKEM768(IANA named group0x11EC) and MUSToffer it as the most-preferred group. Nodes MUST continue to offer
X25519.Both are MUSTs, and the second is the one worth arguing. Requiring the group to
be offered but only recommending it be preferred would permit a node to
negotiate away the property this requirement exists to provide, silently and
by configuration alone. The preference costs nothing in practice — it is already
the default behaviour of the stacks that support the group.
Key exchange material is ephemeral per handshake and MUST NOT be persisted,
reused across connections, or transmitted outside the handshake. No new wire
structure is introduced; the section gives the group codepoints and share sizes.
2. Post-Quantum Scope (P2P Network § Transport Security)
States what the phase does not affect, as a table a reviewer can check rather
than infer: the node identity signature, the certificate signature,
declaration_id, locators, declaration size, SDP messages, service rewards,and the record-layer AEAD. Also states what is deliberately deferred
(authentication, until the next phase), the downgrade behaviour that
interoperability requires, and why the larger handshake is not an amplification
concern on QUIC.
3. Handshake and peer authentication (P2P Network § Transport Security)
First normative statement of what is already deployed: TLS 1.3 only, the three
TLS 1.3 AEAD cipher suites, and the libp2p TLS authentication model — a
self-signed certificate carrying the identity key in the libp2p Public Key
Extension, with the identity key signing
libp2p-tls-handshake:‖certificate_public_key.The node identity key is Ed25519 and is the same key SDP declares as
provider_id.The certificate's own key algorithm is deliberately left unspecified. It is
unrelated to the identity key, carries no protocol meaning, and constraining it
would create an interoperability requirement with no corresponding benefit.
4. Connection Details (Blend Protocol)
The Connection Details section currently reads "TLS 1.3 … the cryptographic
scheme is Ed25519 with ephemeral keys". That phrase packs a static identity
key together with two different ephemeral objects, and was the likeliest source
of the scoping question this PR had to answer. It is replaced by text that
follows the Transport Security section, states the hybrid requirement, and
names Blend's privacy as its sharpest motivation. Nothing normative is lost:
TLS 1.3 remains stated, and the identity and ephemeral layers are now
distinguished instead of conflated.
Implementation
X25519MLKEM768as thepreferred group while retaining
X25519.default.
X25519successfully.flight, flight structure
(
tools/benchmarks/pq-transport/quic-handshake).toolchain is required, so check cross-compilation and container images.
hybrid group offered and preferred,
X25519retained, no key exchangematerial persisted.
Known constraint: no released dependency offers the group yet
Recorded so this is not read as deployable today. This is a constraint rather
than a decision — the mechanism is an engineering call and the specification
deliberately mandates no stack.
rust-libp2p fixes its TLS crypto provider to
ring, which ships no ML-KEM.Upstream merged the change to a provider that has it
(rust-libp2p#6568, 2026-07-31),
but no released version carries it:
libp2p-tlsis 0.6.2 (2025-06-27) andlibp2p0.56.0, while master has moved to 0.7.0 / 0.14.0.Patching
libp2p-tlsalone does not work:libp2p-quic0.13.1 requireslibp2p-tls ^0.6and master is 0.7.0.The QUIC measurement above required an equivalent dependency regardless, so the
production mechanism does not have to be settled before the specification is
agreed.
Affected Specifications
provider_id,zk_idanddeclaration_idare signature-side and unaffected by a key-exchange change. Listed so the omission is checked rather than assumed.zk_id, which never enters the transport handshake.