zerohop.dev
ProThis module is part of zerohop Pro.

Post-Quantum Cryptography

Ask whether a TLS library supports post-quantum cryptography and there is no single answer — there are four, inside one library at one commit. BoringSSL implements ML-KEM and ML-DSA; it offers no post-quantum group by default; it prefers to sign with ML-DSA; and it accepts no ML-DSA signature at all. That last pair is an argument inside one file, and the direction is what bites: the list a peer advertises is the VERIFY list, so a default-configured endpoint announces a set that excludes exactly the algorithm it prefers to use, and two such endpoints will never sign to each other that way. OpenSSL answers the same question once — one signature-algorithm array served in both directions, and a default group list that leads with the hybrid — so the two pinned trees give opposite answers to 'is post-quantum on by default', which is why the library here is a control rather than a footnote. The sizes are where the received wisdom is wrong in a checkable way: the figure usually quoted for ML-KEM-768's public key, 800 bytes, belongs to ML-KEM-512, while the 768 set is 1184 with an 1088-byte ciphertext — and the trap is symmetrical, because ML-KEM-512's ciphertext is 768 bytes, so the number is a byte count for one parameter set and the name of another. Kyber is not ML-KEM, both ship in the same tree, and every size coincides, so a capture cannot tell you which you deployed; only the group code point can, which is why the pre-standard group still carries Draft00 in its name. Two different mechanisms are called hybrid and this module keeps them apart: a hybrid group is one named group whose key share holds two public keys and whose secret is their concatenation, while the pairing offers one post-quantum and one classical key share and is only as post-quantum as the server's selection. The property that makes the hybrid worth its bytes is a code fact rather than a slogan — the 64-byte concatenated secret is handed unsplit to a single HKDF-Extract, so breaking one component still leaves the other's 32 bytes in the input — and the wire order is specified rather than conventional, having flipped between drafts, so the two hybrids are the same total and the opposite layout. A KEM is also not a Diffie-Hellman primitive: the client sends a public key and the server returns a ciphertext, a separate object with its own size, which is why the picture is asymmetric where X25519's is not. On the signature side the cost is the largest number in the module, 3309 bytes for ML-DSA-65 against at most 72 for ECDSA-P256, and signatures are not the retroactive problem — a signature is checked live, so a recording of a handshake that has already finished cannot be replayed into it. The harvest-now argument that does carry is about confidentiality, and it needs no date: an adversary that keeps what it captures, plaintext still worth reading when the recording is opened, and a 32-byte classical public value that costs nothing to collect. Change the threat model, the data sensitivity, the key establishment, the signature algorithm, the pairing toggle, the horizon and the library, and watch the server-computed cascade across all five sections. Validated against OpenSSL 3.5.7 and BoringSSL source, with every citation naming its library because one underscore is all that separates their two post-quantum headers.

  • All current + future modules
  • Full kata library
  • Progress dashboard + weak area analysis

Cancel anytime. Billed annually.

zerohop.dev — Interactive Network Protocol Simulators