Author: Armin Sabouri
Source: https://payjoin.org/blog/2026/03/25/wallet-fingerprints-payjoin-privacy/
When constructing a transaction, wallet software makes dozens of tiny decisions: the order of inputs, the selection of currencies, the estimation of transaction fees, and the encoding of signatures; and so on. The pattern formed by these decisions is called a "wallet fingerprint," which varies systematically between different software implementations, and can therefore be used to identify the source wallet software that created the transaction on the blockchain.
Some fingerprints are deterministic. For example, when generating ECDSA signatures, Bitcoin Core continuously tries different random numbers ("grinding") to ensure the final signature has a "low r value" (resulting in a shorter signature). Therefore, if a signature is 72 bytes long, Bitcoin Core can be immediately ruled out as the signature generator . Other fingerprints are probabilistic: transaction fee rates from different wallet software exhibit typical distributions. Bugs can also become fingerprints. Each maintenance provides independent evidence, and these pieces of evidence, when combined, can be very favorable. Ishaana Misra has conducted a comprehensive study on wallet fingerprints ( Chinese translation ).
Fingerprints can enhance the effectiveness of wallet clustering analysis—which uses behavioral cues to group related transaction outputs (coins). For background information on clustering analysis, see Yuval Kogman's blog post ( Chinese translation ) recounting the history of wallet clustering analysis . Recent work on using wallet fingerprints to support existing cue analysis (such as change output identification ) has demonstrated significant improvements over coarse heuristics. Kappos et al . proved that combining fingerprints from neighboring transactions with numerical analysis can improve the accuracy of clustering analysis; this feasibility was validated using real-world data. This directly threatens the privacy model of Payjoin transactions: it relies on the inability to distinguish between the sender and receiver inputs. Wallet fingerprints, capable of distinguishing input sources, bring back the clustering analysis that Payjoin attempted to break.
(Translator's note: "heuristics" in this article is translated as "clue analysis" or "heuristic analysis".)
This article uses this perspective to observe real payjoin transactions.
Two-layer association
In theory, payjoin transactions appear no different from standard one-sided transactions. Analysts using traditional heuristics might misclassify these transactions, grouping the sender's and receiver's inputs (money) into the same cluster. Therefore, the first step in perceiving payjoin transactions is to detect the human intervention in these collaborative transactions.
The work of Simin Ghesmati et al. demonstrated how quirks in input selection (specifically, the arrangement of redundant inputs) can be used to detect payjoin transactions and distinguish the owners of inputs and outputs. Wallet fingerprinting provides another signal for the same task.
If the sender and receiver use different wallet software, fingerprints can reveal which input and output belong to whom. Once you infer the ownership distinction, the standard "Input Identity of Ownership (CIOH)" clustering method can be applied to the inputs of each participant, thus, from an analytical perspective, payjoin is equivalent to a pair of regular (one-sided payment) transactions.
The wallet's fingerprint signal conveys information on two levels:
- Within a single transaction : These signals help distinguish the owners of the various inputs and outputs within a single transaction. Which output is change (returned to the sender), and which is payment (sent to the recipient)? Correct change output identification is crucial because it links the sender's current transaction to their next transaction. Fingerprints may reveal this directly: because of the wallet software used by the sender, change outputs may inherit the same characteristics (as with a certain input).
- Between trades : The meaning of signals displayed on the trading chart:
- Backward : Each input is created from some preceding transactions, which may carry a unique fingerprint.
- Forward : Every output may be spent in the future, and the transactions that spend them may also carry fingerprints.
Therefore, the goal of blockchain analysis for a payjoin transaction is:
- Traces of collaborative transactions were detected.
- Use intra-trade signals and inter-trade signals to identify the sender/receiver distinction.
- Apply standard heuristic analysis to the differentiated clusters.
Case 1: Samourai Payjoin
Transaction : 8dba6657...
Observing the values of each field in this transaction, nothing suspicious is apparent. nSequence (the numerical value of the field) of the two inputs is the same, both use the P2WPKH script public key type, and their witness data stacks look similar. The signal comes from the length (number of bytes) of the signature.
The DER-encoded (ECDSA) signature for input 0 is 71 bytes (it's low r); the signature for input 1 is 72 bytes (it's high r). A wallet that grinds will only produce low r signatures; a wallet that doesn't grind will only produce low r signatures with a 50% probability. Therefore, the presence of a low r/high r signature pair in a transaction is not strong evidence of cooperation. However, if one of the inputs comes from a cluster that always grinds, and this time it appears alongside a high r input, the probability that they belong to two different wallet clusters is much higher.
Using the asymmetry of the signature as a candidate differentiator: Participant A holds a low r input, and Participant B holds a high r input; the former has a denomination of 50,000 satoshis, and the latter has 3,999,216 satoshis. We can test two possible output scenarios:
Case 1 : Output 0 (9752 Satoshis) belongs to A, and output 1 (403 9216 Satoshis) belongs to B.
- Participant A: 50,000 in, 9,752 out; net outflow of 40,248.
- Participant B: 399,9216 entries, 403,9216 exits; net inflow of 40,000.
- Meaning: A paid B 40,000 satoshis (the other 248 satoshis was a transaction fee).
Case 2 : Output 0 (9752 satoshis) belongs to B, and output 1 (403 9216 satoshis) belongs to A.
- Participant A: 50,000 in, 4,039,216 out; net inflow of approximately 4 million satoshis.
- Participant B: 399,9216 entries, 9,752 exits; net outflow of 398,9464.
- Meaning: A paid B 40,000 satoshis (the other 248 satoshis was a transaction fee).
Scenario 1 means the payment is exactly 40,000 satoshis; Scenario 2 means 3,989,216 satoshis. Integer heuristics tend to favor Scenario 1. Subsequent spending transactions reinforce this conclusion: output 0 is also spent with a low r signature (consistent with A's input in this transaction); output 1 is also spent with a high r signature (consistent with B's input in this transaction).
Payjoin was thus dismantled: the ownership distinction between inputs and outputs was deduced, and the amount of payment was determined.
Case 2: PDK Demo Payjoin
Transaction : 3c5436f1...
Both inputs use P2TR key path cost. According to the Taproot cost rules on P2TR , the default sighash label is SIGHASH_ALL , and this sighash byte can be omitted. Omitting it is the orthodox form, but not omitting it is also valid for consensus. The witness data for input 0 is 64 bytes —it omits the sighash byte. But the witness data for input 1 is 65 bytes — 0x01 appears (the byte explicitly indicating SIGHASH_ALL ). The appearance of this byte is usually an implementation bug, not intentional.
Two inputs from the same wallet (using the same wallet software) should use a consistent sighash strategy. This inconsistency distinguishes the two inputs: participant A holds the input with the sighash bytes omitted; participant B holds the output with the explicit sighash bytes.
Unlike Case 1, in this case, the numerical clues cannot distinguish the owner of the output. The two attribution scenarios are semantically equivalent:
Case 1 : Output 0 (5 9014 Satoshis) belongs to A, and output 1 (86 4506 Satoshis) belongs to B.
- Participant A: 5,1514 entries, 5,9014 exits; net inflow of 7,500.
- Participant B: 87,2224 entries, 86,4506 exits; net outflow of 7,718.
- Meaning: B paid A 7500 satoshis (the other 218 satoshis was a transaction fee).
Case 2 : Output 0 (5 9014 Satoshis) belongs to B, and output 1 (86 4506 Satoshis) belongs to A.
- Participant A: 5,1514 entries, 86,4506 exits; net inflow of 81,2992.
- Participant B: 87,2224 entries, 5,9014 exits; net outflow of 813,210.
- Meaning: B paid A 81,2992 satoshis (the other 218 satoshis was a transaction fee).
Integer clues tend to favor scenario 1, but this approach isn't foolproof. We're fairly certain it's a multi-party constructed transaction because of the presence of wallet fingerprints; however, ownership distinctions are uncertain. The inconsistency in Sighash's handling is a lingering vulnerability, but that's about it.
However, later, the second output's cost transaction again contained bytes explicitly indicating SIGHASH_ALL , consistent with the second input in this transaction. This strongly suggests that the second output and the second input belong to the same transaction, making scenario 1 more likely.
Case 3: Cake Wallet → Bull Bitcoin Mobile Payjoin
Transaction : 8fb80573...
The first thing that catches the eye is that both inputs have the value 0x01 in nSequence field. Cake Wallet sets a relative time lock according to BIP-68, and Bull Bitcoim Mobile also matches this value, so there is no asymmetry within the transaction between the two inputs. The signatures are also homogeneous: both inputs use low-r signatures and the same sighash label. Based solely on this transaction, fingerprint analysis is stalled.
However, the attribution of funds provides a possible distinction. Two scenarios are as follows:
Case 1 : Output 0 (29358 satoshis) belongs to B, and output 1 (429919 satoshis) belongs to A.
- Participant A: 44,0337 in, 42,9919 out; net outflow 10,418.
- Participant B: 19,538 in, 29,358 out; net outflow of 10,000.
- Meaning: A paid B 10,000 satoshis (the other 418 satoshis were transaction fees).
Case 2 : Output 0 (29358 Satoshis) belongs to A, and output 1 (429919 Satoshis) belongs to B.
- Participant A: 44,0337 entries, 29,358 exits; net outflow of 410,979.
- Participant B: 19,538 entries, 429,919 exits; net inflow of 410,561.
- Meaning: A paid B 41,0561 satoshis (the other 418 satoshis were transaction fees).
The assumption of an integer payment amount overwhelmingly favors Case 1. Furthermore, the receiver's input (19358 satoshis) is less than the sender's change (429919 satoshis), consistent with the UIH2 (redundant input) assumption: the sender lacks the appropriate denomination and therefore provides a large input and creates a large change, while the receiver's funds are just enough to cover the payment amount. One possible distinction is: output 0 (29358 satoshis) is the payment, input 1 (19358 satoshis) is the receiver's UTXO, and output 1 (429919 satoshis) is the sender's change.
Cross-transaction analysis also supports this conclusion. The preceding transaction to input 0 has one input with an nSequence value of 0x01 , but another input with an nSequence value of 0xfffffffd . This asymmetry distinguishes the inputs of this transaction, allowing us to know that its output, with a face value of 44 0337, belongs to the participant using an nSequence value of 0x01 ; this output, as input 0, enters the payjoin transaction we are examining.
Furthermore, all outputs of the preceding transactions to input 1 use only 0xfffffffd as the nSequence value. Additionally, the transaction that spends output 1 also sets the nSequence value to 0xfffffffd . This is consistent with typical behavior in Bull Bitcoin Mobile, thus 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 input fingerprints are persistently present in the transaction graph. Cake's 0x01 can be traced back to the preceding transaction, while Bull Bitcoin Mobile's 0xfffffffd can be traced both forwards and backwards. This single payjoin transaction might not reveal much, but it becomes clear once you examine adjacent transactions.
in conclusion
These observations tell us that Payjoin's privacy protection is only preserved if the fingerprints of the participants' wallets are homogeneous. Transaction-level fingerprint homogeneity is necessary, but not sufficient. Differences between senders and receivers in any dimension can become a signal distinguishing them. The analyst's job simplifies to finding these differences in wallet actions, and the transaction graph provides a variable number of observations that analysts can use to find them.
While some wallet fingerprints are relatively easy to erase , others are inherent to specific design choices and goals of the wallet and cannot be easily "fixed." Wallet developers should be aware of potential privacy breaches when integrating Payjoin into their software.
The analysis in this paper focuses on individual payjoin transactions, but the method can be generalized. The distribution of wallet fingerprints can become a property of a cluster; a cluster with consistent fingerprints is more trustworthy than a cluster with incompatible internal features. This points to a broad class of attacks on payjoin privacy. Future work will develop an automated, large-scale analysis using fingerprint distributions to score the trustworthiness of clusters. We are developing such a tool as part of our privacy metrics framework .
(over)





