AUTONOMY DIRECTORATE

๐Ÿ  Main

๐Ÿงช Interactive Apps

๐Ÿ“ฐ News

๐Ÿ›ก๏ธ PQ Crypta Proxy

๐Ÿ‘ค Account

โŸจ QUANTUM ERROR PORTAL โŸฉ

Navigate the Error Dimensions

PQ Crypta Logo

PQ CRYPTA WHITEPAPER · CAPTURE REPLAY

Anatomy of a QUIC Connection

One real scan by the HTTP/3 Analyzer, replayed packet by packet. Scroll to advance the connection.

target
pqcrypta.com:443/udp
captured
2026-07-26 13:22:12 UTC
frames
18 out · 24 in · 0 lost
link
UDP · QUIC v1 (RFC 9000)
observer
http3_scanner.rs (noq)
verdict
sealed until the wire closes ↓
state idle t keys none pkt space
before the wirePROLOGUE

A whitepaper shaped like a packet capture

Most whitepapers describe a system from above. This one rides along with it. On 2026-07-26 at 13:22:12 UTC the PQ Crypta HTTP/3 Analyzer scanned pqcrypta.com, sent 18 UDP datagrams, received 24, lost none, and produced a verdict. Every number on this page comes from that single connection or from the source code that made it. Nothing is illustrative, nothing is simulated, and the verdict stays sealed until the connection closes at the bottom.

The bar above is the connection's state machine. As you scroll, it advances the way the real connection did: through address validation, the Initial flight, a post-quantum handshake, 1-RTT application data, a battery of capability probes, and CONNECTION_CLOSE. The scanner behind all of this is a Rust client built on noq (the multipath-capable quinn fork), driven by a single Axum handler, http3_scanner.rs, that opens a genuine QUIC connection to whatever you type into the analyzer. It does not parse HTML about protocols. It speaks them.

The full capture as a sequence ladder: eight exchanges between scanner and server, replaying on a loop CLIENT SERVER t = 0 Initial · CRYPTO(ClientHello) · 1200 B pad Retry · integrity-tagged token Initial + token · key_share X25519MLKEM768 ServerHello · EncryptedExtensions · Certificate · Finished t = 30 ms Finished · handshake complete · 1-RTT keys HEADERS · GET / +6 ms HEADERS 200 · Alt-Svc h3=":443" t ≈ 2128 ms probes done · CONNECTION_CLOSE (0x00)

The capture at a glance: every exchange in this paper, drawn in wire order and replayed on a loop. Probes (phases 6 and 7) run inside the gap before CONNECTION_CLOSE.

t < 0NO PACKETS YET

Phase 0 · Nothing is trusted, including the target

Before a single datagram leaves, the target string goes through scan_target.rs, a validation module shared with the PQC readiness scanner: domain syntax, DNS resolution, and an SSRF guard that refuses private, loopback, and link-local ranges so the scanner cannot be aimed at internal infrastructure. Only a public, resolvable host reaches the wire.

One deliberate act of amnesia happens here. The scanner installs a NoneTokenStore, so it forgets every address-validation token servers have ever issued it. That guarantees each scan is a true cold start: without it, noq would cache the NEW_TOKEN a server issues after its first Retry, present it on the next scan, and the server would politely skip Retry, making Retry detection report a different answer on every second run. A scanner that remembers is a scanner that measures its own memory.

t = 0LONG HEADER · INITIAL

Phase 1 · First flight, and the server says "prove your address"

Initial[0]: CRYPTO(ClientHello) · version 0x00000001 · PADDING to 1200 B
Retry: token (integrity-tagged) · new SCID
Initial[0]: CRYPTO(ClientHello) + token

The first packet is an Initial: a long-header packet carrying the ClientHello inside a CRYPTO frame, padded to at least 1200 bytes because QUIC refuses to let tiny packets trigger big replies. In this capture the server did not answer with a handshake. It answered with a Retry (retry_packet_received: true): a stateless challenge that forces the client to prove it owns its source address before the server commits any memory to it. The scanner echoed the token and was admitted. It records this as security_features.retry_packets_enabled, a defense most scanners never notice because most scanners never complete a real handshake.

Two more findings land in this phase. The server honors version negotiation (version_negotiation_received: true): poked with a reserved version number, it correctly lists what it speaks, QUIC v1 (RFC 9000) and QUIC v2 (RFC 9369), with GREASE versions sprinkled in (grease_versions_seen: true) to keep middleboxes from ossifying the list. And the amplification math is measured, not assumed: the anti-amplification limit caps a server at 3× the bytes a client has sent until the address is validated. This server's measured factor before validation: 0.09×. It could legally send 33 times more than it does.

Anti-amplification: what the client sent, what the server was allowed to send, and what it actually sent client sent (pre-validation) 1,200 B server allowed (3× rule) 3,600 B server actually sent ≈ 108 B · 0.09× measured on this capture · a reflection-attack answer 33× quieter than the rule requires
t ≤ 30 msCRYPTO · TLS 1.3

Phase 2 · A handshake from after the quantum threat

ClientHello: key_share X25519MLKEM768 (1216 B) · ALPN h3 · ECH
ServerHello · EncryptedExtensions · Certificate · Finished
Finished · handshake complete at t = 30 ms

The ClientHello's key share is the tell. X25519MLKEM768 is a hybrid: a 1184-byte ML-KEM-768 encapsulation key (FIPS 203, the standardized descendant of Kyber) concatenated with a 32-byte X25519 point, 1216 bytes where classical TLS sends 32. Breaking the session requires breaking both: the lattice problem and the curve. The scanner records the negotiated group (pqc_key_exchange: "X25519MLKEM768", pqc_hybrid_offered: true), and this single boolean later decides whether the top grade is even reachable.

Key-share size: classical X25519 alone versus the X25519MLKEM768 hybrid used in this capture classical TLS 1.3 X25519 · 32 B this capture ML-KEM-768 encapsulation key · 1,184 B (FIPS 203) + X25519 · 32 B 1,216 bytes where classical sends 32 · breaking the session requires breaking the lattice problem and the curve

Around it, the rest of the hello is read with the same literalism: ALPN offered and negotiated (h3), Encrypted Client Hello support detected (ech_supported: true, the server publishes a real ECH config, so the hostname itself can travel encrypted), GREASE extensions present, cipher settled as TLS_AES_256_GCM_SHA384, and the signature algorithm list even shows ML-DSA-44: a post-quantum signature scheme advertised in a live TLS stack. The negotiated cipher comes from a small accessor added to the vendored noq (negotiated_cipher_suite on its rustls HandshakeData): real value or an explicit unknown, never a guess.

The clock reads 30 ms for the complete handshake, and that number is honest by construction: an earlier version of this metric accidentally timed DNS resolution and a per-scan certificate-store load along with the handshake. The store now loads once behind a OnceLock and the timer starts at connect(), so 30 ms is the protocol, not the scanner's own overhead.

t = 30 msTRANSPORT PARAMETERS

Phase 3 · The server's confession, in eleven integers

Inside the encrypted handshake, the server hands over its transport parameters: a self-description of every limit it intends to enforce. The scanner does not infer these from behavior. It reads the peer's advertisement raw, through a peer_transport_params() accessor maintained in the vendored noq fork, and republishes them verbatim:

initial_max_data16,777,21616 MiB connection flow-control window
initial_max_stream_data_bidi_*8,388,6088 MiB per stream, both directions
initial_max_streams_bidi / uni1,000 / 1,000generous concurrency for HTTP/3 + WebTransport
max_idle_timeout120,000 mstwo minutes before silent death
max_udp_payload_size1,472tuned to Ethernet MTU minus IP/UDP headers
max_datagram_frame_size65,535unreliable datagrams enabled at maximum size
active_connection_id_limit5spare CIDs for migration and multipath
disable_active_migrationfalsephones may roam
grease_quic_bittrueRFC 9287: the fixed bit is greased against ossification
ack_delay_exponent / max_ack_delay3 / 25 msACK timing contract
stateless_reset_tokenpresentclean death even if the server reboots

These integers are also a fingerprint. The scanner identifies server implementations in three tiers: the Server: header when present (95% confidence), known platform domains (85%), and, when both fail, the characteristic shape of exactly these transport parameters (70%). This capture needed only tier one: Server: pqcrypta resolved to "PQCrypta Proxy (noq)" at 0.95 confidence, with characteristics including "Post-Quantum ready" and "Full multipath QUIC". Sites that hide their server header still get named, just less confidently, by their integers.

t = 30 ms +H3 CONTROL STREAM · SETTINGS

Phase 4 · HTTP/3 clears its throat

SETTINGS: EXTENDED_CONNECT · H3_DATAGRAM · WEBTRANSPORT
PRIORITY_UPDATE (RFC 9218): u=3, non-incremental
accepted · response carries Priority: u=3

With 1-RTT keys installed, both sides open control streams and exchange SETTINGS. This server enables the modern set: Extended CONNECT (the door WebTransport walks through), H3_DATAGRAM, and WebTransport itself. Its max_field_section_size is 4,611,686,018,427,387,903, which is 262−1, the largest value a QUIC varint can carry. The server is not expecting a 4-exabyte header block; it is declining to impose a limit, in the most maximal way the encoding allows.

For RFC 9218 Extensible Priorities, the scanner refuses to settle for reading a header. It sends a real PRIORITY_UPDATE frame (a capability added to the vendored h3 crate) and watches whether the server accepts it. Here: priority_update_accepted: true, with the response advertising Priority: u=3. Passive observation says a feature is configured. An active frame says it works. The capture also shows 103 Early Hints arriving before the main response (early_hints_103: true), preload hints sent while the origin is still thinking.

TTFB = 6 msHEADERS · QPACK

Phase 5 · The request, and the header that decides careers

HEADERS: GET / · :authority pqcrypta.com
HEADERS: 200 · alt-svc: h3=":443"; ma=86400, h3=":4434" · 6 ms to first byte

The actual HTTP part is almost anticlimactic: GET /, a 200, first byte in 6 milliseconds, and a server-timing header confessing the proxy spent 4.43 ms of that. But one response header carries more grading weight than any other: Alt-Svc. It is how browsers discover HTTP/3 exists. A server can run a flawless QUIC stack on UDP 443, and if this one header is missing, every browser on Earth will quietly use HTTP/2 forever.

The scanner treats that failure mode as its own grade. Sites whose QUIC handshake succeeds but whose Alt-Svc is absent are graded C: misconfigured, arguably the saddest grade on the scale, a working engine nobody is told about. Historical scan data shows it is not rare. This capture's Alt-Svc advertises HTTP/3 on 443 with a 24-hour lifetime, plus an alternate endpoint on 4434, so the C trapdoor stays shut.

the interrogationCAPABILITY PROBES

Phase 6 · Four interrogations on one connection

A grade earned by reading headers would be an opinion. The scanner's grades are alibis: each claimed capability is exercised for real. Four probes run against this connection; the entire scan, all of them included, takes 2,128 ms of wall time.

01 WebTransport

A genuine session is established through Extended CONNECT (here on port 443, path /; 4433 and custom ports are also tried). Measured, not asserted: session open in 37 ms, datagrams supported at up to 1,413 bytes, 1,000 incoming streams, both stream directions, a 16 MiB flow-control window.

02 MASQUE CONNECT-UDP

RFC 9298 proxying is verified by actually relaying UDP over the HTTP/3 connection: the probe sends a real DNS query through the relay to 127.0.0.53:53 and waits for the answer. This capture: session accepted, status 200, round trip 5 ms. The server is a working UDP proxy, proven by a resolved query.

03 Multipath

The scanner calls connection.open_path() and opens a second, data-carrying network path (draft-ietf-quic-multipath-21). Path 1 validated with its own congestion window (12,000 B) and MTU (1,200 B), independent of the primary path's 14,400 B and 1,452 B. That story has its own whitepaper.

04 0-RTT

The one probe where the best answer is a refusal. 0-RTT resumes sessions with zero round trips but makes the first flight replayable by anyone who recorded it. This server declines early data (supports_0rtt: false), and the grading system rewards exactly that.

Probe 03 in flight: one connection carrying data over two concurrent network paths with independent per-path state scanner proxy Path 0 · cwnd 14,400 B · MTU 1,452 B · own packet-number space Path 1 · cwnd 12,000 B · MTU 1,200 B · opened by open_path(), validated via PATH_CHALLENGE / PATH_RESPONSE one QUIC connection · Path ID mixed into every AEAD nonce

Probe 03 as the wire sees it: the numbers on each path are this capture's real per-path PathStats, and their divergence is the proof of independent congestion control.

The connection's own vitals are logged alongside: primary-path congestion window 14,400 bytes, MTU discovered to 1,452, GSO offload confirmed on the socket, ACK-frequency extension negotiated, zero packets lost across all 42.

meanwhile, server-sidePATH EVENTS · JOURNAL

Phase 6B · What the server saw

Multipath happens inside the transport, which means that unless someone asks, it happens silently. pqcrypta-proxy asks. It subscribes to noq's path_events() broadcast stream and writes every path establishment, abandonment, and discard to its logs with that path's own statistics attached, at a cost of nothing when no extra paths are opened:

// pqcrypta-proxy/src/quic_listener.rs
let mut events = conn.path_events();
while let Some(ev) = events.next().await {
    if let Ok(quinn::PathEvent::Established { id, .. }) = ev {
        let (rtt, cwnd, mtu) = conn.path_stats(id) /* per-path, not global */ ...;
        info!("Multipath: path {} ESTABLISHED for {} (rtt={}ms cwnd={}B mtu={}B)", ...);
    }
}

Here is what that produces in the live journal. This is phase 6's probe, seen from the other side of the wire:

Jul 26 13:22 pqcrypta_proxy::quic_listener Multipath: path 1 ESTABLISHED for 66.179.95.51:44171 (rtt=0ms cwnd=12000B mtu=1200B)
Jul 26 16:06 pqcrypta_proxy::quic_listener Multipath: path 1 ESTABLISHED for 66.179.95.51:34756 (rtt=0ms cwnd=12000B mtu=1200B)
Jul 26 16:18 pqcrypta_proxy::quic_listener Multipath: path 1 ESTABLISHED for 66.179.95.51:56282 (rtt=0ms cwnd=12000B mtu=1200B)

On the day this page was written, the US East node logged 26 second paths established, arriving roughly every ten to fifteen minutes. Every single one traces back to the scanner's own scheduled scans returning over the node's public egress address (which is why the RTT rounds to zero: the observer lives on the host it is observing). Zero paths were abandoned and zero discarded, because scans end with CONNECTION_CLOSE, which tears down every path with the connection rather than exercising PATH_ABANDON.

Read plainly: no mainstream browser negotiates draft multipath yet, so the multipath internet currently consists of implementations testing each other. That is exactly what the early life of a protocol extension looks like, and it is why the logging exists: when an unfamiliar peer opens a second path for the first time, it will be a log line, not a mystery.

meanwhileCERTIFICATE · X.509

Phase 7 · Papers, please

The certificate chain presented during the handshake gets its own dissection: CN=pqcrypta.com, issued by Let's Encrypt (YE1 intermediate), ECDSA P-384 signed with SHA-384, a four-certificate chain up to ISRG Root X1, two embedded Certificate Transparency SCTs, 48 days until expiry at capture time. OCSP stapling: absent, and recorded as absent, because the scanner reports what is on the wire, not what would be flattering.

The classifier behind this panel goes further than classical PKI. It explicitly recognizes post-quantum signed certificates (ML-DSA, SLH-DSA, FN-DSA) and composite classical+PQC certificates such as mldsa65_rsa3072, because PQ Crypta operates hosts that actually serve them: pqc.pqcrypta.com terminates TLS with an ML-DSA-87 certificate chain today. When the WebPKI's post-quantum migration arrives, this panel will not need updating to notice.

t ≈ 2,128 msCONNECTION_CLOSE

Phase 8 · The wire closes. The verdict unseals.

CONNECTION_CLOSE (0x00): no error · keys discarded

Everything measured now flows through a decision tree that is deliberately unsentimental. There are five grades, and the top one is unreachable without post-quantum cryptography:

Alt-Svc present, HTTP/3 reachable by browsers?
no, but QUIC handshake works → C misconfigured
no, and no QUIC at all → F legacy
yes → is 0-RTT disabled?
no → A fast, but replayable
yes → WebTransport working and post-quantum hybrid key exchange?
not both → A+ most secure classical config
both → A++
this capture's verdict A++ HTTP/3 reachable · 0-RTT off · WebTransport live · X25519MLKEM768

The requirement doing the real work is the last one. Since July 2026 the A++ tier requires a post-quantum hybrid key exchange, which means the scanner's top grade cannot be earned by any deployment that a future quantum adversary could retroactively decrypt. Grades are stored with the scan; the global grade distribution on the analyzer page is the accumulated verdict history of every domain anyone has ever tested.

after the wirePOSTGRESQL · ML

Phase 9 · The connection is dead; the data begins its second life

The full scan JSON lands in PostgreSQL (http3_scan_history, with per-grade totals in http3_scan_totals), joining the dataset behind the analyzer's global statistics. Then the recommendation engine reads it: a scikit-learn RandomForest of 100 trees performing multi-label classification over nine features extracted from each scan (grade, protocol support flags, 0-RTT, WebTransport, Alt-Svc presence), with a GradientBoostingRegressor predicting each recommendation's effectiveness. Only predictions above 30% confidence surface, ranked by confidence times effectiveness, with a rule-based fallback if the ML path ever fails.

Even this A++ capture got homework. The top recommendation flagged that HTTP/1.1 is still enabled on the origin: a legacy attack surface (request smuggling, slowloris) that coexists with the quantum-resistant front door. A perfect grade and an open side entrance are not contradictory, which is precisely why the recommendations exist independently of the grade.

debriefFIELD NOTES FOR IMPLEMENTERS

Field notes: nine lessons so you do not repeat ours

Everything above works today, but not everything worked the first time. These are the concrete problems we hit building the scanner and the server, and what fixed each one. If you are implementing QUIC tooling or multipath, this list is the part of the paper to steal.

  1. Force cold starts or Retry detection lies. QUIC servers issue NEW_TOKEN after a Retry; a client that caches it skips Retry on the next connection. Our Retry detector flip-flopped true/false on alternating scans until the scanner installed a NoneTokenStore. A measurement client must forget on purpose.
  2. Both ends must track the same draft revision. During rollout, our older narrow-probe scanner advertised multipath with a pre-standard frame codepoint; the new server's draft-conformant frames corrupted the old client's HTTP/3 stream. The only casualty of deploying multipath was our previous multipath implementation. Draft extensions interoperate by revision, not by name.
  3. Fold the Path ID into the AEAD nonce. Every path numbers packets from zero, so packet 42 exists on every path. If packet protection ignores the path, two different packets encrypt under the same nonce and AEAD security fails completely, not gracefully. Our rustls fork implements the draft's nonce calculation as encrypt_in_place_for_path(path_id, packet_number, ...).
  4. Multipath deletes the idea of "the" remote address. Any API shaped like connection.remote_address() breaks when a connection has several. Porting our WebTransport layer needed exactly four code fixes, and this was three of them: remote_address() and rtt() now take a PathId.
  5. Alias the fork, do not rewrite the consumers. One manifest line, quinn = { package = "noq" }, let two large codebases compile against a different QUIC engine nearly unchanged. Reserve rewriting for real API divergences; there were only a handful.
  6. Time the protocol, not your own overhead. Our handshake metric once silently included DNS resolution and a per-scan root-store load. The fix: load the certificate store once behind a OnceLock and start the timer at connect(). If a number feeds a grade, audit what the timer actually wraps.
  7. Subscribe to path events or multipath is invisible. The transport manages paths automatically, which means nothing surfaces unless you ask. The server's path_events() subscription (phase 6B) is a few dozen lines and is the only reason we can say, with logs, who opens paths against us.
  8. Report "indeterminate" instead of guessing. This capture's congestion-controller field reads indeterminate: no response body received to measure congestion response, and the second path's RTT reads 0 because observer and target share a host. Both are true statements about measurement conditions. A scanner that fills awkward gaps with plausible values is a fiction generator with a JSON API.
  9. Keep draft features out of the grade. The multipath probe is reported but deliberately not folded into A++ criteria while the draft is unratified. Grades should only reward behavior a site operator can adopt from a standard, not from a moving target.
exhibit listEVERYTHING ANALYZED, AND WHY

The evidence manifest: every check, its reason, its use

This is the scanner's complete coverage, taken from the fields it actually returns. Each group states why it is collected and what the result is used for.

Protocol support why: is HTTP/3 real here, and can browsers find it? · feeds the grade directly

  • http3_supported browsers can reach HTTP/3 (Alt-Svc present + QUIC works)
  • http3_server_capable QUIC answers even if browsers are never told (the grade-C trap)
  • http2_supported / http1_supported fallback surface, including legacy-risk flags
  • protocol_negotiated / browser_protocol what actually got used vs what a browser would use
  • alt_svc the discovery header itself, with endpoints and lifetime
  • status_code / response_time_ms the request worked; total scan wall time

QUIC version behavior why: correctness and ossification resistance · feeds diagnostics + fingerprinting

  • current_version / supported_versions QUIC v1 (RFC 9000) and v2 (RFC 9369) support
  • version_negotiation_received the server correctly rejects unknown versions instead of hanging
  • grease_versions_seen anti-ossification GREASE in the version list
  • retry_packet_received address validation before server state commitment

Transport parameters (peer-advertised, read raw) why: the server's own declared limits · feeds capacity analysis + tier-3 fingerprinting

  • initial_max_data + per-stream / per-direction flow-control windows: throughput ceilings
  • initial_max_streams_bidi/uni concurrency ceilings for HTTP/3 and WebTransport
  • max_idle_timeout / max_udp_payload_size connection lifetime and datagram sizing
  • max_datagram_frame_size unreliable datagram support and its cap
  • active_connection_id_limit headroom for migration and multipath
  • disable_active_migration whether phones may roam networks mid-connection
  • grease_quic_bit RFC 9287 fixed-bit greasing
  • preferred_address / stateless_reset_token / ack_delay params: failover, clean reset, ACK timing contract

TLS 1.3 and post-quantum why: is the handshake quantum-resistant and private? · gates the A++ tier

  • pqc_key_exchange / pqc_hybrid_offered hybrid PQ key exchange (e.g. X25519MLKEM768); required for A++
  • key_share_group(s) / signature_algorithms negotiated and offered crypto, including PQ signatures like ML-DSA
  • ech_supported Encrypted Client Hello: can the hostname itself travel encrypted
  • alpn_protocols / supported_versions / cipher suite: negotiation facts
  • early_data_accepted / max_early_data_size 0-RTT posture (replay risk)
  • grease_extensions_used / grease_key_shares_used ossification hygiene
  • server_name_indication / certificate_compression hello completeness

HTTP/3 SETTINGS and headers why: which application-layer capabilities are switched on · feeds feature detection + recommendations

  • enable_connect_protocol Extended CONNECT, the prerequisite for WebTransport
  • enable_webtransport / h3_datagram WebTransport and datagram flow
  • qpack_* header-compression configuration (table capacity, blocked streams)
  • max_field_section_size header-block limit policy
  • priority_* + priority_update_accepted RFC 9218: verified by sending a real PRIORITY_UPDATE frame, not by reading a header
  • early_hints_103 preload hints before the main response
  • server_timing / accept_ch / nel / report_to observability and client-hint posture

Connection metrics (measured, not quoted) why: real performance of this path · feeds performance panel + honesty checks

  • handshake_time_ms protocol-only handshake duration (timer starts at connect)
  • time_to_first_byte_ms / rtt_estimate/min/max latency truth
  • congestion_window / bytes_in_flight / congestion_controller transport state; reported indeterminate when unmeasurable
  • packets_sent/received/lost / loss_rate_percent path quality of the scan itself
  • path_mtu_discovery / current_mtu / max_packet_size datagram sizing discovered live
  • gso_supported / ack_frequency* / pto_count socket offload and ACK economics

Active capability probes why: claims are only counted when exercised · feeds grade (WebTransport) + capability panels

  • webtransport_capabilities real session opened: latency, datagram size, stream limits, flow-control window, uni/bidi
  • connect_udp MASQUE RFC 9298: a genuine UDP relay round trip (DNS query through the proxy), with timing
  • multipath_probe a second data-carrying path opened via open_path(), with per-path RTT, cwnd, MTU (informational while draft)
  • supports_0rtt early-data acceptance test; refusal is rewarded by the grade

Security posture why: DDoS and spoofing resilience of the QUIC deployment · feeds security panel + recommendations

  • retry_packets_enabled / retry_token_received address validation in action
  • address_validation_enabled / token_validation_enabled the full validation pipeline
  • anti_amplification_limit / amplification_factor the 3x rule, and the measured reality against it
  • stateless_reset_supported clean teardown across server restarts
  • rate_limiting_detected visible throttling behavior

Certificate chain why: trust, expiry risk, and quantum readiness of the PKI · feeds certificate panel + expiry warnings

  • subject / issuer / root_ca / chain_length the full trust path
  • valid_from/until / days_until_expiry operational expiry risk
  • key_type / key_size / signature_algorithm including PQC-signed (ML-DSA, SLH-DSA, FN-DSA) and composite classical+PQC classification
  • ocsp_stapling / ocsp_must_staple / scts_present + count: revocation and transparency posture
  • delegated_credentials / is_valid / validation_errors edge cases stated plainly

Identification and verdict why: who runs this stack, and what should they do next · feeds fingerprint card, grade, ML recommendations

  • server_fingerprint implementation named via three tiers (Server header 95%, known domains 85%, transport-parameter shape 70%) with confidence and characteristics
  • grade the five-tier verdict; A++ unreachable without post-quantum key exchange
  • recommendations RandomForest multi-label predictions over nine scan features, effectiveness-ranked, rule-based fallback
  • persistence: every scan saved to PostgreSQL, powering the global adoption statistics on the analyzer page
end of captureEPILOGUE

Provenance

Every figure above comes from one scan of pqcrypta.com executed at 2026-07-26T13:22:12Z through the same public API the analyzer page calls (POST https://api.pqcrypta.com/http3-scanner/scan), cross-checked against the scanner source (http3_scanner.rs), the proxy source (pqcrypta-proxy), and the vendored noq / h3 / wtransport forks. Run your own capture at the HTTP/3 Analyzer; the numbers will be yours, but the anatomy will be the same.

References

  1. RFC 9000 · QUIC: A UDP-Based Multiplexed and Secure Transport
  2. RFC 9114 · HTTP/3
  3. RFC 9369 · QUIC Version 2
  4. RFC 9218 · Extensible Prioritization Scheme for HTTP
  5. RFC 9298 · Proxying UDP in HTTP (MASQUE CONNECT-UDP)
  6. RFC 9287 · Greasing the QUIC Bit
  7. RFC 8446 · TLS 1.3 · RFC 7838 · HTTP Alternative Services
  8. draft-ietf-quic-multipath-21 · Multipath Extension for QUIC
  9. FIPS 203 · Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM)
  10. draft-ietf-tls-esni · TLS Encrypted Client Hello