Skip to main content

Quantum-resistant on purpose

xoron
positive-intentions

Glitr’s encryption story has two timescales: computers we have today, and computers we may have later. A messenger that only did today’s elliptic-curve handshake would be finished for 2016. The shipped cascade adds post-quantum key agreement on purpose: ML-KEM-1024 as a standalone hybrid envelope, and PQXDH so classical X25519 and the lattice KEM ride together.

These experiences are spec-faithful educational implementations. They are not a claim of wire compatibility with the Signal messenger app, and they are not a warranty about tomorrow’s cryptanalysis. They are the “we did not stop at 2016 curves” part of Glitr.

ML-KEM-1024​

ml-kem is a pure-Rust ML-KEM-1024 (FIPS 203) wrapper for this stack. Signal alone does not meet a post-quantum requirement.

PieceRole
ml-kem-coreThin wrapper over libcrux-ml-kem 0.0.10 — the same crate and pin as libsignal — plus hybrid AES-256-GCM.
ml-kem-wasmwasm-bindgen façade.
ml-kem-galleryDioxus demos on the same chrome the product uses.

Lattice review lives in libcrux, not in this wrapper. The crate targets the 1024 parameter set (Signal PQXDH production): 1568-byte public key, 3168-byte expanded secret key, 1568-byte ciphertext, 32-byte shared secret. Secret keys are the expanded FIPS form.

Hybrid encrypt in core: encapsulate, HKDF-SHA256 with info ML-KEM-1024-AES-GCM, then AES-256-GCM. This is a different parameter set and key encoding from older ML-KEM-768 work.

You can press the buttons:

PQXDH​

pqxdh is the composition step: signal-protocol-core (X25519 ECDH, HKDF-SHA-256, Ed25519, Double Ratchet) plus ml-kem-core (ML-KEM-1024), aimed at Signal PQXDH revision 3.

Classical hardness and post-quantum hardness are not substitutes for each other. X25519 stays hard against the computers we have. ML-KEM-1024 is expected to stay hard if large quantum computers arrive. PQXDH keeps both, so a break in one family does not automatically finish the handshake.

Documented deviations from the spec:

SpecThis crate
XEdDSA on a single X25519 identitySeparate X25519 (DH) and Ed25519 (signatures)
SHA-256 or SHA-512HKDF-SHA-256 via signal-protocol-core
libsignal encodings / protobufsSimple EncodeEC / EncodeKEM with type tags

Parameters: curve X25519, hash SHA-256, info PQXDH-v1, pqkem ML-KEM-1024, AEAD AES-256-GCM. It is a spec-faithful educational implementation. It is not libsignal wire-compatible.

The gallery is public:

How the product stacks them​

The shipped recipient path is AES → Signal → PQXDH on the inside, then RSA hybrid → ML-KEM on the outside. Stacking Signal + standalone ML-KEM + PQXDH is defense-in-depth. PQXDH already includes X25519, ML-KEM-1024, and a Double Ratchet. The extra Signal and ML-KEM layers are not a spec-recommended profile; they are extra independent wraps on the same payload.

Password sealing of your mailbox stays outside that cascade. The encryption password you type at connect derives a key (memory-hard hashing, then authenticated encryption) that seals documents in your mailbox. That is “the host should not read the file contents,” not “this is Signal,” and not “this is post-quantum.”

Your public profile publishes protocol bundles so a contact can encrypt the first message to you. After a fetch, the contact row caches those bundles. Git and live share one protocol session per contact so the ratchet does not fork.

What we will not claim​

  • Unaudited end-to-end forever against nation states.
  • Compatible with the Signal app.
  • The entire messenger is open source.
  • A guarantee about tomorrow’s cryptanalysis.

Safe sentences: a post-quantum KEM and PQXDH are part of the shipped cascade, not only demos. Recipient payloads run AES → Signal → PQXDH, then RSA hybrid → ML-KEM.

The try path is Post-quantum. The user-level story is Signal Protocol and the post-quantum path. Library detail: Cryptography.