CoinJoin Probing Attack
A practical analysis of how a malicious actor can deanonymize CoinJoin participants through probing, and the countermeasures that neutralize it.
1. The Problem: Privacy in CoinJoin
CoinJoin is a collaborative Bitcoin transaction where multiple participants combine their inputs and outputs into a single transaction. When done correctly, an outside observer cannot determine which input funded which output, providing transaction privacy.
In JoinMarket-style CoinJoins, there are two roles:
Makers are always-online bots that advertise offers on a public orderbook. Each maker has a wallet divided into multiple mixdepths (separate accounts, typically 5). They hold funds across these mixdepths and earn fees for participating in CoinJoins. Makers are selected weighted by their fidelity bond, a time-locked Bitcoin deposit that proves commitment and makes Sybil attacks expensive.
Takers initiate CoinJoin transactions. They select makers from the orderbook, agree on a CoinJoin amount, and coordinate the transaction. The taker's goal is privacy: after the CoinJoin, their output should be indistinguishable from the makers' outputs.
The anonymity set of a CoinJoin with N makers is N + 1: an observer cannot tell which of the N+1 equal-amount outputs belongs to the taker. A CoinJoin with 8 makers gives an anonymity set of 9.
This works well against passive observers. But what about an active attacker?
2. How Probing Works
A probing attack exploits the CoinJoin negotiation protocol. Before a CoinJoin transaction is signed and broadcast, makers must reveal their input UTXOs to the taker. Normally this is fine because the taker is honest and completes the transaction. But a malicious taker can abuse this:
- Probe: The attacker initiates a CoinJoin with a maker, requesting the maker's maximum offer amount. The maker reveals all UTXOs in their largest mixdepth. The attacker records them and aborts the transaction.
- Accumulate: The attacker repeats this with many or all makers, building a database of known UTXOs per maker.
- Identify: When an honest taker later creates a CoinJoin, the attacker observes the on-chain transaction. If any input matches a known UTXO from the attacker's database, the corresponding maker is identified.
- Cascade: When a maker is identified, the attacker also learns their co-spent inputs (other UTXOs the maker contributed) and their change output. These new UTXOs are added to the database, enabling identification in future CoinJoins. The attacker's knowledge snowballs.
- Deanonymize: If the attacker can identify all N makers in a CoinJoin, the remaining unidentified output must belong to the taker. The anonymity set collapses from N+1 to 1. The taker is fully deanonymized.
Existing protections and their limits
JoinMarket already has a protection against probing: PoDLE (Proof of Discrete Logarithm Equivalence). To initiate a CoinJoin, the taker must commit a real UTXO worth at least 20% of the requested amount. Each UTXO can only be used for up to 3 PoDLE commitments (to allow for honest failures). Makers broadcast used commitments to each other as a blacklist.
The problem: PoDLE works against casual abuse, but a well-resourced attacker can probe all makers simultaneously, before the blacklist propagates. Each maker is probed for their maximum offer amount, revealing as many UTXOs as possible. The attacker spends their PoDLE commitment UTXOs, but in return they get a complete snapshot of every maker's largest mixdepth. This is the attack scenario we simulate.
3. Baseline: How Bad Is It?
With no additional countermeasures beyond PoDLE, the CoinJoin protocol is highly vulnerable to probing. We simulate a network of 100 makers with realistic wallet structures sampled from the live JoinMarket orderbook.
Even at moderate attacker shares, a significant fraction of honest takers are fully deanonymized. At 20% attacker share (1 in 5 CoinJoin rounds is a probe), roughly 20% of takers lose all privacy. At 40%, it reaches 32%.
It gets worse over time. Because each identification reveals more UTXOs (the cascade effect), the attacker's database grows with every honest CoinJoin. Over 5,000 rounds, even a 10% attacker share produces 45% deanonymization, up from 4% in 1,000 rounds. This is the long-term steady-state risk.
4. Countermeasures
We evaluate six countermeasures. Each addresses a different aspect of the probing attack: limiting information leakage, breaking the identification chain, or raising the attacker's cost.
4.1 Max UTXOs per offer
What it does: Caps how many UTXOs a maker reveals when responding to a CoinJoin request. Instead of revealing all UTXOs in their largest mixdepth (which could be 5-10 or more), the maker only discloses the top N by value.
Why it helps: The attacker learns fewer UTXOs per probe. With a cap of 3, most of the maker's UTXOs remain unknown, making identification in future CoinJoins much less likely.
4.2 Flagged UTXO isolation
What it does: UTXOs that were disclosed during a failed CoinJoin negotiation (i.e., a probe) are marked as flagged. When a flagged UTXO appears as input in a later CoinJoin, it does not count as identification of the maker. The flag also propagates to change outputs derived from flagged UTXOs.
Why it helps: It breaks the identification chain at its root. Even if the attacker knows a UTXO belongs to a maker, that knowledge came from a probe, so it is tainted and cannot be used for identification. Only UTXOs learned through legitimate channels (e.g., the maker being identified via other means) count.
4.3 Sticky disclosed UTXOs
What it does: After a probe (failed CoinJoin), the maker remembers which UTXOs were disclosed. On subsequent probes, the maker re-offers the same UTXOs instead of revealing new ones. The sticky set clears when the UTXOs are actually spent in a completed CoinJoin.
Why it helps: Repeated probing of the same maker yields no new information. The attacker cannot learn more by probing the same maker multiple times.
4.4 Initiation fee
What it does: Each maker charges a fee (in sats) just to start the CoinJoin negotiation, paid regardless of whether the transaction completes. Both honest and malicious takers pay.
Why it helps: It makes probing expensive. At 500 sats per maker with 100 makers, each full probe round costs 50,000 sats. At 10 rounds per day, the attacker spends 0.005 BTC/day. However, this is purely an economic deterrent; it does not reduce information leakage.
4.5 Merge algorithm (gradual)
What it does: Controls how makers select inputs when participating in a CoinJoin. The gradual algorithm selects the minimum UTXOs needed to cover the amount, then adds one small UTXO for slow consolidation. The default algorithm uses greedy largest-first with no extras.
Why it helps: Fewer inputs per CoinJoin means less information revealed to any observer (including the attacker) if a maker is identified through other means.
4.6 Disclosed input policy (adaptive)
What it does: Makers track which of their UTXOs the attacker has seen (disclosed UTXOs). The adaptive policy dynamically decides whether to preferentially spend disclosed or clean UTXOs based on the current backlog ratio. When many UTXOs are disclosed, the maker more aggressively cycles them through CoinJoins to generate fresh outputs.
Why it helps: It accelerates the turnover of compromised UTXOs while preserving clean ones for normal use.
Individual effectiveness
The chart below shows each countermeasure's standalone impact against the probing attack, tested at 8 makers per CoinJoin over 1,000 rounds:
| Countermeasure | Effect on deanonymization | Mechanism |
|---|---|---|
| Max 3 UTXOs per offer | Eliminates deanonymization | Limits information per probe |
| Flagged UTXO isolation | Eliminates deanonymization | Blocks probe-derived identification |
| Sticky disclosed UTXOs | Near-zero (<0.5% at 80% evil) | Prevents repeat probing gains |
| Initiation fee (500 sats) | Does not reduce deanonymization | Economic cost only |
| Initiation fee (1000 sats) | Does not reduce deanonymization | Economic cost only |
Three countermeasures individually eliminate or nearly eliminate deanonymization: max UTXOs per offer, flagged UTXO isolation, and sticky disclosed UTXOs. The initiation fee is important as an economic deterrent but insufficient alone.
5. Recommended Policy
Rather than relying on any single countermeasure, we combine them into a defense-in-depth policy. The recommended configuration is:
| Parameter | Value | Purpose |
|---|---|---|
max_utxos_per_offer |
3 |
Limit information per probe |
sticky_disclosed_utxos |
true |
Block repeat probing gains |
flagged_utxo_isolation |
true |
Break identification chain from probes |
initiation_fee_sats |
500 |
Economic deterrent |
merge_algorithm |
gradual |
Minimize input exposure per CoinJoin |
disclosed_input_policy |
adaptive |
Cycle compromised UTXOs efficiently |
n_makers_per_coinjoin |
8 |
Larger anonymity set |
n_mixdepths |
5 |
Wallet compartmentalization |
Sustained attack resistance
We test the recommended policy under the harshest conditions: 5,000 rounds with a pre-probed attacker (every maker is probed before the first honest CoinJoin, simulating the simultaneous snapshot attack). The result is zero deanonymization across all attacker shares, from 10% to 60%.
The baseline reaches 79.2% deanonymization at 40% attacker share. The recommended policy stays at 0.0%.
6. Attack Economics
Even if an attacker is willing to spend Bitcoin on probing, the combination of initiation fees and information-limiting countermeasures makes the attack fruitless. The chart below shows how probe intensity affects both deanonymization and attacker cost over a 14-day attack window:
Against the baseline, even a single probe round per day achieves 70% deanonymization. Increasing to 50 probes/day pushes it to 97%, at a cost of 0.025 BTC/day. Against the recommended policy, the attacker achieves zero deanonymization regardless of spend.
Initiation fees alone are not enough. Even at 1,000 sats per maker, an attacker can still deanonymize ~56% of takers at 80% evil share. Fees raise the cost but do not address the fundamental information leakage. The real defense comes from limiting what the attacker learns.
7. Recovery After an Attack
What happens when the attacker stops? As honest CoinJoins continue, makers generate new UTXOs the attacker does not know about. The attacker's database becomes stale and identification rates drop.
After a 14-day attack with 20 probes/day, the baseline takes until approximately day 20 to recover below 5% deanonymization. The recommended policy was never affected: deanonymization stayed at 0% throughout the attack.
8. Key Takeaways
- CoinJoin probing is a real privacy threat. Without countermeasures, a moderately resourced attacker can deanonymize the majority of honest takers through the information cascade from probing.
- Three countermeasures are individually effective: capping UTXOs per offer, isolating flagged UTXOs, and sticky disclosure each eliminate deanonymization on their own. They work by limiting or poisoning the information the attacker collects.
- Initiation fees are necessary but not sufficient. They raise the attacker's cost but do not stop the information leakage that enables deanonymization. Fees complement information-limiting measures.
- The recommended policy combines all layers. It achieves zero deanonymization even under sustained, pre-probed, high-intensity attacks. The defense is robust across all tested scenarios.
- Recovery is slow without mitigations. After a 2-week attack ends, the baseline needs ~12 more days to recover. With the recommended policy, there is nothing to recover from.