<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: executor</title>
    <description>The latest articles on DEV Community by executor (@xilioscient).</description>
    <link>https://dev.to/xilioscient</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4015067%2F3010effa-3210-4e7d-8fc9-720db37bd078.png</url>
      <title>DEV Community: executor</title>
      <link>https://dev.to/xilioscient</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xilioscient"/>
    <language>en</language>
    <item>
      <title>I Built a Post-Quantum Tunnel With a Chrome 124 TLS Fingerprint</title>
      <dc:creator>executor</dc:creator>
      <pubDate>Sat, 04 Jul 2026 13:37:16 +0000</pubDate>
      <link>https://dev.to/xilioscient/i-built-a-post-quantum-tunnel-with-a-chrome-124-tls-fingerprint-31m0</link>
      <guid>https://dev.to/xilioscient/i-built-a-post-quantum-tunnel-with-a-chrome-124-tls-fingerprint-31m0</guid>
      <description>&lt;p&gt;&lt;em&gt;By Alessandro Faraone&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Most "secure tunnel" tools share the same fundamental problem: they are detectable. VPN handshakes have fingerprints. Tor cells have patterns. Even obfuscated proxies leave statistical traces that commercial DPI systems can classify. An adversary who can see your packets does not need to decrypt them — they only need to identify them.&lt;/p&gt;

&lt;p&gt;I spent months thinking about a different question: what if a tunnel produced traffic that was not just encrypted, but fingerprint-identical to a browser at the TLS layer? Not approximately similar — the same ClientHello structure, the same cipher suites, the same extension order, the same JA3/JA4 hashes that DPI classifiers extract to identify Chrome.&lt;/p&gt;

&lt;p&gt;That question became &lt;a href="https://github.com/xilioscient/rinnegato" rel="noopener noreferrer"&gt;Labyrinth-Mesh&lt;/a&gt; — a post-quantum resilient multi-path tunnel written in Rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Threat Model
&lt;/h2&gt;

&lt;p&gt;Before the architecture: what are we actually defending against?&lt;/p&gt;

&lt;p&gt;The system is designed to resist an adversary who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intercepts and records traffic on a subset of paths&lt;/li&gt;
&lt;li&gt;Runs ML-based Deep Packet Inspection (Snort, Zeek, or commercial classifiers)&lt;/li&gt;
&lt;li&gt;Has access to a cryptographically-relevant quantum computer capable of breaking RSA and ECDH&lt;/li&gt;
&lt;li&gt;Has physically compromised one or more relay nodes before the handshake&lt;/li&gt;
&lt;li&gt;Injects replayed packets captured from previous sessions&lt;/li&gt;
&lt;li&gt;Attempts multi-path flow correlation to identify the sender&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a real threat model for journalism, human rights work, and high-value corporate communication. It is not theoretical.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-Path as a Cryptographic Primitive
&lt;/h2&gt;

&lt;p&gt;Most tunnels treat multi-path as a performance feature. In Labyrinth-Mesh it is a cryptographic property.&lt;/p&gt;

&lt;p&gt;Every payload is split into &lt;strong&gt;5 shares&lt;/strong&gt; using Shamir Secret Sharing over GF(2⁸). Any 3 of the 5 shares are sufficient to reconstruct the original. Each share is authenticated with a BLAKE3 tag keyed on &lt;code&gt;(session_key, seq, fragment_index)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The shares are sent over &lt;strong&gt;5 independent network paths simultaneously&lt;/strong&gt;. No single path ever carries enough information to reconstruct the payload. An adversary who intercepts 2 of the 5 paths gets nothing — not degraded security, literally zero information about the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Payload
  │
  ▼
GF(2⁸) Shamir SSS  →  5 shares, k=3 threshold
  │
  ▼
BLAKE3 auth tag     →  8 bytes per share
  │
  ▼
5 independent network paths
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design means the tunnel is resilient not just to DPI but to partial path failure, selective blocking, and relay compromise — all simultaneously.&lt;/p&gt;




&lt;h2&gt;
  
  
  Post-Quantum Key Agreement
&lt;/h2&gt;

&lt;p&gt;The session key uses a &lt;strong&gt;hybrid KEM&lt;/strong&gt; combining two independent primitives:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Security&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Post-quantum&lt;/td&gt;
&lt;td&gt;Kyber-1024 (ML-KEM)&lt;/td&gt;
&lt;td&gt;Resistant to CRQC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Classical&lt;/td&gt;
&lt;td&gt;X25519 ECDH&lt;/td&gt;
&lt;td&gt;Resistant to classical MITM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;session_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BLAKE3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;derive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;labyrinth-hybrid-v3 session&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;kyber_shared_secret&lt;/span&gt; &lt;span class="err"&gt;‖&lt;/span&gt; &lt;span class="n"&gt;x25519_shared_secret&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking one of the two layers does not compromise the session. A quantum computer can break X25519 — it cannot break Kyber-1024. A classical attacker cannot break Kyber or X25519. The session key is secure against both attack classes simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key ratchet&lt;/strong&gt;: every 10,000 packets, the key is rotated via BLAKE3-KDF. Past keys cannot be derived from current keys. Forward secrecy is maintained at the packet level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Receiver identity&lt;/strong&gt;: the receiver's KEM public key is signed with &lt;strong&gt;Dilithium3&lt;/strong&gt; (ML-DSA), a post-quantum signature scheme. The sender can pin the receiver's fingerprint. This eliminates KEM MITM attacks even against quantum adversaries.&lt;/p&gt;




&lt;h2&gt;
  
  
  The DPI Problem and Protocol Steganography
&lt;/h2&gt;

&lt;p&gt;Standard tunnel implementations fail against modern DPI because they produce distinctive packet sizes, timings, and byte patterns. Even when encrypted, the &lt;em&gt;shape&lt;/em&gt; of traffic is revealing.&lt;/p&gt;

&lt;p&gt;Labyrinth-Mesh addresses this at two layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wire-Format Framing (UDP mode)
&lt;/h3&gt;

&lt;p&gt;Each share is wrapped in a frame that mimics a legitimate protocol before being sent over UDP:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path index % 4&lt;/th&gt;
&lt;th&gt;Wire format&lt;/th&gt;
&lt;th&gt;Magic bytes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;TLS 1.3 Application Data&lt;/td&gt;
&lt;td&gt;&lt;code&gt;17 03 03 &amp;lt;len&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;QUIC Short Header&lt;/td&gt;
&lt;td&gt;&lt;code&gt;41 &amp;lt;DCID[8]&amp;gt; &amp;lt;pkt_num[2]&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;WebSocket Binary (masked)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;82 &amp;lt;len&amp;gt; &amp;lt;mask[4]&amp;gt; &amp;lt;masked&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;HTTP/2 DATA frame&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;len[3]&amp;gt; 00 00 &amp;lt;stream_id[4]&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The inner payload is padded with &lt;strong&gt;ChaCha20 pseudo-random bytes&lt;/strong&gt; derived from the session key to reach protocol-typical sizes (TLS ~480 B, QUIC ~500 B, HTTP/2 ~1500 B). The padding is computationally indistinguishable from real encrypted data.&lt;/p&gt;

&lt;p&gt;A Markov-chain inter-arrival time model shapes packet timing to match observed protocol distributions.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/2 Mode — The Real Thing
&lt;/h3&gt;

&lt;p&gt;Wire-format mimicry is good. Actual HTTP/2 with a Chrome 124 TLS fingerprint is better.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--http&lt;/code&gt; flag switches the transport to &lt;strong&gt;real TLS 1.3 + HTTP/2&lt;/strong&gt;. The receiver generates a self-signed certificate at runtime (via &lt;code&gt;rcgen&lt;/code&gt;), exchanges its DER fingerprint over the Dilithium3-signed control channel, and starts a standard HTTPS server backed by &lt;code&gt;tokio-rustls&lt;/code&gt; + &lt;code&gt;hyper&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The sender uses a &lt;strong&gt;custom TLS 1.3 client&lt;/strong&gt; — not a library — built from scratch in Rust. It constructs a ClientHello wire-identical to Chrome 124: all 17 extensions in Chrome's exact order, the same cipher suite list (with GREASE), and an &lt;code&gt;X25519Kyber768Draft00&lt;/code&gt; (0x6399) hybrid post-quantum key share. The JA3 and JA4 fingerprints of every connection are identical to Chrome 124 — the same hashes that passive network monitors and DPI classifiers compute to identify browser traffic.&lt;/p&gt;

&lt;p&gt;The key schedule, AEAD (AES-128-GCM), and record layer follow RFC 8446 exactly. Certificate pinning is enforced by comparing the server's certificate DER byte-for-byte against the fingerprint received over the Dilithium3-authenticated control channel.&lt;/p&gt;

&lt;p&gt;Each share is posted to &lt;code&gt;https://receiver:port/s&lt;/code&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;User-Agent: Mozilla/5.0 ... Chrome/124.0.0.0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Bucket-padded body: [512, 1024, 2048, 4096, 8192] bytes&lt;/li&gt;
&lt;li&gt;Inter-arrival timing sampled from an empirical Chrome distribution (P10 = 2 ms, P50 = 15–80 ms, P90 = 400 ms)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: a passive network observer performing TLS fingerprinting sees a standard Chrome 124 connection. DPI classifiers that extract JA3/JA4 hashes, extension order, or cipher lists cannot distinguish this traffic from a browser visiting a web server. Packet sizes match browser buckets. Timing matches real user behavior.&lt;/p&gt;

&lt;p&gt;The TLS certificate provides transport encryption. The Dilithium3 signature on the ctrl channel provides receiver authentication. These are two orthogonal security layers — the self-signed cert does not need a CA because identity is established post-quantumly before TLS begins.&lt;/p&gt;




&lt;h2&gt;
  
  
  Threshold KEM — Eliminating the Single Point of Compromise
&lt;/h2&gt;

&lt;p&gt;Standard KEM setups have a weakness: if the receiver is compromised before the handshake, the session key is exposed. Labyrinth-Mesh solves this with a &lt;strong&gt;Threshold KEM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The receiver generates N independent Hybrid KEM sub-keypairs (&lt;code&gt;--tkem-relays N&lt;/code&gt;). The sender:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generates a 32-byte master secret M&lt;/li&gt;
&lt;li&gt;Splits M into N Shamir shares with threshold K&lt;/li&gt;
&lt;li&gt;For each relay i: encapsulates with &lt;code&gt;relay_pk_i&lt;/code&gt;, gets &lt;code&gt;kem_secret_i&lt;/code&gt;, encrypts the share with &lt;code&gt;BLAKE3("tkem-share-enc" ‖ kem_secret_i)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sends the full ciphertext bundle over the authenticated control channel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The receiver decapsulates all N ciphertext, recovers the N shares, reconstructs M, and both sides derive &lt;code&gt;session_key = BLAKE3-derive("labyrinth-tkem-v1 session", M)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The security property: an adversary who compromises K−1 sub-keys obtains K−1 Shamir shares. With K−1 &amp;lt; K shares, the master secret M is &lt;strong&gt;information-theoretically secret&lt;/strong&gt; on GF(256). No amount of computation recovers M from fewer than K shares. Even if a quantum computer breaks one of the sub-KEMs, the session key remains secure as long as fewer than K relay sub-keys are compromised.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;labyrinth recv &lt;span class="nt"&gt;--tkem-relays&lt;/span&gt; 3
labyrinth send &lt;span class="nt"&gt;--to&lt;/span&gt; 127.0.0.1:8199 &lt;span class="nt"&gt;--tkem-threshold&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Adaptive Multi-Path Scheduler
&lt;/h2&gt;

&lt;p&gt;Traffic is not distributed in fixed round-robin. Each path gets a continuous quality score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;score_new = α × rtt_component + (1−α) × (1 − loss_rate)
score     = 0.7 × score_old + 0.3 × score_new              [EWMA, α=0.3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shamir shares are assigned to paths by weighted sampling proportional to score. Dead paths (loss &amp;gt; 85%) enter exponential backoff (1 s → 60 s) and are excluded until they recover.&lt;/p&gt;

&lt;p&gt;Probe packets (20 bytes, sent every 500 ms) measure per-path latency. ICMP hard errors (&lt;code&gt;ECONNREFUSED&lt;/code&gt;, &lt;code&gt;ENETUNREACH&lt;/code&gt;, &lt;code&gt;EHOSTUNREACH&lt;/code&gt;) immediately increment the loss counter. The receiver silently discards probes because their BLAKE3 auth tag is invalid.&lt;/p&gt;

&lt;p&gt;This makes the tunnel &lt;strong&gt;self-healing&lt;/strong&gt;: when a path degrades or is selectively blocked, traffic automatically migrates to healthy paths without session interruption.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cover Traffic (XDP)
&lt;/h2&gt;

&lt;p&gt;Even when traffic flows constantly, silence is revealing. If a sender goes idle, the absence of packets allows an adversary to infer activity patterns.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;BPF/XDP program&lt;/strong&gt; runs in kernel space and maintains a constant bitrate (CBR) by injecting cover packets when the channel is idle. This eliminates traffic-silence correlation attacks.&lt;/p&gt;

&lt;p&gt;The cover traffic program uses Linux eBPF (kernel ≥ 5.15) and runs with the scheduler at &lt;code&gt;XDP_TX&lt;/code&gt;. It operates entirely in kernel space — the cover packets never reach userland.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Stack
&lt;/h2&gt;

&lt;p&gt;The full implementation is in Rust 2021:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pqcrypto-kyber     0.7    Kyber-1024 session KEM + Kyber-768 TLS key share
x25519-dalek       2      X25519 ECDH (session KEM + TLS key share)
pqcrypto-dilithium 0.5    Dilithium3 receiver identity signatures
blake3             1.5    Hash, KDF, auth tags, key derivation
sharks             0.5    Shamir SSS over GF(256)
chacha20           0.9    Padding CSPRNG
aes-gcm            0.10   AES-128-GCM AEAD for custom TLS 1.3 records
hmac               0.12   HMAC-SHA256 for TLS 1.3 Finished messages
sha2               0.10   SHA-256 transcript hash
rcgen              0.13   Runtime self-signed cert generation (receiver)
tokio-rustls       0.26   Async TLS 1.3 server (receiver side only)
hyper              1      HTTP/2 client + server
http-body-util     0.1    HTTP body helpers
axum               0.7    Management plane REST API + share endpoint
reqwest            0.12   HTTP client for management plane (TUI, status)
aya                0.12   eBPF userspace loader
tokio              1      Async runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One non-obvious detail on the sender side: the custom TLS 1.3 client does not use any TLS library. It opens a raw &lt;code&gt;TcpStream&lt;/code&gt;, writes the ClientHello bytes directly, parses the ServerHello, performs X25519 (or X25519+Kyber768) key exchange, derives handshake keys via HKDF, decrypts the server's Finished with AES-128-GCM, and sends the client Finished. The Chrome 124 extension order is hardcoded exactly — any deviation changes the JA3/JA4 hash.&lt;/p&gt;

&lt;p&gt;On the receiver side, &lt;code&gt;rustls 0.23&lt;/code&gt; requires an explicit crypto provider before &lt;code&gt;ServerConfig::builder()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;rustls&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ring&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default_provider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.install_default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.ok()&lt;/code&gt; is intentional — it silences the duplicate-install error on re-entry (internally a &lt;code&gt;OnceLock&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;hyper_util::server::conn::auto::Builder&lt;/code&gt; is used instead of the strict &lt;code&gt;http2::Builder&lt;/code&gt; so the server handles both HTTP/1.1 and HTTP/2 transparently, in case TLS ALPN negotiation falls back.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Makes This Different
&lt;/h2&gt;

&lt;p&gt;Existing tools in this space generally pick one property:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt;: use standard crypto, accept traffic fingerprinting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stealthy&lt;/strong&gt;: obfuscate, sacrifice some security guarantees&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-path&lt;/strong&gt;: split traffic, but use classical crypto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Labyrinth-Mesh tries to provide all three simultaneously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Post-quantum secure&lt;/strong&gt;: hybrid KEM against CRQC; Dilithium3 receiver identity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wire-undetectable in HTTP mode&lt;/strong&gt;: actual TLS 1.3 + HTTP/2 with Chrome fingerprint, indistinguishable from browser traffic at the DPI layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Information-theoretically multi-path&lt;/strong&gt;: Shamir SSS means no partial path subset reveals anything&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Threshold KEM adds a fourth property that most tunnels ignore entirely: resilience to relay compromise during the key setup phase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Current Limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;XDP cover traffic&lt;/strong&gt; requires Linux ≥ 5.15 and root. Most deployment environments qualify; edge deployments on older kernels cannot use this feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Threshold KEM&lt;/strong&gt; in the current implementation places all sub-keypairs on the same receiver machine. Full protection against physical relay compromise requires distributing sub-keypairs to independent hosts — the protocol supports this but the routing infrastructure is not yet built.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP mode steganography&lt;/strong&gt; defeats DPI-based classifiers and statistical analysis. It does not help if the receiver IP is layer-3 blocked. A future version will add domain-fronting support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Markov IAT&lt;/strong&gt; in UDP mode models parametric distributions, not empirically-captured real traffic. A well-resourced adversary with ML classifiers trained on real traffic could potentially distinguish it from genuine TLS/QUIC. HTTP mode does not have this limitation because it uses the actual protocol stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# UDP mode — 3 terminals&lt;/span&gt;
labyrinth recv &lt;span class="nt"&gt;--ctrl&lt;/span&gt; 0.0.0.0:8199 &lt;span class="nt"&gt;--udp&lt;/span&gt; 0.0.0.0:8200
labyrinth-tui &lt;span class="nt"&gt;--mgmt&lt;/span&gt; 127.0.0.1:9090
labyrinth send &lt;span class="nt"&gt;--to&lt;/span&gt; 127.0.0.1:8199

&lt;span class="c"&gt;# HTTP/2 mode — TLS fingerprint identical to Chrome 124 (JA3/JA4)&lt;/span&gt;
labyrinth recv &lt;span class="nt"&gt;--ctrl&lt;/span&gt; 0.0.0.0:8199 &lt;span class="nt"&gt;--udp&lt;/span&gt; 0.0.0.0:443 &lt;span class="nt"&gt;--http&lt;/span&gt; &lt;span class="nt"&gt;--sign&lt;/span&gt;
labyrinth send &lt;span class="nt"&gt;--to&lt;/span&gt; 127.0.0.1:8199 &lt;span class="nt"&gt;--remotes&lt;/span&gt; 127.0.0.1:443 &lt;span class="nt"&gt;--http&lt;/span&gt;

&lt;span class="c"&gt;# Threshold KEM — compromise-resilient key setup&lt;/span&gt;
labyrinth recv &lt;span class="nt"&gt;--tkem-relays&lt;/span&gt; 3
labyrinth send &lt;span class="nt"&gt;--to&lt;/span&gt; 127.0.0.1:8199 &lt;span class="nt"&gt;--tkem-threshold&lt;/span&gt; 2

&lt;span class="c"&gt;# Container&lt;/span&gt;
docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://github.com/xilioscient/rinnegato" rel="noopener noreferrer"&gt;github.com/xilioscient/rinnegato&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Alessandro Faraone — Feedback and security reports welcome at the repository.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>rust</category>
      <category>networking</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
