On June 15th we received an encrypted message sent to Samourai Wallet lead developer TDevD. The author of the message states that they have found 5,113 reused addresses in post-mix Whirlpool spend transactions as of May 22 2020.
Alright man, I don’t know how else to put it, I’ll be blunt. I’ve found 5113 reused addresses in post-Whirlpool spends on the blockchain as of May 22nd. Someone approached me concerned because they noticed after checking one of their transactions on a block explorer that one of the addresses in a Stonewall output had been reused multiple times. This, along with just regular address reuse, is a consistent pattern with these addresses involving thousands of transactions.
The author included a sample of 200 transactions and provided a timeline of when they would take their findings public.
In our immediate review of the supplied sample list of transactions we found numerous transactions that did not suffer address reuse at all, and a good portion of the list was deemed inaccurate. We did however note some true positives in the list and they all pre-dated the May 2020 time frame.
While we did not arrive at the same conclusion as the author regarding the severity of the situation based on the provided sample, we had two issues to deal with:
First, the provided data set — 200 transactions is a small sample to begin with, and with half of the sample wrong we needed to get a better view of the landscape before we could make a serious judgement on the severity.
Second, while the list was inaccurate overall, it did contain some actual instances of address reuse that could not be denied, the possibility of widespread and systemic address reuse is a serious issue that requires serious in-depth analysis, and if any issues exist then quick and actionable resolution is required.
We immediately paused new development on our range of products — Samourai Wallet, Sentinel, Whirlpool, and Dojo — and focused our already strained resources on investigating this issue.
To be clear, this analysis is focused on post-mix transactions that spend Whirlpool mixed outputs (known as post-mix spending). Address reuse is absolutely rejected by the Whirlpool coordinator to protect privacy gained during mixing.
We have analyzed this newly provided list and can confirm there are 4,486 false positives, meaning addresses that do not suffer Address Reuse.
This confirms our original findings that the original disclosure was working with false data and thus was led to a false conclusion. However, 441 addresses do contain address reuse which we cover in the rest of this report. We have provided the list analyzed here
First, we spent considerable time attempting to replicate the reported address reuse issue but were unable to do so using the most recent versions of the wallet. We then looked through Github issues to see if we could find any user reports of this issue.
We found one Github issue from January 2020 but the issue was marked as resolved in April 2020.
Because we were unable to replicate the results ourselves, there were no outstanding user reports of this issue, nor could we validate the supplied sample we decided the only way to continue was to analyze every single post-mix spend we could find on the blockchain since the launch of Whirlpool in May 2019.
Post-mix transaction analysis
We analyzed a total of 12,736 post-mix transactions on the blockchain. Of that total we can further categorize the type of post-mix transaction.
Coinjoin Like post-mix: 3,334 (26.25%)
These transactions resemble CoinJoin transactions in structure and are likely to be STONEWALL or STONEWALLx2 transactions.
Payment Like post-mix: 2,423 (19.02%)
These transactions resemble normal payment transactions in structure and are likely to be simple spends or Stowaway transactions.
Sweep post-mix: 6,804 (53.42%)
These transactions resemble sweep transactions. All the input UTXOs are spent in their entirety and there is no resulting change output back to the wallet.
Other post-mix: 166 (1.3%)
These transactions cannot easily be classified.
Of these 12,736 total post-mix transactions analyzed we found 1,904 transactions with a reused address in the output of the transaction.
While this supported our original speculation that the issue wasn’t as serious or widespread as the disclosure described, any unintentional address reuse must be responded to immediately and eliminated where possible, so further research is required to determine what kind of address reuse we are dealing with.
Of the 1,904 transactions with identified address reuse, let us classify them by their transaction types described above.
- CoinJoin Like post-mix: 817 (6.41%)
- Payment Like post-mix: 494 (3.88%)
- Sweep post-mix: 544 (4.27%)
- Other post-mix: 49 (0.38%)
We classify address reuse into two broad categories. The first is Unintentional Address Reuse — This is when the wallet reuses addresses without the user invoking such behavior, the user is usually entirely unaware of the reuse. The second is Intentional Address Reuse — This is when the user purposefully reuses addresses, in some cases bypassing built in safeguards to do so.
With these two broad categories in mind, we are concerned primarily with Unintentional Address Reuse, so we can disregard the 544 occurrences of address reuse within the Sweep post-mix category, as the user is either initiating a full wallet spend (and thus providing the address) or using an external wallet software. This category would be classified as Intentional Address Reuse since the user is invoking the transaction.
To gain further insight at the scope of this problem let us examine the 24,894 total addresses found within the 12,736 post-mix transactions analyzed
Of these addresses we find that 93.9% are not reused leaving a total of 1,518 reused addresses.
Using the publicly available OXT Analysis Platform we have used blockchain data to attempt to cluster and apply generally accepted heuristics to further break down these addresses into additional categories.
Addresses likely generated by the wallet: 391 (1.57%)
These reused addresses were likely automatically derived by the wallet and could indicate Unintentional Address Reuse
Addresses likely external to the wallet: 1,016 (4.08%)
These reused addresses were likely specifically sent to by the user and are not associated with their own wallet.
Addresses associated to an unidentified wallet: 111 (0.45%)
These reused addresses could not be reliably determined to be internal or external.
Of the 1,518 reused addresses 1,127 are likely external addresses not derived by the wallet — instead provided by the user. These instances can be further categorized into the broad category of Intentional Address Reuse.
This leaves 391 addresses that have been likely derived by the wallet indicating potential Unintended Address Reuse that warrants further investigation.
Post-mix transaction output analysis
Looking deeper at each of the 12,736 total post-mix transactions we further explored each individual output of those transactions looking for address reuse.
Of the 26,437 total outputs analyzed we found 2,791 outputs containing a reused address.
Again, we are looking for cases of Unintentional Address Reuse so we have to further dive into the 2,791 reused outputs and categorize them.
Using the same OXT Analysis Platform and heuristics we used to classify addresses we did the same with each output.
- Outputs with likely wallet address: 1,028 (3.89%)
- Outputs with likely external address: 1,588 (6.01%)
- Outputs with unidentified wallet address: 175 (0.66%)
We again see the broad amount of offending outputs aren’t derived by the wallet, so must be provided by the end user, which would again indicate cases of Intentional Address Reuse.
This still warrants further research into the type of transactions these 2,791 outputs can be categorized into even if only 1,028 of those outputs were associated with a wallet address. Any case of Unintentional Address Reuse needs to be examined.
We will use the previously described transaction types to further categorize these 2,791 outputs.
CoinJoin Like post-mix using a mixed input with plausible external address: 372 outputs (1.41%)
These are STONEWALL or STONEWALLx2 transactions using a mixed UTXO as an input of the transaction and the reused output is likely external of the wallet, so this would classified as Intentional Address Reuse, i.e.: the user is sending to an address that has been reused before.
CoinJoin Like post-mix using a mixed input with plausible internal address: 164 outputs (0.62%)
These are STONEWALL or STONEWALLx2 transactions using a mixed UTXO as an input of the transaction and the reused output is likely derived by the wallet, so this would classified as Unintentional Address Reuse, i.e.: the wallet deriving addresses that have been used before.
CoinJoin Like post-mix using a mixed input with unidentified address: 288 outputs (1.09%)
These are STONEWALL or STONEWALLx2 transactions using a mixed UTXO as an input of the transaction and the reused address cannot be identified by our algorithms.
CoinJoin Like post-mix with a reused change output: 699 outputs (1.09%)
These are STONEWALL or STONEWALLx2 transactions using a change UTXO as an input of the transaction and a change output was reused. This can clearly be defined as Unintentional Address Reuse.
Sweep post-mix: 544 outputs (2.06%)
These are transactions that spend the entirety of the input UTXO(s). This type of transaction indicates Intentional Address Reuse because the user must initiate the sweep and provide the destination address.
Payment Like payee output: 371 outputs (1.4 %)
These are transactions that appear as standard payments to a third party (but could also be a Stowaway transaction) where the payee output is reused. This is a clear indication of Intentional Address Reuse.
Payment Like change output: 117 outputs (0.44 %)
These are transactions that appear as standard payments to a third party (but could also be a Stowaway transaction) where the change output is reused. This is a clear indication of Unintentional Address Reuse.
Payment Like unidentified output: 22 outputs (0.08 %)
These are transactions that appear as standard payments to a third party (but could also be a Stowaway transaction) where the output that is reused cannot be determined to be payer/payee.
Other post-mix: 214 outputs (0.81%)
As with all our other findings we find a small minority of Unintentional Address Reuse and a larger share of Intentional Address Reuse.
We now have a clear picture of the extent of address reuse throughout the entire Whirlpool post-mix transaction landscape.
Overall address reuse within post-mix spending transactions is low. With only a total of 1,904 out of 12,736 transactions containing a reused address. Thankfully this is nowhere near the alleged 5,000+ transactions described in the original disclosure but as we have stated many times before, no address reuse is acceptable.
Looking closer at the 24,894 total addresses we find a total of 1,518 reused addresses. At least 1,016 of these addresses classified as external to the wallet, meaning the user would have had to proactively engage in the act of address reuse and in some cases bypass the built in controls in the wallet designed to prevent against this behavior. We can discard these occurrences for now as user invoked.
We still however must account for the sparse number of Unintentional Address Reuse — address reuse occurring due to no fault of the user — occurrences that we have uncovered thanks to the investigation that this disclosure prompted.
Of primary interest are 699 post-mix STONEWALL or STONEWALLx2 transaction outputs, the 117 payment or Stowaway transaction outputs, and the 164 post-mix STONEWALL or STONEWALLx2 using a mixed input that appear to contain reused addresses as change outputs. These are the most clear case of Unintentional Address Reuse due to no fault or action of the user.
Tackling and eliminating these occurrences must be and has been our focus for the last month. We will continue to monitor reuse levels and integrate these metrics into our ongoing efforts to create a healthy post-mix spending environment.
In no way are we discounting the other occurrences of Address Reuse, such as those occurrences that were invoked directly by the user, however in the context of searching for a systemic issue of address reuse we must look on these occurrences with less weight to focus on occurrences that are outside of a users control.
The number of transactions that are impacted by Unintentional Address Reuse appears to be very limited and contained based on our in depth and widespread investigation. However, any address reuse is not desirable and an effort has been made to eliminate all forms of Address Reuse where ever we can.
We already lead the pack on trying to discourage users from sending to addresses they have already transacted with by building Address Reuse Alerts into the wallet.
We are pushing this proactive approach forward with the introduction of a Strict Mode transaction policy that by default will refuse to broadcast transactions that contain Unintentional Address Reuse.
Strict Mode PushTx
Strict Mode acts as a blanket shield at the node level and should help eradicate Unintentional Address Reuse. This will work side by side with the existing Address Reuse Alerts to help tackle Intentional Address Reuse with education and gentle warnings.
Strict Mode is a back-end change that most users do not have to concern themselves with. All users running the most recent version of Samourai Wallet available in the Google Play Store and on our website are running with Strict Mode enabled by default.
Yesterday we released Dojo 1.7 to the public. This update includes the previously described Strict Mode. This new endpoint addition allows the Dojo to prevent transactions that violate the address reuse policy from being broadcast to the network.
In our exploration and ongoing audit we determined that Ricochet served as a potential area for Unintentional Address Reuse, though we have not yet seen evidence of this occurring in the wild yet, we wanted to nip any potential issues in the bud.
As of the latest version of Samourai Wallet the back-end server or your own hosted Dojo will keep track of the consumed indexes of Ricochet addresses in your wallet. Previously, only your wallet was keeping track of this information which would be lost in the case of a mnemonic restore.
In addition to Ricochet indexes being reset in the case of mnemonic restore, the same is true of PayNym channel address indexes. In some cases Unintentional Address Reuse can occur after a mnemonic restore. Unfortunately we cannot yet automate the syncing process but users can manually re-sync their PayNym channels after a mnemonic restore in the mean time. We look forward to automating this in the near future.
Open Access Data
The data snapshot we used to perform this analysis can be found here. Additionally, the python script and corresponding output can be found here. We encourage anyone to conduct their own investigation and contribute their findings.
While the results of the original disclosure and accompanying data has been proven to be misguided, the resulting investigation and changes being made are only a positive for users. The introduction of the Strict Mode pushTx policy should help put a significant dent in any cases of Unintentional Address Reuse, edge-case or not.