connected to indraj.net on tty0
follow the white rabbit...
Secure protocol design for the quantum era

Secure protocol design for the quantum era

It has long been suspected that certain state-backed actors are secretly intercepting and storing encrypted communications data in the hope that one day they can build a cryptographically-relevant quantum computer capable of recovering a private key from a public key, allowing the encryption to be broken. Regardless of the truthfulness of this claim, the threat to existing public key infrastructure from quantum computers has been widely acknowledged, even if viability timeline estimates vary wildly.

In 2024, NIST finalised the first set of post-quantum cryptography standards, believed to be resistant to quantum attacks using Shor's algorithm. However, these algorithms are not mature enough to be relied on alone, so new quantum-resistant cipher suites incorporate both post-quantum and classical techniques in a so-called hybrid design.

In this post, I will describe a secure communications protocol that follows the typical client-server paradigm, featuring mutual authentication and a quantum-resistant hybrid design.

First, the client sends a new session request to the server. This consists of a client ID (for mapping the signatures to public keys), a random 192-bit nonce, a freshly-generated Curve25519 public key to be used in Diffie-Hellman (ECDH), a freshly generated ML-KEM-1024 public key and signatures from the client's long-term Ed25519 and ML-DSA-87 keys.

The server responds with its own ID (if necessary), alongside a separate, random 192-bit nonce, a freshly-generated Curve25519 public key, a shared secret encapsulated with the client's KEM public key and signatures from the server's long-term Ed25519 and ML-DSA-87 keys.

Both sides verify the corresponding signatures, then derive/de-encapsulate shared secrets using ECDH and ML-KEM respectively. These secrets are concatenated together along with the client and server nonces, and the result is fed into the BLAKE2b hashing algorithm, which produces a 32-byte output to be used as the session key.

Every message exchanged during the session is encrypted using the XChaCha20-Poly1305 AEAD construction. The first encrypted chunk contains a sequence number as additional authenticated data (AD). This is incremented with every message sent. When the value is about to overflow, the session key is rotated by feeding it into BLAKE2b, using the output as the new session key and resetting the sequence counter. This scenario is unlikely but it should be accounted for regardless.

Security properties

This protocol is immune to downgrade attacks, handshake replay attacks, message replay attacks and encrypted chunk replay attacks. Corruption can be detected early without having to decrypt the entire stream first. Authentication is mutual; the server and client both authenticate each other and do not require a separate authentication step once the session has been established.

Practical considerations

When implementing this protocol, you will probably want to use a networking abstraction rather than raw TCP sockets. You should also implement compression for plaintext data. For these purposes, I recommend ZeroMQ and zstd respectively.

The resultant architecture is a good contender for replacing gRPC when interoperability with third party services is not a concern. As of May 2025, there is no official IETF specification for hybrid key exchange in TLS.

Thanks for visiting my website!

Belfast, United Kingdom
Copyright (C) 2024-2025 Indraj Gandham
Licensed under CC BY-SA 4.0

Privacy information