guide · handshake race · static layout (animation pending)

handshake race

Two TLS 1.3 handshakes side-by-side. Pick a cipher suite for each track, hit play, watch the messages travel between client and server with the byte counts ticking on every arrow. The point isn't speed — it's cost. Post-quantum key exchange and signatures aren't "a little bigger." They're an order of magnitude bigger, and a handshake is the place where that lands hardest.

left: vs right: speed 1.0×
Client
Server
handshake total 0
Client
Server
handshake total 0

what's in each message

TLS 1.3 reduced the handshake to a single round-trip: the client sends its key share, the server responds with its key share plus the certificate it'll be authenticated with, both sides confirm with Finished. Two slots in this flow change with the cipher suite — the key share (KEX) and the CertificateVerify signature (SIG). Everything else is constant.

ClientHello
Carries the client's key_share. For classical it's a 32-byte X25519 pubkey. For hybrid PQ it's that pubkey plus a 1,184-byte ML-KEM-768 pubkey concatenated.
ServerHello
Server's matching key_share. In hybrid the server's contribution is an ML-KEM ciphertext (1,088 B) — the server encapsulated to the client's pubkey rather than sending its own pubkey, which saves the round-trip a strict KEM design would otherwise need.
Certificate
The server's identity, plus the chain that authenticates it. This row scales dramatically with the signature scheme, because each cert in the chain carries both a subject pubkey AND a signature from its issuer. ECDSA-P256 chain ≈ 820 B; ML-DSA-65 chain ≈ 11,300 B; ML-DSA-87 chain ≈ 15,200 B. The hybrid track keeps a classical cert because TLS PQ certs aren't deployed in production yet.
CertificateVerify
The server signs the handshake transcript so the client knows the server holds the cert's private key. Ed25519 is 64 B; ML-DSA-65 is 3,309 B; ML-DSA-87 is 4,627 B. This row alone grows by ~50× when PQ signatures arrive — but it's dwarfed by what the cert chain costs, because the chain pays for both pubkeys and signatures.
Finished
HMAC over the handshake transcript, both directions. Tag size follows the cipher suite hash (32 B for SHA-256, 48 B for SHA-384).

The orange left-border on a payload row marks a cipher-suite-dependent field — the bytes that change when you pick a different suite. Everything without an orange border stays the same. That's the whole point of the side-by-side: the delta is post-quantum's actual cost.