Field report / Post-quantum E2EE

10 Things I Wish I KnewBefore Building a Post-Quantum E2EE Platform

The hard part was not adding ML-KEM. The hard part was preserving trust while messages, devices, calls, retries, and offline state all moved at the same time.

Security engineers collaborating around encrypted devices and post-quantum key exchange visuals

Opening story

It was never just a key exchange.

I expected the difficult part of our post-quantum migration to be cryptography.

I spent weeks reading standards, implementing ML-KEM, studying PQXDH, validating shared secrets, and checking that both sides derived the same root material. Those parts were demanding, but they were not what kept me awake.

The turning point came during a production debugging session. A message encrypted successfully. It left the sender. The relay acknowledged it. The recipient eventually came online. Yet the message never appeared.

Nothing was wrong with the cryptography. Everything was wrong with the state. Retries had raced against prekey consumption. One device rotated its key material while another was still establishing a session. A duplicate delivery collided with recovery logic that had never been exercised under those conditions.

We were not migrating cryptography. We were migrating a distributed system that happened to use cryptography.

01

TLS Is Not Your Security Boundary

TLS protects the pipe. PQXDH protects the conversation.

In an end-to-end encrypted product, the server is not the final security boundary. The sender and recipient devices are. The server may queue ciphertext, route envelopes, fan out to multiple devices, retry delivery, and acknowledge progress, but it should not be able to read the message or impersonate the recipient's cryptographic state.

If your trust boundary lives inside the application, your PQC migration has to live there too.

02

PQC Changes the Session State Machine

It is not an algorithm swap.

Classical end-to-end encryption already carries identity keys, signed prekeys, one-time prekeys, device registration, session establishment, message ratchets, and recovery behavior. PQXDH adds post-quantum key agreement to that path, but the new key exchange has to compose with everything the existing protocol already promised.

The snippet is clean. Production is not. Retries, state transitions, offline delivery, depleted prekeys, stale sessions, and partial recovery decide whether the protocol survives contact with real users.

const bundle = await server.fetchPreKeyBundle(recipientId);
const classicalSecret = deriveClassicalSecret(identityKey, bundle.classicalPreKey);
const { sharedSecret: pqSecret, ciphertext } = await platformCrypto.mlKemEncapsulate(bundle.mlKemPublicKey);
const rootSecret = await hkdf(concat(classicalSecret, pqSecret), salt, "PQXDH Root");
03

Offline Messaging Is Really Key Management

Offline messaging exists because keys exist before users do.

When a recipient is offline, the sender still needs a way to create a session for that recipient's device. The recipient cannot participate in the handshake at that moment, so the system depends on pre-published key material.

Once post-quantum material is part of the bundle, prekey management becomes even more important. You have to generate it, upload it, sign it, rotate it, expire it, consume it safely, prevent replay, and replenish it before inventory runs out.

04

Multi-Device Breaks One User Equals One Identity

Product language likes users. Cryptographic systems have to talk about devices.

A person may have one account, but each device has its own keys, capabilities, trust history, and recovery state. A phone that registered yesterday is not the same trust object as a laptop registered six months ago.

Send a message to this user becomes a more precise operation: send to every trusted device for that user that currently has valid session material, acceptable device state, and a delivery path that can preserve the protocol's guarantees.

05

Calls Are a Different Cryptographic System

A message is discrete. A call is live.

Messaging and calling can share identity, authentication, and session establishment ideas, but they are not the same cryptographic system.

A call has offer and answer timing, ICE candidates, codec negotiation, permissions, media capture, audio routes, video renderers, and frame encryption. The cryptographic session has to be ready at the right moment, not merely correct eventually.

Encrypted media has its own lifecycle. You have to design for that lifecycle directly.

06

Standards Describe Protocols, Not Production

Standards are necessary. They do not operate your service.

Standards define algorithms, inputs, outputs, transcript binding, security properties, and the shape of the handshake. Production turns those requirements into lifecycles: generate, sign, upload, rotate, retry, cache, recover, roll back, observe, and upgrade.

07

Debugging Cryptography Looks Like Debugging Distributed Systems

Most failures begin with distributed state.

A duplicate message arrived after a retry. A stale session survived longer than expected. A device updated its bundle while another request still depended on the old one. A recovery path processed events in the wrong order.

None of those failures begin with the algorithm being broken. They become cryptographic failures because the state carries cryptographic meaning.

08

Observability Has to Work Without Seeing the Data

Plaintext logs are gone. That is a feature.

End-to-end encryption removes the easiest debugging tool: plaintext logs. The system has to be observable in a different way.

You need correlation IDs that connect sender attempts, relay acceptance, recipient drains, acknowledgements, and checkpoints. You need to know that a device could not decrypt without knowing what it tried to decrypt.

09

Migration Is Mostly About Compatibility

Real users do not upgrade at the same time.

Some devices are offline for weeks. Some sessions were established before the new protocol existed. Some clients understand post-quantum bundles and some do not.

A post-quantum migration is not finished when the new code ships. It is finished when the old state has safely aged out.

10

Cryptography Is Only One Layer of Security

The standards are the beginning.

ML-KEM matters. Hybrid session establishment matters. Standards matter. But none of them remove the need for correct device identity, careful prekey handling, reliable state transitions, replay resistance, safe retries, media ordering, compatibility strategy, and operational observability.

Implementation is where the security model either survives contact with production, or quietly becomes a theory.