Evaluating usage of the Whirlpool Bitcoin privacy protocol
The privacy problem in Bitcoin
One downside of using a cryptocurrency like Bitcoin is that all transactions are publicly visible -- anyone in the world can see amounts, spending and receiving addresses, and the transaction graph of all Bitcoin transactions. Though addresses need not contain personally identifying information, a blockchain observer might have access to off-chain information that lets them identify which addresses belong to which users. Users can generate new addresses for every payment, but many don’t, and this doesn’t obscure how funds are further spent.
It is a common misconception that this level of transparency is only an issue for criminals who want to hide how they are moving their money. This is not true. To illustrate why this is a problem even for regular consumers, imagine that a user gets paid by their employer on-chain in bitcoin. The employer can directly observe how the user further spends that money on-chain, and might be able to see, for example, if a user pays to a well-known charity address (donation addresses are typically reused) or to a medical professional. By default, using vanilla Bitcoin can leak sensitive personal information about a user to their employer that we would normally expect to be private.
CoinJoin protocols
In order to mitigate this, users can engage in protocols to mix their coins together with other users, breaking the link between transactions and making it harder to tell how a user receives or spends their coins. There are a wide variety of these protocols, but we focus on a non-custodial variant known as CoinJoin. Some examples of CoinJoin applications are JoinMarket, a command line and desktop tool; and Wasabi and Samourai wallets. Wasabi and Samourai saw greater adoption than JoinMarket.
CoinJoins rely on the fact that signatures for different inputs in a transaction are independent -- multiple users can come together to sign a transaction spending different inputs. In JoinMarket users perform this function together, whereas in Wasabi and Samourai they rely on a centralized coordinator. It’s important to note the coordinator never takes custody of the users’ coins, it merely facilitates transaction creation.
We were interested in learning more about how users engage in CoinJoin transactions by examining their on-chain trace. We decided to focus on Whirlpool transactions, used in Samourai, first since they use a very clear on-chain pattern.
Whirlpool transactions
Whirlpool transactions involve 5 inputs and 5 outputs. All outputs are identical in denomination (e.g. 0.05 BTC), while input denominations vary slightly from that value to account for mining fees (e.g. both 0.05 BTC and 0.051 BTC inputs in the same transaction). Each denomination is one of the following 4 pools (hence the name Whirlpool): 0.001 BTC, 0.01 BTC, 0.05 BTC, or 0.5 BTC. The 0.001 BTC pool was introduced in 2021; in this work we focus on the three other pools in operation since 2019 (in September 2024 Samourai wallet was forked into a new wallet called Ashigaru; we don't distinguish between the two). Our analysis covered blocks 572341 (April 19, 2019) to 892876 (April 17, 2025).
The five inputs must originate from a combination of re-mix inputs, which are the outputs of previous coinjoin transactions, and pre-mix inputs that come from tx0s, which are transactions that break down other inputs into the aforementioned equal-denomination chunks (see the illustration below). Each transaction must include at least one re-mix input. Due to the unique, unmistakable form of these Whirlpool transactions, we can reliably detect and study these Coinjoin transactions. The most popular wallets that have implemented these coinjoin transactions are Samourai and Sparrow.
(As an aside, Samourai Wallet was shut down in early 2024 due to charges of money laundering and other illegal activity. The shutdown serves as a reminder that like many tools, privacy practices like CoinJoin can be used by criminals for nefarious purposes. However, it is important to study and evaluate the potential effectiveness of such techniques in protecting the average Bitcoin user’s privacy and wellbeing.)
Prior research on Coinjoins
A steady stream of research works have investigated the effectiveness of different privacy techniques in Bitcoin, and have identified effective techniques for deanonymizing individual transactions. Even simple heuristics like the "common input ownership heuristic" (all inputs in a transaction are under control of a single party; this is generally true for consumer wallets) can be surprisingly effective. Analysts, including commercial firms like Chainalysis or Elliptic, can use specialized software, various heuristics, and external databases (e.g., known address-identity relationships from open-source intelligence, court disclosures, data leaks, or proprietary data sharing) to iteratively draw inferences about a real-world user behind a particular blockchain transaction.
To improve Bitcoin privacy a number of protocols try to limit the sources of information available to analysis, or to make heuristics unreliable. For example, Silent Payments lets a user publish a static address that will result in a random ephemeral address being recorded on the blockchain. While the intended recipient can detect and use these funds, the address appears completely random to an external observer, thus helping with the address reuse problem. Similarly, protocols like PayJoin and CoinJoin break the common input ownership heuristic. PayJoin constructs a collaborative transaction between the sender and recipient, e.g., customer and merchant, so that some of the recipients funds are used as inputs to the transaction - that way one can't assume that both inputs are controlled by a single party, nor can one reliably detect which output was a change output and which was the actual payment. While PayJoin necessarily requires recipient adoption, CoinJoin, as explained above, lets a user get fresh post-mix coins that can later be used with any recipient.
The privacy of CoinJoin systems has been extensively analyzed in the literature. Maksutov et al 2019, Schnoering and Vazirgiannis 2023, and Stutz et al 2023 worked on the detection of various CoinJoin transactions (not limited to Samourai Whirlpool). Wahrstätter et al 2019 and Deuber and Schroeder 2021 used clustering and entity analysis to analyze how user error (e.g., using pre-mix coins together with post-mix coins in a single transaction) can lead to the reuse or clustering of addresses as belonging to one entity, reducing anonymity. Goldfeder et al 2017 investigates how third party web-trackers can link distinct user’s on-chain transactions, and extend these attacks to cluster intersection attacks on CoinJoins. Cluster intersection attacks affect both the pre-mix change outputs (so called “toxic change”, which can’t be used together with post-mix outputs) as well as post-mix outputs (that also can’t be used together in subsequent transactions, lest it links these CoinJoins together). We refer reader to Yuval Kogman’s Spiral blog post series, especially Part 4, for detailed description.
Further, Ghesmati, Fdhila and Weippl 2022 performed usability studies on Coinjoin software, analyzing whether complicated usage for these programs constituted a barrier to entry for the average Bitcoin user to improve their privacy. Finally, Moeser and Boehme 2016 studied the feasibility of "flooding attacks," a type of attack where one entity could sybil attack the Coinjoin market with its own addresses, therefore stripping the remaining minority of other users of privacy.
Research questions
Our lab was also interested in several research questions:
How much would it cost to render a CoinJoin less effective/ineffective by contributing pre-mix UTXOs to a given CoinJoin transaction in 2020s? (similar to Moeser and Boehme research, but for a new decade)
Do people in a certain area of the world favor privacy practices like CoinJoin more than people in other parts of the world? (time-of-use analysis)
What is the average number of times a CoinJoin output is remixed?
And most importantly:
Do people forgo privacy practices when feerates are high?
Whirlpool CoinJoins require multiple on-chain transactions (i.e., pre-mix, CoinJoin itself, and post-mix transactions), which means they also incur more fees. We were curious as to whether high-feerate periods would correspond to periods of low Coinjoin usage and vice versa. For the purposes of this project, we focused on Whirlpool transactions for their aforementioned detectability.
Data analysis pipeline
In order to answer this question, we needed to gather historical data on both Whirlpool transactions and feerates. Both types of data had to include a time element so that joint analysis could be performed on them. We had the option of using Bitcoin Core JSON-RPC API or commercial APIs like Iknaio; however, these APIs were not meant for bulk requests or chain scanning. Our work would incur over 100,000 requests, which would be slow and inefficient.
The pipeline that we used instead is shown below:
To access chain data, we initially tried to use py-bitcoinkernel, which is a Python wrapper for libbitcoinkernel. However, py-bitcoinkernel was new and experimental, meaning it did not have full functionality to provide us with all the needed data. Instead, we used the Bitcoin Core kernel, where we received assistance (thanks to Cory Fields) in retrieving the needed information. The chain data collected was very large (around 650 GB), so we converted it into a (still very large) text file containing only the needed information:
Block height
Feerates for each transaction within block
Number of detected tx0s up to that block height
Timestamp of block
Denomination information for the detected tx0s
Our CoinJoin detection code works as follows. Our starting point is seven Whirlpool genesis CoinJoin transactions which we obtained from authors of AFT'22 paper analyzing CoinJoins. To detect all Whirlpool CoinJoins we sequentially process subsequent Bitcoin transactions and iteratively identify transactions matching the Whirlpool pattern. Specifically, when processing a transaction, our isWhirlPool detection checks whether a transaction simultaneously (a) has five inputs and outputs, (b) has outputs of the same value (either 0.01 BTC, 0.05 BTC, and 0.5 BTC, the pools we analyzed), and (c) has at least one input from a previously identified Whirlpool CoinJoin transaction. If so, we deem this transaction to be a Whirlpool CoinJoin transaction, and deem all of its inputs that do not originate from previously identified Whirlpool CoinJoin transactions as coming from tx0 transactions.
This process finds both Whirlpool CoinJoins and the associated tx0 transactions [1]. As tx0’s serve a proxy for Whirlpool users (a CoinJoin can have a varying number of remix inputs from previous CoinJoins), our data analyses focuses on tx0’s as the main usage metric.
Given this text file, we passed it into Python, where it was processed and pickled to create a smaller, easily readable file that could be used for easier data analysis. Then, also in Python, we wrote code to calculate and plot various metrics of feerate, tx0s, time, etc. We also grouped the data into epochs of either a constant number of blocks or a certain period of time. These epochs allowed the data to be less fine-grained and more readable for analysis.
Results
Here are some of the results.
First, time-of-use analysis seems to be inconclusive: CoinJoin usage is relatively uniform along the day, and while there is a bump in afternoons in U.S. east coast time, the relative increase is rather minor:
Thus we went on to investigate how other environmental factors, like feerates, impact CoinJoin use.
Above is a time-series plot with the horizontal axis denoting epochs (here each epoch is 10 days for ease of reading). The red line represents the average median feerate in each epoch (axis on the left), and the blue line represents the number of tx0s that were created in each epoch (axis on the right). You can see that, somewhat as we expect, there is an increase in tx0s when the feerate is low and a corresponding decrease when the feerate is high. (Fascinatingly enough, there is also an abrupt drop in tx0s at roughly 180 epochs. According to timestamps, our first datapoint is from April 19, 2019, so 1,800 days after is around March or April 2024, which aligns with when Samourai servers were being shut down.)
Above are three more graphs very similar to the previous one; each graph displays data for exactly one denomination of tx0s. You can see that they share similar patterns overall, including the steep drop around the time of shutdown. In addition, you can see from the scale of the axes that the smaller denomination transactions are much more popular than the larger ones.
Here is one last graph, which plots the average median feerate per epoch (horizontal axis) against the percent of transactions that are Coinjoin transactions. Notably, the feerate is denoted in USD rather than BTC as in the previous few graphs. Plotting feerates in BTC against the number of Coinjoin transactions results in an ambiguous graph with few conclusions, but making changes from BTC to USD and from number of transactions to percent of transactions reveals a negative correlation: there is a substantial decrease in Coinjoin activity when feerates are high.
Specifically, this graph corresponds to an econometric model (suggested by Dan Aronoff), where `usage = c0 + median_feerate_in_USD * c1` (we use a fraction of tx0 transactions as a proxy for usage). This suggests that users are price sensitive in USD terms (c1 < 0 in the entire 95% confidence interval), but not so in BTC terms. However, as the confidence interval is rather wide, we conclude that fee sensitivity is not the primary driving factor for coinjoin usage in low feerate regime. However, the sensitivity is definitely noticeable (even by visual inspection) in a high feerate regime.
Conclusion
While the work done so far has given our theory some initial confirmation, further work needs to be done to rigorize the findings. In addition, we plan to explore how wallet fingerprinting affects privacy practices; Ishaana already has a helpful blog post about her work in this area.
[1] Due to an oversight our iterative analysis starts on block 572341 and misses a single CoinJoin after the a554db... genesis transaction in block 572030. As outputs of this CoinJoin transaction do not get remixed in Whirlpool this omission does not impact our CoinJoin detection or subsequent analysis.
Authors: Alicia Lin, Ishaana Misra, Madars Virza, Neha Narula
Thanks to Yuval Kogman and Sebastian Kung for feedback on this post.