RouteHardenHire us
Back to blog
Anonymity Engineering··23 min read·advanced

Mix networks: Loopix and Nym

From Chaumian mixes to Loopix and Nym: delay, cover traffic, Sphinx packets, and the anonymity-latency-bandwidth tradeoff.

The previous two modules established that low-latency anonymity overlays leak through traffic shape and that padding raises the cost of attack but cannot make low-latency systems safe against a global passive adversary. The structural reason is straightforward: an interactive system passes packets through quickly enough that the timing of the original traffic survives at the output. Padding can hide which gaps are silence and which are activity, but it can't make a 50ms-latency tunnel statistically indistinguishable from no traffic at all without paying so much in bandwidth that the system becomes unusable.

Mix networks are the family of designs that says: fine, we'll pay the latency. Instead of forwarding packets in milliseconds, mixes batch traffic at each hop, deliberately delay it, reorder it, and pad it with cover traffic, so that an adversary observing both ends of the network sees timing patterns at the input and timing patterns at the output that are no longer correlated. Anonymity goes up substantially; latency goes from "interactive" to "minutes-to-hours." The trade is structural and intentional.

This module walks through mix-network design from David Chaum's 1981 originating paper to the modern Loopix architecture and the Nym deployment. We'll cover the Sphinx packet format, batched-vs-Poisson mixing, why cover traffic is essential and not optional, the anonymity-latency-bandwidth trilemma that quantifies the tradeoffs, and the operational challenges that mixnets face even when their anonymity story is much stronger than Tor's. The honest picture: mixnets solve some problems Tor doesn't and don't solve others. They are appropriate when the threat model justifies high latency and when applications can tolerate it.

Prerequisites

Learning objectives

  1. Explain why mix networks pursue stronger anonymity than low-latency onion routing by intentionally adding delay and cover traffic.
  2. Compare Chaumian mixes, Sphinx packet format, Loopix Poisson mixing, and Nym's deployment model.
  3. Reason about anonymity, latency, and bandwidth as a design trilemma rather than isolated metrics.
  4. Describe what mixnets improve against global observation and what operational problems they introduce in return.

Why mixes exist at all

The previous modules' lesson, restated: low-latency anonymity systems preserve timing patterns. An interactive Tor circuit produces packets at the exit on a timing schedule that's visibly correlated with the packets the user sent into the guard. Encryption hides what's in those packets; correlation works on when they arrive, not what they contain. A global passive adversary observing both endpoints can match the patterns and break the anonymity, even when every cell in between is encrypted.

The structural fix isn't a better cipher or smarter padding within the low-latency frame. It's giving up the interactive frame entirely. If the system can introduce per-hop delays measured in seconds rather than milliseconds, batch many users' messages together, reorder them, and emit them in random order, then the output stream has no usable timing relationship to the input stream. Correlation becomes statistically infeasible.

This is what mix networks do. The cost is that messages take minutes to hours to traverse the network. Real-time interactive use (browsing, voice, gaming) is impossible. The applications mixnets support are messaging, email, asynchronous notifications, document exchange, financial transactions where seconds-to-minutes latency is acceptable in exchange for stronger anonymity guarantees.

For some users this trade is wrong (most everyday browsing doesn't require GPA-level defense). For some users it's exactly right (whistleblowers, activists in authoritarian states, journalists handling sensitive sources, dissident communicators). Mixnets aren't a Tor replacement; they're a different point on the design space, addressed at threat models Tor explicitly accepts losing.

Chaum's original insight

David Chaum's 1981 paper "Untraceable electronic mail, return addresses, and digital pseudonyms" introduced the mix concept that remains foundational. The setup:

A mix is a relay that receives many messages, encrypted to it specifically, and then:

  1. Decrypts each incoming message (peeling one layer of nested encryption).
  2. Buffers messages until enough have accumulated (a "batch").
  3. Reorders the messages randomly.
  4. Forwards each message to its next hop.

The properties this gives:

  • Encryption hides content from the mix and from observers. The mix only sees ciphertext until it's the message's specifically-keyed envelope to peel.
  • Batching prevents per-message timing inference. A message arriving at time T is forwarded along with N other messages, all at roughly time T + δ; the receiver can't tell which output corresponds to which input.
  • Reordering breaks the entry-to-exit correspondence. Within a batch, the order at output is randomized; correlating input order to output order isn't possible.

Chain multiple mixes (Chaum proposed at least three), each operated by a different party, and the anonymity properties compound. No single mix knows both the original sender and the final recipient. As long as one mix in the chain is honest, anonymity is preserved.

The Chaumian mix is conceptually beautiful. The implementation problems are practical:

  • Latency is the worst case. A message has to wait for the batch to fill before being forwarded. If a mix fills its batch every 5 minutes, every message waits up to 5 minutes per hop. With 3 hops, total latency is 15-30 minutes.
  • Throughput is bounded by the slowest hop. A flood of messages backs up at the slowest mix.
  • Cover traffic is needed for low-utilization periods. If only one user sends a message in an hour, the batch contains one message; reordering one message preserves perfect linkability.
  • Operator trust is concentrated. Each mix sees its own input batch and output batch; mix operators can collude pairwise to break anonymity.

Chaum's design was the start, not the end. Modern mixnets address each of these issues with various refinements while preserving the core "batch, mix, forward" pattern.

Packet format and layered forwarding

A practical mixnet needs a packet format that's compact (so messages fit in network MTUs), supports per-hop processing efficiently, prevents replay attacks, and includes sender or receiver anonymity primitives.

The Sphinx packet format (Danezis and Goldberg, 2009) is the modern de facto standard. A Sphinx packet has the same size at every hop in its journey — the layered encryption peels off one layer at each hop, but new padding fills the freed space, so the packet remains the same fixed size. This solves a critical problem: variable-length packets at intermediate hops would be a discriminator the mix couldn't hide.

A Sphinx packet contains:

  • Header. Encrypted routing information for each remaining hop, plus a per-hop MAC.
  • Per-hop payload section. The current hop's instructions (which next hop to forward to, with what header).
  • Application payload. The actual message (or a chunk of one, if longer than a single Sphinx packet).
  • Padding. Filler that maintains constant size.

At each hop:

  1. Mix decrypts the header section using its private key.
  2. Mix verifies the MAC.
  3. Mix extracts: next-hop address, the next-hop header (which is already encrypted to the next hop).
  4. Mix replaces the header with the (smaller) next-hop header plus padding to maintain size.
  5. Mix queues the packet for the batch.
  6. Eventually mix forwards the packet to next hop.

Critical properties:

  • Constant size. Each hop's processing produces a packet of identical size. Observers can't distinguish first-hop packets from third-hop packets.
  • Per-hop unforgeability. The MAC ensures a packet can't be modified in flight; replay protection (via per-message identifiers and a replay cache) prevents replay attacks.
  • Sender and receiver anonymity. With clever construction, the same packet format can support both anonymous-sender and anonymous-receiver semantics.
  • No persistent state between mixes. Each packet carries its own routing instructions; no inter-mix coordination is needed for routing.

The Sphinx specification is dense (the original paper is 26 pages of formal protocol description) but the practical implementation is relatively compact — modern Sphinx libraries are a few thousand lines of code total. The packet format is what makes mixnets engineering-feasible at scale; without it, the routing problem alone would be a barrier.

From batching to Poisson mixing

Classical Chaumian mixes use threshold batching or timed batching:

  • Threshold batch: wait until N messages accumulate, then flush.
  • Timed batch: wait T seconds, then flush whatever's queued.

Both have a problem: the batch boundaries are observable. A mix that emits 100 messages exactly at 5-minute intervals is itself a fingerprint; an adversary can correlate "I see Alice send to her ISP at 2:01pm; the mixnet's first hop emits a batch at 2:05pm; that's likely her message in that batch." Batches give some mixing, but the discrete batching pattern itself leaks information.

Loopix (Piotrowska et al., 2017) introduced Poisson mixing: instead of batching, each message is independently delayed by a random duration drawn from a Poisson distribution. The mix forwards messages continuously as their independent delays expire. The aggregate statistical effect is similar to batching (many messages exit together in a flow), but no discrete batch boundary exists.

The Loopix advantages:

  • Smoother output traffic. No "burst-emit-burst-emit" pattern from threshold batching; the output is more uniform.
  • Per-message anonymity bound. The probability that an adversary correctly correlates a specific input to a specific output can be analytically computed from the Poisson parameter.
  • Tunable. The Poisson parameter (the delay's average) can be set per-mix or per-message, trading anonymity strength for latency.
  • No batch-fill waiting. Even one message in the system is mixed (with whatever cover traffic happens to be flowing); no need to wait for a batch to fill.

Loopix typical numbers: per-hop delay around 50-300ms, three hops, total latency in the seconds range — substantially better than Chaumian mixes' minutes-to-hours, while still providing meaningful anonymity bounds. Cover traffic is the other half of Loopix; without it the analytical anonymity bound assumes traffic levels that may not actually be present.

Cover traffic and loop messages

A mixnet with no cover traffic provides poor anonymity in low-traffic periods. If only one real message is in flight, no amount of mixing helps — the output corresponds to that one input.

Loopix introduced two cover-traffic mechanisms:

Drop cover traffic: Each client periodically sends dummy messages to a special "drop" address. The dummy messages traverse the network like real messages — encrypted as Sphinx packets, mixed at each hop, processed end-to-end. They differ from real messages only in that the recipient is the drop address, which discards them. From an observer's perspective, drop cover is indistinguishable from real traffic.

Loop messages: Each client sends messages addressed back to themselves, traversing the full mixnet path. The client receives their own loop message after the mixnet's normal latency. Loop messages provide:

  • Continuous traffic from each client (so an observer always sees activity, not just when the client is "really" communicating).
  • A liveness check: if the loop message doesn't return, something is broken.
  • Additional ambiguity: real messages and loop messages are indistinguishable in transit.

The cost: cover traffic is bandwidth. Loopix's recommended cover traffic rates are in the tens of bytes per second per client — modest for a desktop user, more meaningful for a mobile user. The total system bandwidth is the sum of cover and real traffic; for a mostly-idle network, cover dominates.

Cover traffic is essential, not optional. A mixnet without it has anonymity only when many real messages are flowing simultaneously; in low-traffic periods, a single real message can be tracked through the network. Loopix's contribution wasn't just Poisson mixing — it was integrating cover traffic so that the anonymity argument holds even when real traffic is sparse.

Loopix as a modern reference architecture

The Loopix architecture has four roles:

Clients. End users running Loopix-aware applications. Generate messages, encrypt them as Sphinx packets, dispatch them to providers. Maintain loop and drop cover traffic.

Providers. First and last hops in the path. Each client is associated with a provider (analogous to an email provider — a service the client trusts to be online). Providers receive client messages and forward them into the mix network; they also receive incoming messages destined for their clients and queue them until the client polls. Providers handle the asynchrony between always-online network nodes and intermittently-online clients (a phone might be offline for hours; the provider buffers).

Mixes. Intermediate hops. Receive Sphinx packets from providers or other mixes, run Poisson-mixed forwarding, emit to next hop. Mixes don't know their own positions (first/middle/last) — they just process Sphinx packets per the routing instructions encoded in each.

Recipients. Either other Loopix clients (in which case the message goes to their provider, queued until they poll), or external destinations (in which case the last mix hop sends to the destination over normal IP).

The trust model:

  • The client trusts their provider for availability (provider sees that the client is sending traffic, but doesn't see destinations).
  • The client trusts that not all mixes are colluding (anonymity holds as long as at least one honest mix is in the path).
  • Mixes don't need to be trusted for confidentiality; the layered Sphinx encryption handles that.
  • Providers can be subpoenaed for their queued messages; clients should consider provider trust accordingly. (The provider can see "this client is associated with these incoming messages awaiting pickup," even though they can't read the messages.)

Loopix's anonymity argument is formal and quantitative: under the Poisson mixing assumption and a specified amount of cover traffic, the probability that an adversary correctly links a sender to a receiver is bounded. The bound depends on the Poisson parameter, the network size, and the cover traffic rate. Stronger anonymity requires longer per-hop delays or more cover traffic.

Nym as deployment strategy, not just a paper design

Loopix is a paper protocol. Nym is a paper protocol plus an attempted internet-scale deployment with operator incentives, governance, and an actual user-facing service.

Nym's contributions beyond Loopix:

Operator incentives. Nym uses a token-based incentive structure to pay mix-node operators. The argument: a robust mixnet needs many independent operators, and "run a mix node out of altruism" doesn't scale. Tokens give operators an economic reason to provide bandwidth. (The token economics raise questions of their own — token-based systems have well-known problems around speculative cycles, regulatory uncertainty, and incentive alignment that distract from the protocol-design discussion. This module focuses on the technical architecture, not the economics.)

Operator diversity through stake-based selection. Mix nodes register with the network by staking tokens; the routing layer selects nodes weighted by stake (and by reputation/uptime). The aim is to make operator diversity self-sustaining without a central directory authority.

Application gateway. The Nym deployment includes gateways that translate between the mixnet and external applications (web requests, API calls). This is the practical bridge that lets an existing application use the mixnet without being itself rewritten — the gateway handles Sphinx encoding, route selection, and result reassembly.

Public mixnet. Unlike Loopix-the-paper, Nym is a live deployed network. As of 2026 it has hundreds of mix nodes operated by independent parties, with users sending real traffic. Deployment surfaces operational issues (operator churn, performance variance, abuse handling, application integration) that don't appear in paper protocols.

The honest engineering picture: Nym is not a finished solution. The network has demonstrated that mixnet deployment at internet scale is possible; it has not demonstrated that the deployed network achieves the analytical anonymity bounds Loopix claims. Real-world operator behavior, real-world traffic patterns, and real-world abuse handling all introduce variance from the formal model. Nym's deployment is a useful experiment that's still in progress; treating it as proof of mixnet practicality is overconfident; treating it as worthless is also wrong. It's a serious system that demonstrates serious tradeoffs.

The anonymity-latency-bandwidth trilemma

The fundamental tradeoff in mix-network (and anonymity-overlay generally) design is between three quantities:

  • Anonymity: how confidently can an adversary identify the sender of a given message? Stronger anonymity = lower confidence.
  • Latency: how long does a message take to traverse the network? Lower latency = better usability.
  • Bandwidth: how much total traffic does the network use, including cover traffic? Lower bandwidth = cheaper to run, more accessible to users on metered connections.

The trilemma claim, made formal in research like "Studying the anonymity trilemma with a discrete-event mix network simulator" (Das et al., 2021): you can have any two of these but not all three at high quality simultaneously.

To increase anonymity, you need either more delay (more mixing per message) or more cover traffic (more ambiguity per observation). Either choice costs latency or bandwidth. To reduce latency, you need shorter per-hop delays, which means weaker mixing per message — anonymity drops. To reduce bandwidth, you cut cover traffic, which weakens the anonymity bound during low-real-traffic periods.

Real systems pick a point on this surface:

  • Tor: Maximizes usability (low latency, modest bandwidth). Trades off against GPA-resistance (weak anonymity against the strongest adversary).
  • Loopix: Picks medium latency (seconds), modest cover traffic, gets strong anonymity bounds against GPAs.
  • Mixmaster (classical email mix): Maximizes anonymity (long delays, batched messages, plenty of cover when it's available). Trades off latency (hours).
  • Hypothetical perfect mixnet: Constant-rate transmission everywhere, no usable bandwidth left for real traffic. Anonymity is mathematical; bandwidth is impractical.

The trilemma is a useful framework for evaluating systems honestly. A system that claims "fast, anonymous, and low-bandwidth" is overstating something. The right question is: which two does it actually deliver, and how well?

Where mixnets still struggle

Even with strong protocol design, deployed mixnets face real engineering problems:

Reliability. Each hop introduces delay and risk of message loss. With three hops at 200ms average delay each plus cover traffic and queueing, end-to-end message delivery times are seconds-to-tens-of-seconds in the best case. With operator failures or congestion, delivery can take minutes. Acknowledgment protocols add round trips; dropped messages need retry, doubling effective latency.

Mobile intermittency. Phones and laptops are offline frequently. The provider role buffers messages, but coordinating when a client is online enough to poll, what messages have been delivered, and how to handle conflicting updates is a small distributed-systems problem.

Application integration. Most applications are designed assuming TCP-style request/response with sub-second latency. Mixnet integration requires either restructuring the application to be asynchronous (significant work for legacy apps) or wrapping it in a translator gateway (which becomes its own trust point).

Abuse handling. A mixnet that anonymizes traffic also anonymizes abusive traffic. Spam, DoS attacks, illegal content distribution all become harder to attribute. The community-and-policy responses Tor has developed (BadExits flag, abuse complaints workflow, exit-node policies) need to be reinvented for the mixnet context.

Operator economics. Mix-node operators bear bandwidth costs and legal risks. Without economic incentives or strong altruistic motivation, the operator pool shrinks. Nym's token-based model is one attempt; it remains to be seen whether it produces sustainable operator diversity.

Censorship. A mixnet is a fixed set of identifiable IPs (the mix nodes). Adversaries can block mixnet entry points; users may need additional bridge-like infrastructure to reach the mixnet at all. See domain-fronting-2026 for the broader censorship-evasion-front-end pattern.

Application latency tolerance. Even messaging applications have UX expectations of "message delivered within a few seconds." A mixnet that delivers in 30 seconds feels slow even for asynchronous use; users may not stick with it.

These are real problems, not arguments against mixnets. They're the engineering work that has to happen for mixnets to become broadly usable rather than research-curiosity systems. Nym is making progress on several of these; many remain open.

Hands-on exercise

Simulate queueing delay in a toy mix.

Tools: python3. Runtime: 25 minutes.

Simulate a 3-hop mix network with Poisson per-hop delays. Compare the input/output timing correlation to a no-delay (Tor-like) baseline.

import random
import statistics
from typing import List, Tuple

def simulate_path(input_times: List[float], hops: int = 3,
                  per_hop_mean_delay: float = 0.0) -> List[float]:
    """Simulate per-hop random delays. With per_hop_mean_delay=0, behaves like
    a low-latency overlay. With nonzero delay, simulates Poisson mixing."""
    output_times = []
    for t_in in input_times:
        t = t_in
        for _ in range(hops):
            if per_hop_mean_delay > 0:
                t += random.expovariate(1 / per_hop_mean_delay)
        output_times.append(t)
    return sorted(output_times)

# Generate 100 input messages over 60 seconds
n = 100
input_times = sorted(random.uniform(0, 60) for _ in range(n))

# Low-latency simulation: minimal delay, output order matches input order
out_low = simulate_path(input_times, hops=3, per_hop_mean_delay=0.0)
# High-latency mixnet simulation: 1-second mean delay per hop
out_mix = simulate_path(input_times, hops=3, per_hop_mean_delay=1.0)

# Compute correlation: how well does input order predict output order?
def order_correlation(in_t, out_t):
    in_rank = {t: i for i, t in enumerate(sorted(in_t))}
    out_rank = {t: i for i, t in enumerate(out_t)}
    diffs = []
    for it, ot in zip(in_t, out_t):
        diffs.append(abs(in_rank[it] - out_rank[ot]))
    return statistics.mean(diffs)

print(f"Low-latency mean rank deviation: {order_correlation(input_times, out_low):.2f}")
print(f"Mixnet mean rank deviation:      {order_correlation(input_times, out_mix):.2f}")
print(f"End-to-end latency low-latency:  {max(out_low) - max(input_times):.2f}s")
print(f"End-to-end latency mixnet:       {max(out_mix) - max(input_times):.2f}s")

Expected behavior:

  • Low-latency: rank deviation near zero (output order matches input order). End-to-end latency is essentially zero.
  • Mixnet: rank deviation substantial (output order is scrambled relative to input order). End-to-end latency is on the order of 3 seconds (3 hops × 1-second mean delay).

The correlation result is the key insight: in the low-latency case, an adversary observing both the input and output order can match them up with confidence. In the mixnet case, the order is sufficiently scrambled that matching is harder.

Stretch: extend the simulation to add cover traffic. Generate 100 dummy messages randomly distributed in time, mix them with the real messages, and observe how cover traffic changes the input/output order analysis.

Map the roles in a Loopix-style system.

Tools: plain text. Runtime: 10 minutes.

Draw the following roles and label what each one sees about a single message from Alice to Bob:

Alice                                                              Bob
  |                                                                ^
  v                                                                |
Alice's    →   Mix1   →   Mix2   →   Mix3   →   Bob's
provider                                          provider
  |                                                  |
  v                                                  v
"sees:        "sees:    "sees:    "sees:           "sees:
Alice as       prev      prev      prev            next hop is
sender,        hop is    hop is    hop is          local recipient,
encrypted      provider, mix2,     mix2,           encrypted Sphinx
Sphinx         next is   next is   next is         packet"
packet"        mix2"     mix3"     Bob's
                                   provider"

Make explicit:

  • Alice's provider knows who Alice is and that she's sending traffic; doesn't know to whom.
  • Each mix knows only its predecessor and successor.
  • Bob's provider knows Bob is the recipient and that messages are arriving for him; doesn't know who sent them.
  • Bob knows the message and (after decryption) what Alice's content was, but not which network path it took.

Compare this to Tor (3 hops, no provider role, no asynchrony). What does Loopix add that Tor doesn't have?

Common misconceptions and traps

"A mixnet is just Tor with more hops." The differences are structural, not just quantitative. Mixnets add per-hop random delay (Tor doesn't), cover traffic (Tor's is minimal), batch-or-Poisson mixing semantics (Tor forwards as fast as possible), and a different threat-model focus (mixnets target GPA resistance; Tor accepts losing against GPAs). More hops alone wouldn't address the timing-correlation problem.

"Delay alone provides anonymity." Delay helps only in combination with batching/mixing and cover traffic. A system that delays every message by 1 second but processes them in arrival order provides little anonymity benefit — the order at output still matches input. Random per-message delay plus parallel processing of many messages plus cover traffic is what produces meaningful anonymity bounds.

"If a system is stronger against correlation, it's automatically practical for all applications." Real-time interactive use (browsing, voice, gaming) remains impossible at mixnet latencies. Mixnets address messaging, asynchronous notifications, document submission — applications where seconds-to-minutes latency is acceptable. They don't replace Tor for browsing; they complement it for different threat models.

"Nym proves the deployment problem is solved." Nym demonstrates that internet-scale mixnet deployment is achievable. It doesn't demonstrate that the deployed network achieves the analytical anonymity bounds the protocol claims, that operator incentives are stable long-term, or that user adoption will reach levels where the anonymity-set size is consistently large enough. The deployment is a serious experiment in progress, not a finished solution.

"Batching and Poisson mixing are interchangeable." They produce different latency distributions and different observability properties. Batching has discrete batch boundaries observable in the output stream; Poisson mixing produces a smoother continuous output. Batching has worse worst-case latency (waiting for batch to fill) but possibly better best-case throughput. The choice between them is a real engineering decision, not a stylistic preference.

"Cover traffic is wasteful." Cover traffic is essential for anonymity in low-traffic periods. Without it, a mixnet provides anonymity only when many real messages are flowing simultaneously; in idle periods, a single real message can be tracked. The "waste" is what buys anonymity uniformity across traffic levels.

"Mixnets are obsolete because Tor exists." Tor and mixnets address different threat models. Tor doesn't claim GPA resistance; mixnets do. Users whose threat model includes GPAs need mixnets (or equivalent measures) and shouldn't be talked out of them by "Tor is good enough" arguments that don't reckon with the threat model.

"Sphinx is just a packet format." It's a packet format that solves multiple problems: constant size at every hop (preventing size-based discrimination), per-hop authentication (preventing tampering), replay protection, sender and receiver anonymity primitives. The format choice has substantial security implications; using a non-Sphinx format would require addressing all those problems separately.

Wrapping up

Mix networks are the answer to "what if we accept high latency in exchange for stronger anonymity?" Chaum's 1981 paper introduced the foundational batch-and-reorder concept; Sphinx made packet formats engineering-feasible; Loopix added Poisson mixing and cover traffic with formal anonymity bounds; Nym attempted internet-scale deployment with operator incentives.

The anonymity-latency-bandwidth trilemma frames the design space honestly: stronger anonymity costs latency, bandwidth, or both. Real systems pick a point on this surface; no design escapes the trade. Tor sits at the low-latency, low-bandwidth, weak-anonymity-against-GPA corner; mixnets at the medium-latency, moderate-bandwidth, strong-anonymity-against-GPA region; theoretically perfect mixnets at the high-latency, high-bandwidth, very-strong-anonymity extreme.

For threat models that include GPAs and don't require interactive latency, mixnets are the right architecture. For threat models satisfied by Tor's weaker GPA-acceptance position, mixnets are over-engineering. The engineering question is which trade your threat model justifies; the right answer varies by user.

Track 4 continues with the application-layer leakage that all transport-level anonymity (low-latency or high-latency) must be composed with. The next module (browser-fingerprinting-in-depth — coming soon) covers how browsers leak identifying information at the application layer regardless of transport, and how those leaks compose with transport-layer anonymity to determine effective anonymity in real deployments.

Further reading