pqtransport logopqtransport

Architecture

Module layout, barrels, hybrid concat, and the swissarmyknife / pqforge mapping for pqtransport.

pqtransport is a protocol layer. It does not implement ML-KEM, ML-DSA, X25519, AES-GCM, or HKDF. Those come from package:pqforge. It does not hand-roll state machines, Result, caches, or breakers. Those come from package:swissarmyknife.

  application (HTTP/1.1, DNS, mDNS, QUIC frames)
           │
           ▼
  pqtransport  ── StateMachine / Result / Cache / CircuitBreaker / Throttler
           │        (swissarmyknife)
           ▼
  pqforge      ── ML-KEM / ML-DSA / X25519 / AES-256-GCM / ChaCha / HKDF
           │
           ▼
  pqcrypto     ── FIPS 203/204/205 primitives + KAT evidence

Package layout#

lib/
  pqtransport.dart          # web-safe public barrel (no dart:io, no dart:ffi)
  pqtransport_io.dart       # re-exports barrel + IoDatagramChannel
  src/
    core/                   # lengths, errors, bytes, hybrid, transcript, zeroize, crypto facade
    socket/                 # PqTransportSocket, memory pair, IO UDP
    udp/                    # datagram AEAD, replay, encrypted session
    tls/                    # machines, records, handshake, client/server/socket, key schedule
    dns/                    # records, wire, client, DoH/DoT helpers
    mdns/                   # probe/announce/browse, signed TXT
    quic/                   # packet protect, frames, flow control, machines
    http/                   # HTTP/1.1 codec, HTTP/3 frames, PqHttpClient

All protocol sizes live in lib/src/core/lengths.dart. A numeric literal for a protocol size anywhere else is a defect.

Barrels#

ImportContainsMust not contain
package:pqtransport/pqtransport.dart Codecs, machines, hybrid, TLS, DNS, HTTP, memory sockets dart:io, dart:ffi, SecureSocket
package:pqtransport/pqtransport_io.dart Everything above plus IoDatagramChannel Crypto of its own

Callers on web supply a byte channel (MemoryByteSocket or their own PqTransportSocket) and run TLS over it. Raw UDP / multicast require the IO barrel on VM/mobile/desktop.

Hybrid concat (normative)#

X25519MLKEM768
  client = ek_mlkem (1184) || pk_x25519 (32)     = 1216
  server = ct_mlkem (1088) || pk_x25519 (32)     = 1120
  ss     = ss_mlkem (32)   || ss_x25519 (32)     = 64

SecP256r1MLKEM768
  client = pk_p256 (65) || ek_mlkem (1184)       = 1249
  server = pk_p256 (65) || ct_mlkem (1088)       = 1153
  ss     = ss_ecdhe (32) || ss_mlkem (32)        = 64

SecP384r1MLKEM1024
  client = pk_p384 (97) || ek_mlkem1024 (1568)   = 1665
  server = pk_p384 (97) || ct_mlkem1024 (1568)   = 1665
  ss     = ss_ecdhe (48) || ss_mlkem (32)        = 80

Implemented in lib/src/core/hybrid.dart. See Hybrid Groups.

TLS 1.3 (0.1.0 shape)#

RFC 8446-shaped ClientHello / ServerHello (legacy_version 0x0303, supported_versions, key_share, SNI, ALPN). Cipher suite is IANA 0x1302 (AES-256-GCM + HKDF-SHA-384, default) or IANA 0x1303 (ChaCha20-Poly1305 + HKDF-SHA-256). Private-use 0xFF00 is retired. Handshake vs application epochs reset the record sequence. Finished is HMAC over the transcript (SHA-384 for 0x1302, SHA-256 for 0x1303). Certificate is a raw ML-DSA-65 public key (OPEN-04).

Wording stays "RFC 10024-aligned hybrid share encoding with unit-tested concatenation," not "OpenSSL interop."