Skip to main content

How Wallet Fingerprints Damage Payjoin Privacy

· 10 min read

When a wallet constructs a transaction, it makes dozens of small decisions: input ordering, coin selection, fee estimation, signature encoding. These choices vary systematically across implementations and can be used to identify wallets on-chain. These patterns are called wallet fingerprints.

Some fingerprints are deterministic. For example, Bitcoin Core grinds all ECDSA signatures to a low-r value, so a single 72-byte signature immediately eliminates Core as the signer. Others are probabilistic: fee rates follow characteristic distributions per wallet. Bugs become fingerprints too. Each dimension contributes independent evidence, and the evidence compounds. For a comprehensive study of wallet fingerprints, see prior work by Ishaana Misra.

Fingerprints sharpen clustering, the process of grouping related outputs using behavioral heuristics. For background, see Yuval Kogman's blog post on the history of wallet clustering. Recent work in clustering uses wallet fingerprints to bolster existing heuristics such as change identification showing meaningful improvements over naive heuristics. Kappos et al. showed that combining wallet fingerprints from adjacent transactions with value analysis improves clustering accuracy, validating the approach on ground truth data. This directly threatens Payjoin's privacy model, which relies on making the sender's and receiver's inputs indistinguishable. Fingerprints that partition the inputs restore the clustering Payjoin was designed to break.

This post applies that lens to real Payjoin transactions.

Two Levels of Linkage

Payjoin transactions should appear indistinguishable from standard single-party transactions. Analysts applying conventional heuristics would misclassify the transaction, wrongly clustering the sender's and receiver's inputs together. So a Payjoin-aware analyst's first step is detecting artifacts of collaborative transactions.

Simin Ghesmati et al. show how oddities in coin selection, specifically unnecessary inputs, can be used not only to detect Payjoin transactions but also to partition inputs and outputs by owner. Wallet fingerprints offer another signal for the same task.

If sender and receiver use different wallet software, their fingerprints may reveal which inputs and outputs belong to whom. Once you've inferred the ownership partition, standard Common Input Ownership Heuristic (CIOH) clustering applies within each owner's inputs. The Payjoin becomes analytically equivalent to a pair of regular transactions.

Wallet fingerprint signals operate at two levels:

  • Intra-transaction signals help partition inputs and outputs by owner within a single transaction. Which outputs are change (returned to sender) and which are transfers (sent to receiver)? Correct change identification is critical because it connects the sender's current transaction to their next one. Fingerprints may reveal this directly: change outputs may inherit distinctive traits from the sender's software.
  • Inter-transaction signals operate across the transaction graph:
    • Backward: Each input was created by some prior transaction that may carry its own fingerprint.
    • Forward: Each output may eventually be spent in a future transaction, revealing fingerprints.

The goal of chain analysis against a Payjoin is therefore:

  1. Detect artifacts of collaboration.
  2. Recover the sender/receiver partition using intra- and inter-transaction signals.
  3. Apply standard heuristics within each partition.

Example 1: Samourai Payjoin

Transaction: 8dba6657...

Inspecting the transaction at the field level reveals nothing immediately suspicious. Both inputs share the same nSequence, the same P2WPKH scriptpubkey type, and superficially similar witness stacks. The signal emerges from the signature bytes directly.

Input 0's DER-encoded signature is 71 bytes. The r-value is 32 bytes with no leading zero pad, meaning r < 2^255. This is a grinded, low-R signature. Input 1's signature is 72 bytes (the r-value requires a leading 0x00 pad, meaning r ≥ 2^255). This is an ungrinded, high-R signature. A single wallet running a consistent signing policy would either grind all signatures or grind none. Observing one of each is a strong signal that two different signing implementations contributed inputs.

This signature asymmetry partitions the inputs: Party A owns the low-R input, Party B owns the high-R input. With input values of 50,000 and 3,999,216 sats, we can test both output assignments and see which one is more likely:

Assignment 1: Output 0 (9,752 sat) = Party A's output, Output 1 (4,039,216 sat) = Party B's output

  • Party A: 50,000 in → 9,752 out, net outflow = 40,248
  • Party B: 3,999,216 in → 4,039,216 out, net inflow = 40,000
  • A pays B ≈ 40,000 sat (+ 248 fee)

Assignment 2: Output 0 (9,752 sat) = Party B's output, Output 1 (4,039,216 sat) = Party A's output

  • Party A: 50,000 in → 4,039,216 out, net inflow = ~4M
  • Party B: 3,999,216 in → 9,752 out, net outflow = 3,989,464

Assignment 1 implies a payment of exactly 40,000 sat while Assignment 2 implies 3,989,216 sat. The round-number heuristic favors Assignment 1. The spending transactions reinforce it: output 0 is spent with a low-r signature (matching Party A's input), output 1 with a high-r signature (matching Party B's input).

The Payjoin is decomposed: an input/output ownership partition is inferred and the payment amount recovered.

Example 2: PDK Demo Payjoin

Transaction: 3c5436f1...

Both inputs are P2TR key path spends. Under Taproot spending rules applying to P2TR, the default sighash is SIGHASH_ALL and the sighash byte may be omitted. Omitting it is the canonical form. Both options are consensus-valid. Input 0's witness is 64 bytes. The sighash byte is omitted. Input 1's witness is 65 bytes. An explicit 0x01 SIGHASH_ALL byte is appended. Including an explicit SIGHASH_ALL byte is typically a bug rather than an intentional policy.

Two inputs from the same wallet would apply a consistent sighash policy. The inconsistency partitions the inputs: Party A owns the input with the omitted sighash byte, Party B owns the input with the explicit sighash byte.

Unlike Example 1, the value assignment does not uniquely resolve the output partition. Both assignments are arithmetically consistent:

Assignment 1: Output 0 (59,014 sat) = Party A's output, Output 1 (864,506 sat) = Party B's output

  • Party A: 51,514 in → 59,014 out, net inflow = 7,500
  • Party B: 872,224 in → 864,506 out, net outflow = 7,718
  • B pays A ≈ 7,500 sat (+ 218 fee)

Assignment 2: Output 0 (59,014 sat) = Party B's output, Output 1 (864,506 sat) = Party A's output

  • Party A: 51,514 in → 864,506 out, net inflow = 812,992
  • Party B: 872,224 in → 59,014 out, net outflow = 813,210
  • B pays A ≈ 812,992 sat (+ 218 fee)

The round-number prior favors assignment 1, but it is not decisive. We can say with high confidence that the multi-party construction is detectable due to the wallet fingerprint signals; however, the ownership partition is not uniquely determined. The sighash inconsistency is a residual leak, but genuine ambiguity remains.

However, inspecting the spending transaction of the second output reveals the explicit SIGHASH_ALL byte again, matching the second input. This strongly suggests the second output belongs to the same wallet as the second input, making Assignment 1 more likely.

Example 3: Cake Wallet → Bull Bitcoin Mobile Payjoin

Transaction: 8fb80573...

The first thing that sticks out is that both inputs carry nSequence = 0x01. Cake Wallet sets a relative timelock via BIP-68 and Bull Bitcoin Mobile matches the nSequence value, so no intra-transaction asymmetry exists between the two inputs. The signing is also homogeneous: both inputs produce low-r signatures with the same SIGHASH flag. At the transaction level, the fingerprint analysis stalls.

The value assignment, however, does provide for a likely partitioning. Two possible assignments follow:

Assignment 1: Output 0 (29,358 sat) = Party B's output, Output 1 (429,919 sat) = Party A's output

  • Party A: 440,337 in → 429,919 out, net outflow = 10,418
  • Party B: 19,358 in → 29,358 out, net inflow = 10,000
  • A pays B ≈ 10,000 sat (+ 418 fee)

Assignment 2: Output 0 (29,358 sat) = Party A's output, Output 1 (429,919 sat) = Party B's output

  • Party A: 440,337 in → 29,358 out, net outflow = 410,979
  • Party B: 19,358 in → 429,919 out, net inflow = 410,561
  • A pays B ≈ 410,561 sat (+ 418 fee)

The round-number hypothesis overwhelmingly favors Assignment 1. Furthermore, the receiver's input (19,358 sat) is smaller than the sender's change (429,919 sat), consistent with UIH2: the sender had no UTXO small enough to contribute without creating large change, while the receiver's UTXO perfectly covers the payment increment. A likely partition is: output 0 (29,358) is the payment, input 1 (19,358) is the receiver's UTXO, and output 1 (429,919) is the sender's change.

The inter-transaction analysis then supports the input partitioning analysis. The prior transaction for input 0 has one input carrying nSequence = 0x01 and the other carrying 0xfffffffd. This asymmetry partitions that transaction's inputs and identifies the 440,337 sat output as belonging to the party using nSequence = 0x01, which flows directly into the Payjoin as input 0.

The prior transaction for input 1 uses only 0xfffffffd across all inputs. Additionally, the transaction spending output 1 also sets nsequence to 0xfffffffd. This is consistent with Bull Bitcoin Mobile's standard behavior, providing strong evidence that output 1 and input 1 belong to the same wallet.

┌──────────────────────────┐
│ PRIOR TX (9ecd77...) │
│ │
│ in_0 [seq=1] │
│ in_1 [seq=MAX-2] │
│ ──────────────────────── │
│ out_0: 204,326 │
│ out_1: 440,337 ──────────────────┐
└──────────────────────────┘ │
│ ┌──────────────────────────┐
│ │ PAYJOIN TX (8fb805...) │
│ │ ──────────────────────── │
└──►│ in_0 [seq=1] │
┌──►│ in_1 [seq=1] │
┌──────────────────────────┐ │ │ ──────────────────────── │
│ PRIOR TX (3fbe17...) │ │ │ out_0: 29,358 │
│ │ │ │ out_1: 429,919 ──────────────────┐
│ in_0 [seq=MAX-2] │ │ └──────────────────────────┘ │
│ in_1 [seq=MAX-2] │ │ │
│ ──────────────────────── │ │ │
│ out_0: 430,856 │ │ ┌──────────────────────────┐ │
│ out_1: 19,358 ──────────────────┘ │ SUBSEQUENT TX (9232d5...)│ │
└──────────────────────────┘ │ ──────────────────────── │ │
│ in_0 [seq=MAX-2] ◄───────────────┘
│ ... │
└──────────────────────────┘

Both fingerprints persist across the transaction graph. Cake's 0x01 traces back to the prior transaction, Bull Bitcoin's 0xfffffffd traces both backward and forward. What appeared ambiguous from the Payjoin alone becomes much clearer once adjacent transactions are inspected.

Conclusions

These observations teach us that Payjoin's privacy preservation extends only as far as the homogeneity of the participating wallets' fingerprints. Fingerprint homogeneity at the transaction level is necessary but not sufficient. Any dimension on which the sender and receiver diverge becomes a partition signal. The analyst's job reduces to finding those divergences in wallet behaviors, and the transaction graph provides arbitrarily many observations to find them in.

While some of these wallet fingerprints are relatively trivial to eliminate, others are intrinsic to a particular wallet's design choices and goals and can't just be "fixed". Wallet developers should be aware of these potential privacy leaks when integrating Payjoin into their wallets.

The analysis in this post focuses on individual Payjoin transactions, but the approach generalizes. Wallet fingerprint distributions can serve as features for clusters. A cluster with consistent fingerprints is more credible than one with incompatible wallet traits. This points toward a broader class of attacks on Payjoin privacy. Future work would entail an automated, large-scale analysis that scores cluster plausibility using fingerprint distributions. We're currently building tooling for this as part of our privacy metrics framework.

Reviving Our Email List Back From the Dead

· One min read

A couple years back, our team had an email list that gave regular updates on Payjoin's progress from Chaincase/Payjoin Substack. If you are receiving this as an email, it's because you were a subscriber on one of those lists.

We're the same team who has pivoted to the Payjoin solution to solve the same problem. Since then, we've worked hard to deploy Payjoin Dev Kit, the Payjoin Foundation 501(c)(3), and a team of executors moving fast to bring you the next generation of this technology. If you've been out of the loop, you can try it out in Cake Wallet or Bull Bitcoin Mobile.

Stay tuned for email updates on Payjoin's progress, and always feel free to send us feedback, by this email, our Discord or on Github.

Onward!

Payjoin Foundation Granted 501(c)(3) Status

· 3 min read

Payjoin Foundation has received approval from the Internal Revenue Service recognizing the Foundation as tax-exempt under Section 501(c)(3) of the Internal Revenue Code effective July 23, 2025. We announce it now because we have just received the determination letter from the IRS. We can now accept tax-deductible charitable contributions to support our mission to advance practical privacy in peer-to-peer digital transactions. We're finalizing our online donation flow; if you'd like to contribute now, please see our donate page.

Having an organized foundation with a dedicated budget enables us to recruit talent to solve specific problems rather than recommend an external org make a grant to each individual contributor whose talents may serve the mission more effectively on deep technical work than making it legible to an organization without a technical mission.

I'll highlight @chavic's work on Dart bindings as an example. Before we met Chavic, we had a controversial monthslong, fraught discussion about all the work needed to be done to make Dart bindings work for those implementations who were most interested in jumping on the chance to run production Async Payjoin pilots. Both Cake Wallet and Bull Bitcoin Mobile apps are built in the Dart programming language, while Payjoin Dev Kit is built in Rust. PDK's strategy is to maintain a strongly-typed, well-tested core in Rust that we bind to various downstream languages for end users.

We reached out to Chavic, a young developer from Zambia, because of his public experience building Dart bindings from Rust outside of the Bitcoin space. Since "make all the library bindings work" might be hard to convey to "make Freedom Money" donors, I'd wager his applications to outside orgs would spend half a year or more in Bitcoin Grant Purgatory. Instead, we recruited his help in the span of a week and updated our Dart bindings before that grant would get approved. Not only are we seeing the results of our teamwork with Chavic in Payjoin Dev Kit, even Bitcoin Dev Kit is using his work now. This kind of recruiting is only possible by the same team that's having the burning technical issues, and organization lets us move much faster in this regard.

Nonprofit structure also frees us from some limitations of for-profit orientation, aligning our incentives with users' most pressing but hard-to-monetize concerns. Our accountability is to the public interest, not to quarterly returns. This makes it easier for us to make hard decisions prioritizing a long term view. Formalizing responsibility and accountability of Foundation leadership helps donors and users know that decisions are not made lightly. It also gives contributors clear direction and makes establishing a culture a more explicit, deliberate endeavor based on a formal written mission and norms. The Foundation is overseen by our board and operated for public benefit. Donations do not provide control over technical direction. We'll publish periodic updates on our work and funding as our reporting practices mature.

Thanks to all of our supporters, without which this work would not be possible. OpenSats and Cake Wallet get a shoutout here for being the very first to fund the Foundation itself. Thank you.

Thank you, Cake Wallet

· 2 min read

Feedback from implementations fuels our growth, and we want to thank Cake Wallet for being their close collaboration and reporting which helped lead to our stable rust-payjoin 1.0 release candidate. Just now, they have offered generous material support to the Payjoin Foundation to continue operations.

Cake wallet has been leading the way on the cutting edge of Bitcoin privacy technology and user experience. Async Payjoin is now their default Bitcoin flow, and their early support helps us improve so that more wallets and software may interoperate with Cake's use of the BIP 77 standard.

Cake wallet also runs an OHTTP Relay which users can use to reach Payjoin Directories, making the Payjoin infrastructure more robust and decentralized.

Vik's incessant Payjoin evangelism has brought Payjoin to a new audience at conferences, online, and in my experience even on the fly at chance meetings in restaurants. His message is clear: the world needs more Payjoin, and the time to support it is now. Seth has been a pleasure to work with since the beginning of the project, nudging developers to use the tools, offering his hand to contribute edits to the upstream source to improve the developer experience, and of course convincing the Cake team Payjoin needs doing. Konstantin has been the most reliable implementing developer, getting up at odd hours to service requests from our team and user feedback, and contributing his feedback to inform the integration upstream. The Cake pilot integration brings Async Payjoin to hundreds of thousands of devices.

Their recent generous donation to Payjoin Foundation additionally bolsters our ability to recruit and improve the core protocol libraries.

Thank you Cake for your generous support. The future of Bitcoin depends on it.

Yuval Kogman Joins Payjoin Foundation as Advisor

· 3 min read

Spiral Bitcoin Wizard and longtime Bitcoin privacy developer Yuval Kogman joins Payjoin Foundation as the first Advisory Board member. He draws on more than two decades of programming experience. Few others can boast Yuval's dedication to the Bitcoin privacy niche. He is perhaps best known for his work developing the WabiSabi DoS prevention protocol. His subsequent whistleblowing of privacy vulnerabilities in CoinJoin implementations, including those touting WabiSabi integration, demonstrates his commitment to the underlying principles.

Announcing Payjoin Foundation

· 2 min read

Commercial attempts to solve Bitcoin’s privacy problems have faced tremendous barriers. Short-term profit motives have delivered partial and temporary solutions, but transacting privately on Bitcoin remains a challenge.

We formed Payjoin Foundation to pursue the long-term mission of addressing Bitcoin’s privacy problems. Our non-profit exists to develop open-source protocols that align economic incentives with network-wide privacy protection. We believe that users have a right to choose whether or not to reveal their on-chain activity, and that such protocols can even offer a more convenient and delightful experience than those that don't respect this choice.

Automatically Refresh Liana Inheritance Timelocks with Payjoin

· 4 min read

Liana secures bitcoin such that after time passes, if and only if you haven't yet spent your coins, your heirs can spend them. This condition is called a "timelock" contract. To prevent unintentional activation of this inheritance policy, these timelocked coins require periodic refreshing by being spent into a new timelock. Liana's Payjoin integration automates timelock refresh as payments are received, boosting privacy and cutting costs.

Payjo.in Directory Security Incident: Misconfiguration May Have Exposed Some Payjoin v1 Messages

· 4 min read

Due to a docker misconfiguration, the payjo.in directory server had an open redis database, allowing unauthorized parties to observe exchanges between pairs of senders which only support BIP 78 and receivers which support BIP 77.

Some payjoins which used the backwards compatibility of BIP 77 receivers with BIP 78 senders during this period may thus not have the common input ownership heuristic protection they otherwise would, but the unauthorized access does not change the nature of the risk regarding the user custody of funds.

Payjoin Probing Attacks: Facts, Mitigations, and Why Payjoin Still Wins for Privacy

· 5 min read

The following is a conclusive address of concerns around UTXO probing attacks on Payjoin, clarification of why current mitigations are effective, and definitive argument for Payjoin adoption. Payjoin, the fundamental interactive transaction batching protocol, saves fees by reducing the effective size of transfers and improves privacy by disrupting common blockchain surveillance heuristics. While probing attacks exist in theory, they're costly to pull off, mitigated in practice, and are not a meaningful barrier to adoption.