Skip to content

tls: enable hybrid post-quantum key exchange (X25519MLKEM768) - #421

Open
ramnbt wants to merge 1 commit into
haproxytech:masterfrom
ramnbt:crypt/pqc-hybrid-kex
Open

ramnbt wants to merge 1 commit into
haproxytech:masterfrom
ramnbt:crypt/pqc-hybrid-kex

Conversation

@ramnbt

@ramnbt ramnbt commented Oct 24, 2026

Copy link
Copy Markdown

tls: enable hybrid post-quantum key exchange (X25519MLKEM768)

The Data Plane API's HTTPS listener pins CurvePreferences to P-256 only (server.go:227). The comment there — "only use curves which have assembly implementations" — predates Go's post-quantum support: since Go 1.24, an explicit curve list without X25519MLKEM768 opts the server out of the hybrid post-quantum key exchange it would otherwise have by default. Since the Data Plane API often runs long-lived on infrastructure hosts, its admin traffic is the kind of thing "harvest now, decrypt later" collection targets. This change re-enables the hybrid group, additively — P-256 stays, and the classical-fallback handshake below demonstrates compatibility with classical-only peers.

This PR was generated by crypt 0.0.1-dev and verified before it was opened — every gate below ran against this branch's code. Machine-checked: this change touches exactly what it claims. An independent checker (sharing no code with the rewriter) compared the pre- and post-change syntax trees and confirmed the delta is precisely the edits listed below — no other declaration differs. An explicit CurvePreferences list without X25519MLKEM768 silently disables post-quantum key exchange in Go ≥ 1.24; this change re-enables it, preferred first. The change is additive: all previously accepted curves remain (crypt hard rule: rewrites never remove a working path), and compatibility is demonstrated against the tested classical-only peer below. One known ecosystem caveat: a larger ClientHello can trip fragmentation-buggy middleboxes on some network paths — Go documents GODEBUG=tlsmlkem=0 as the operator escape if that occurs.

Changes

  • server.go:227 — []tls.CurveID{tls.CurveP256} → []tls.CurveID{tls.X25519MLKEM768, tls.CurveP256}

Evidence

gate result detail
compile PASS (7292ms) go build ./... && go vet ./... clean
proof-diff-isolation PASS (24ms) machine-checked: AST delta across 1 file(s) is exactly the 1 claimed edit(s) [insert-hybrid-group ×1]; all other declarations identical (position/comment-insensitive)
kat-mlkem768 PASS (368ms) ML-KEM-768: 125 keyGen KATs (ACVP 25 + Wycheproof 100) + roundtrip + implicit-rejection passed in target build
interop-openssl35 PASS (4387ms) TLS 1.3 handshake vs OpenSSL 3.5 completed; negotiated group == X25519MLKEM768
interop-fallback PASS (2677ms) handshake vs classical-only OpenSSL peer completed with a classical group — hybrid preference does not break non-PQ peers
rescan PASS (8894ms) template dry runs find no remaining rewritable sites
proof-diff-isolation artifacts
  • claim: full
  • scope: syntax-tree level; identical ASTs under the same compiler imply identical behavior for unchanged code
kat-mlkem768 artifacts
  • vector_sources: NIST ACVP ML-KEM-keyGen-FIPS203 (final spec) + C2SP/wycheproof mlkem_768_keygen_seed — two independent vector authors
  • checks: keygen ek match (public seed API); encaps/decaps roundtrip; corrupted-ct implicit rejection
  • vector_count: 125
interop-openssl35 artifacts
  • server_groups: X25519MLKEM768:X25519:P-256 (classical offered; client chose hybrid)
  • entrypoint: synthesized config from rewritten CurvePreferences literal
  • negotiated_group: X25519MLKEM768
  • tls_version: 0x0304
  • peer: OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)
interop-fallback artifacts
  • peer: OpenSSL 3.5.9 29 Sep 2026 (Library: OpenSSL 3.5.9 29 Sep 2026)
  • server_groups: X25519:P-256 (no hybrid offered; fallback must complete)
  • entrypoint: synthesized config from rewritten CurvePreferences literal
  • negotiated_group: CurveP256
  • tls_version: 0x0304

evidence bundle: crypt-evidence.json · templates T1-tls-curvepreferences-x25519mlkem768 · generated 2026-10-24T15:54:00Z

Generated by crypt 0.0.1-dev; templates T1-tls-curvepreferences-x25519mlkem768; all verification gates passed in a sandbox build (compile, diff-isolation proof, ML-KEM KAT, OpenSSL interop, rescan).
Evidence: crypt-evidence.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant