Skip to content

Hybrid post-quantum Noise handshake (X25519 + ML-KEM-768) #723

@royzah

Description

@royzah

Why

/noise is classical X25519, so recorded sessions are open to harvest-now-decrypt-later. A hybrid KEM closes that, and stays secure if either primitive holds.

Proposal

A new, separately negotiated handshake (not a change to /noise), keeping the spec's "one id, one fixed suite" design:

  • id: /noise-mlkem768-hfs/0.1.0 (provisional)
  • suite: Noise_XXhfs_25519+ML-KEM-768_ChaChaPoly_SHA256. XX with Hybrid Forward Secrecy; ML-KEM-768 (FIPS 203) mixed into the chain alongside the X25519 DHs.

Identity payload and signature are unchanged. Authentication stays classical (it cannot be broken retroactively); only confidentiality is HNDL-sensitive.

Implementations advertise the hybrid id ahead of /noise, so a mixed fleet falls back with no flag day.

Reference impl

Working in Rust: libp2p/rust-libp2p#6481 over mcginty/snow#210. Revives #2168.

To pin for interop

  1. Protocol id string.
  2. Exact HFS token placement and KDF mixing order, with KATs, so go/js/rust agree byte for byte.
  3. ML-KEM-768 only, or the 512/768/1024 family?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions