Carr Digital

Measurement · August 7, 2026

The typical chain moved

The models disagree on whether a drop-in ML-DSA-44 chain fits TCP's initial congestion window, because each builds a different typical chain. Projected onto 8,151 real chains from the top 10k: 85.1% do not fit, and the deciding variable is depth.

The standard way to reason about post-quantum certificate sizes is to build a typical chain: one leaf, one intermediate, a root that stays off the wire, a couple of CT log signatures, then swap the classical algorithms for ML-DSA and see what the total does to TCP’s initial congestion window. The models do not agree on the answer. Chou and Cao measured a simulated ML-DSA-44 chain at about 7.9KB against a 14KB window: fits. Kampanakis and Kallitsis, whose tables include CT, put Dilithium at roughly 15KB once SCTs are present: does not fit. Ivan Ristic ran the arithmetic again four days ago and concluded the cryptography alone busts the window. A modeled chain answers whichever way you build it, and no model says what fraction of the web sits on which side.

I captured the certificate chains that 8,151 of the Tranco top 10,000 actually serve, projected each one onto ML-DSA using its own measured contents, and checked the result against the window. Under a drop-in ML-DSA-44 migration, 85.1% of real sites exceed the initial congestion window: an extra round trip on every full handshake, at five of every six sites, on migration day. The direction was predicted. The fraction, the spread, and the per-site answer are what was missing, and the reason the optimistic models miss is not where I expected to find it.

What was measured

One TLS connection per domain on 2026-08-07, capturing the chain exactly as served: 8,152 domains completed a handshake, and 8,151 produced a parseable chain. (The holdout serves a certificate with an empty serial number, which RFC 5280 forbids. It is a payment network.) Everything downstream is offline parsing of that captured evidence.

The corpus calibrates against published data before any projection happens: median served chain 3,754 bytes, against the 4,032-byte median that the cert-abridge draft reports over ~75,000 Tranco chains. Close enough to trust the instrument; different enough to matter later.

The projection swaps exactly two things per certificate: the measured signature bytes and the measured public-key bytes, replaced with their FIPS 204 equivalents as emitted by OpenSSL 3.5.5, so the DER wrapping is included rather than idealized. Names, SANs, extensions, SCT structure, chain depth, and whether the site transmits its root all stay exactly as observed. The verdict is computed on the server’s first flight, not the bare chain: chain plus CertificateVerify plus a measured 1,256-byte constant for the remaining server messages, a framing I measured previously. Every projected figure is a projection, and the assumptions travel with the numbers.

Scenario p50 flight p95 flight over IW10 over IW20
ML-DSA-44, full chain 16,810 21,499 85.1% 0.1%
ML-DSA-44, leaf key only 8,506 11,176 0.3% 0%
ML-DSA-44, full chain, SCTs migrate 21,651 28,535 99.7% 1.6%
ML-DSA-65, full chain 22,282 28,495 99.5% 1.5%
ML-DSA-65, leaf key only 10,035 12,705 0.9% 0%
ML-DSA-65, full chain, SCTs migrate 28,805 38,201 99.8% 48.1%

You can look up any domain in the corpus yourself: the chain check tool serves this dataset per site, with the scenario and the window as inputs.

Why the models and the web disagree

The typical chain has one intermediate. The web mostly stopped serving that chain.

Intermediates served Sikeridis et al., 2022 This corpus, 2026
0 13 to 31% 0.6%
1 35 to 45% 22.8%
2 24 to 30% 66.1%
3 9 to 12% 10.2%

Two caveats belong to that table. My counting rule is stated: an intermediate is any transmitted certificate above the leaf that is not self-signed, so a cross-signed root on the wire counts as one. Sikeridis et al. never state theirs, and the buckets disagree in a telling pattern: the 3-intermediate rows match within a point while the 0-intermediate rows sit 24 points apart, so some of this table is a counting or collection difference rather than four years of change. The 2026 column stands on its own stated rule either way, and its edges cross-check against the newest million-domain completeness measurement (Yao et al., IMC 2025): they find 1.3% of domains serving no intermediate and 89.9% omitting the root, next to this corpus’s 0.6% and 86.9%.

Whichever way the 2022 comparison is counted, today two thirds of the top 10k serves two intermediates, and every extra intermediate is another ML-DSA signature and another ML-DSA public key on the wire. The expected certificates per chain moved from about 2.24 to 2.99. Each certificate that migrates picks up 3.2 to 3.6 kilobytes net of the classical bytes it sheds, so the drift alone is worth roughly two and a half kilobytes of projected flight, which is the difference between “squeaks under the window” and “clears it by two kilobytes in the wrong direction.”

The one-intermediate models did not get the arithmetic wrong. Their chain went stale.

The part where I argue against my own project

Before building this, I recorded the strongest objection a reviewer could raise: the projection is trivial. The ML-DSA delta per certificate is a constant from FIPS 204, so a projected distribution is just the classical distribution shifted by depth times a constant, and the published depth distributions plus the published arithmetic should reproduce everything without scanning anybody.

I tested that objection instead of arguing with it, and it mostly wins. Given the measured classical totals and each site’s real depth, a constant-delta model flips almost no verdicts against the full per-certificate projection: at worst 0.9% of sites at the ML-DSA-44 boundary, 5.7% in the worst scenario tested. Counting each site’s actual SCTs instead of assuming two or three moves under 1% of verdicts. Per-site content measurement buys about a kilobyte of per-site precision, and most sites sit further than that from any boundary.

Two things survive the objection, and they are the two things worth knowing. First, the constant-delta model only works if its inputs are current, and the published inputs are not: build the model purely from the literature, with 2022’s depth mix, and the median site comes out 1 to 1.8KB lighter than measured, landing just barely over the window instead of comfortably over it. Second, the model’s answer depends on which typical chain it silently assumed. An ECDSA-typical model overshoots real chains by a median 1,161 bytes, because 61% of real leaves are still RSA and carry more removable classical bytes. The literature rarely says which flavor it assumed. The corpus shows the choice moves the median by more than an entire SCT.

So the honest framing of this work is not “the models are wrong.” It is: the arithmetic was always fine, the inputs had a shelf life, and here are the 2026 inputs, measured, with a per-site lookup so nobody has to take the aggregate’s word for it.

What actually helps

Leaf-only migration is the escape hatch, and the numbers are stark. Put a post-quantum key in the leaf, keep the chain signatures classical, and the flight fits the default window at more than 99% of sites in both parameter sets, with the ML-DSA-44 median landing at 8.5KB, inside the 9 to 10KB zone Kampanakis and Kallitsis name as the comfortable target. The transition shape that works is the one that migrates the fewest signatures.

The scenario that hurts is CT. If the log ecosystem migrates its SCT signatures to ML-DSA-65 alongside the chains, 48.1% of sites exceed even a doubled IW20 window. Every embedded SCT is a whole extra signature, and half the corpus embeds three.

Three smaller observations from the same capture. 13.1% of sites transmit their root certificate, which every client ignores; under migration those sites would pay a full wasted ML-DSA signature and key per handshake for nothing. 54.7% of the sampled sites negotiate X25519MLKEM768 with an OpenSSL 3.5.5 default client, consistent with the published adoption scans (49.3% across 32,011 domains earlier this year). And with that client, which sends only the hybrid key share by default, 284 of 285 classical TLS 1.3 servers answered with a HelloRetryRequest: an extra round trip as the price of leading post-quantum against a server that has not moved. That is RFC 8446 doing what it specifies, measured rather than assumed, and it is a property of the client’s key-share policy, not of the servers. Browsers dodge it by sending a classical share alongside the hybrid one, as Chrome did when it shipped Kyber, and draft-ietf-tls-key-share-prediction exists so DNS can say which share to send.

Limits

Every projected number here is a projection under stated assumptions, not a measurement of a post-quantum handshake; the corpus contains zero post-quantum certificates, and every published scan to date reports the same for the production web. The 1,256-byte flight constant is one lab stack’s measurement. The corpus is a one-day snapshot of one ranking’s top slice, and chains rotate. Nothing here measures latency, and nothing here knows any server’s configured congestion window, which is why the window is an input in the tool rather than a constant in the verdicts.

Provenance

Measured here (Verified). The captured chains, the corpus statistics, the depth distribution, the root-transmission rate, the negotiated-group subsample, and the HelloRetryRequest count come from captures taken 2026-08-07 on one machine, Tranco list ZJGPG pinned. The ML-DSA sizes were generated with local OpenSSL 3.5.5 rather than copied from FIPS 204, so DER wrapping is included. The capture and analysis scripts and the full dataset are public at pqc-chain-budget (DOI 10.5281/zenodo.21846142), and the chain check tool serves the per-site data.

Projected, not measured (Proposed). Every post-quantum chain size and flight verdict is arithmetic on measured inputs under assumptions stated above and in the tool. No post-quantum handshake was performed against any corpus site, because none of them can perform one.

Cited, not claimed (Reported). The congestion-window interaction is established work: Kampanakis and Childs-Klein for the initial-window interaction, Chou and Cao for measured time-to-first-byte thresholds, and Kampanakis and Kallitsis for the budget tables by chain depth. Per-site measurement of real chains against a transport budget exists for classical certificates: Nawrocki et al. measured 1M domains against QUIC’s amplification limit in 2022, and their method is this method, minus the projection. The 2022 depth distribution is Sikeridis, Huntley, Ott and Devetsikiotis. The classical chain-size baseline is the cert-abridge draft. Adoption context is Dubey and Varshney. Ristic’s modeled-chain arithmetic is Red Sift, 2026-08-03; chain completeness at the million-domain scale is Yao et al., IMC 2025; the dual key-share mitigation is documented by Cloudflare. One relevant lab study varying chain compositions (Henrich et al., ISC 2025) sits behind a paywall and was not opened; no claim above depends on it. We found no prior study that projects post-quantum signature sizes onto each site’s own deployed chain across a large corpus of real domains; the closest published work is named above, and the repository’s prior-art file records the full map, including the claims it has already forced this project to narrow.

Things this project got wrong along the way. An earlier probe run reported 72% hybrid key-exchange adoption; that number was an instrument artifact (the parser echoed the client’s own key share for TLS 1.2 sessions) and the corrected figure is 54.7%. The instrument notes ship with the dataset. Two web summaries fabricated or misattributed source content during the prior-art search for this work; every citation above was verified against the downloaded full text, a policy this body of work adopted after being burned the same way before.

If something here is wrong, email the studio and I will correct it in place with a note saying what changed.