Skip to content

noise-pq: add Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256 spec (Stage 1 Working Draft)#716

Open
paschal533 wants to merge 2 commits into
libp2p:masterfrom
paschal533:master
Open

noise-pq: add Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256 spec (Stage 1 Working Draft)#716
paschal533 wants to merge 2 commits into
libp2p:masterfrom
paschal533:master

Conversation

@paschal533

@paschal533 paschal533 commented Apr 28, 2026

Copy link
Copy Markdown

Summary

This PR adds a new protocol spec for Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256, a post-quantum hybrid extension of the classical Noise XX handshake used in libp2p.

Update (2026-06-24): The spec has been revised from an earlier X-Wing draft to use raw ML-KEM-768 (FIPS 203). The Noise XXhfs pattern already provides classical security through three independent DH operations (ee, es, se), so using X-Wing (which bundles an extra X25519 inside the KEM) would be redundant — adding 64 bytes of wire overhead with no security benefit. Raw ML-KEM-768 gives the same hybrid security guarantee with a smaller footprint, and aligns with the Rust reference implementation royzah/rust-libp2p PR #1 (Rust).

The spec is filed at Stage 1 (Working Draft) per the libp2p spec lifecycle.

  • Specifies the e1 and ekem1 HFS token extensions from the Noise HFS draft, applied to the existing Noise XX pattern
  • Uses raw ML-KEM-768 (NIST FIPS 203) as the KEM primitive in the ekem1 slot
  • Covers wire format (Msg A 1,216 B, Msg B 1,200 B, Msg C 64 B), token ordering requirements, cipher state split, ML-KEM implicit rejection semantics, and interoperability requirements
  • Includes a test vector schema matching the reference implementations

Motivation

NIST finalized ML-KEM (FIPS 203) in August 2024. Harvest-now-decrypt-later attacks make forward secrecy the most urgent deployment target. The XXhfs pattern adds quantum-safe forward secrecy with no changes to the classical authentication layer, giving operators a safe incremental migration path.

Reference Implementations

Three independent implementations exist and have been validated against each other:

Language Link Tests
TypeScript js-libp2p-noise PR #665 (JS) 99 tests, 5 deterministic test vectors
Python libp2p/py-libp2p libp2p/py-libp2p#1310 68 tests
Rust royzah/rust-libp2p PR #1 (Rust) ml-kem crate (RustCrypto)

Triangle interoperability (2026-06-24)

All three implementations were tested pairwise over real TCP connections:

Pair Result
TypeScript ↔ Python ✅ PASS
Rust ↔ TypeScript ✅ PASS
Rust ↔ Python ✅ PASS

Test plan

  • Review spec against Noise HFS extension spec for correctness
  • Review token ordering (encryptAndHash before mixKey in ekem1)
  • Verify wire format sizes match the reference implementations (Msg A: 1,216 B, Msg B: 1,200 B, Msg C: 64 B)
  • Check lifecycle header format matches other specs in this repo
  • Identify interest group members (need 3+ for Stage 2)

@paschal533 paschal533 changed the title noise-pq: add Noise_XXhfs_25519+XWing_ChaChaPoly_SHA256 spec (Stage 1 Working Draft) noise-pq: add Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256 spec (Stage 1 Working Draft) Jun 25, 2026
- Protocol name: Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256
- Protocol ID: /noise-mlkem768-hfs/0.1.0
- KEM: raw ML-KEM-768 (FIPS 203), removing X-Wing composite wrapper
- Wire sizes: Msg A 1216 B, Msg B 1200 B (was 1248/1232 with X-Wing)
- Add Rust reference impl (royzah/rust-libp2p PR libp2p#1)
- Add triangle interop results (JS/Python/Rust -- 3/3 PASS, 2026-06-24)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

1 participant