Using a new address for each Bitcoin transaction is a crucial aspect of maintaining privacy. This often requires a secure interaction between sender and receiver so that the receiver can hand out a fresh address, a batch of fresh addresses, or a method for the sender to generate addresses on-demand, such as an xpub.
However, interaction is often infeasible and in many cases undesirable. To solve for this, various protocols have been proposed which use a static payment address and notifications sent via the blockchain. These protocols eliminate the need for interaction, but at the expense of increased costs for one-time payments and a noticeable footprint in the blockchain, potentially revealing metadata about the sender and receiver. Notification schemes also allow the receiver to link all payments from the same sender, compromising sender privacy.
This proposal aims to address the limitations of these current approaches by presenting a solution that eliminates the need for interaction, eliminates the need for notifications, and protects both sender and receiver privacy. These benefits come at the cost of requiring wallets to scan the blockchain in order to detect payments. This added requirement is generally feasible for full nodes but poses a challenge for light clients. While it is possible today to implement a privacy-preserving light client at the cost of increased bandwidth, light client support is considered an area of open research
== Goals ==
We aim to present a protocol which satisfies the following properties:
We first present an informal overview of the protocol. In what follows, uppercase letters represent public keys, lowercase letters represent private keys, || refers to byte concatenation, and G represents the generator point for secp256k1. Each section of the overview is incomplete on its own and is meant to build on the previous section in order to introduce and briefly explain each aspect of the protocol.
=== Simple case ===
Bob publishes a public key B as a silent payment address. Alice discovers Bob's silent payment address, selects a UTXO with private key a, public key A and creates a destination output P for Bob in the following manner:
In order to allow Alice to create more than one output for Bob, we included an integer in the following manner:
=== Preventing address reuse ===
If Alice were to use a different UTXO from the same public key A for a subsequent payment to Bob, she would end up deriving the same destination P. To prevent this, Alice should include a hash of the outpoint in the following manner:
=== Using all inputs ===
In our simplified example we have been referring to Alice’s transactions as having only one input A, but in reality a Bitcoin transaction can have many inputs. Instead of requiring Alice to pick a particular input and requiring Bob to check each input separately, we can instead require Alice to perform the tweak with the sum of the input public keys[3]. This significantly reduces Bob's scanning requirement, makes light client support more feasible[4], and protects Alice's privacy in collaborative transaction protocols such as CoinJoin[5].
Alice performs the tweak with the sum of her input private keys in the following manner:
Since Bob needs his private key b to check for incoming payments, this requires b to be exposed to an online device. To minimize the risks involved, Bob can instead publish an address of the form (Bscan, Bspend). This allows Bob to keep bspend in offline cold storage and perform the scanning with the public key Bspend and private key bscan. Alice performs the tweak using both of Bob’s public keys in the following manner:
=== Labels ===
For a single silent payment address of the form (Bscan, Bspend), Bob may wish to differentiate incoming payments. Naively, Bob could publish multiple silent payment addresses, but this would require him to scan for each one, which becomes prohibitively expensive. Instead, Bob can label his spend public key Bspend with an integer m in the following way:
=== Labels for change ===
Bob can also use labels for managing his own change outputs. To do so, he can reserve a secret change label in the following manner: