# Silent Payments BIP Draft - Advancing Bitcoin Workshop ## Introduction ### Abstract ### Copyright ### Motivation 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 address, or a way for the send to generate addresses, 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[footnote]. 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. ## Goals We aim to present a transaction protocol which satisifies the following properties: * No increase in the size or cost of transactions * Resulting transactions blend in with other bitcoin transactions and can't be distinguished * Transactions can't be linked to a silent payment address by an outside observer * No sender-receiver interaction required * No linking of multiple payments to the same sender * Each silent payment goes to a unique address, avoiding accidental reuse * Supports payment purpose labeling * Uses existing seed phrase or descriptor methods for backup and recovery * Separates scanning and spending responsibilities * Compatible with other spending protocols, such as CoinJoin * Light client/SPV wallet support * Protocol is upgradeable ## Overview We first present an informal overview of the protocol followed by a full specification, separated by sender and reciever. ### Simple case Alice publishes a public key *A* as her silent payment address. Bob selects an input *B,b* and tweaks Alice's public key to create a destination public key *D* in the following way: * Let *D = HASH(b·A)·G + A* Bob constructs a transaction in the normal way with *B* as an input and *D* as the destination address. Alice detects this payment by computing *D = HASH(a·B)·G + A* (Diffie-Hellman Key Exchange). ### Sending to more than one output For additional privacy, Bob can derive multiple outputs for Alice in the following manner: * Let *D~0~ = HASH(b·A \|\| 0)·G + A* * This is defined as the *0-tweaked address* * For additional outputs: * Let *D~i~ = HASH(b·A \|\| n)·G + A*, where *n* starts from 1 and is incremented for each subsequent output Alice detects this output the same as before by searching for *D~0~ = HASH(a·B \|\| 0)·G + A*. Once she detects the *0-tweaked address*, she must: * Check for *D~1~ = HASH(B·a \|\| 1)·G + A* * If *D~1~* is not found, she is done * If *D~1~* is found, she continues to check for *D~2~* and so on until an output is not found Since Alice will only perform these subsquent checks after a transaction with a *0-tweaked address* paying her is found, the increase to her overall scanning requirement is negligible. ### Preventing address reuse If Bob were to use a different UTXO from the same public key *B* for a subseqent payment, he would end up deriving the same destination for Alice. To prevent this, Bob should include a hash of the outpoint in the following manner: * Let *outpoint_hash = HASH(txid \|\| vout)* * Let *D~0~ = HASH(outpoint_hash·b·A)·G + A* ### Using all inputs In our simplified example we have been referring to Bob's transactions as having only one input *B*, but in reality a Bitcoin transaction can have many inputs. This complicates our protocol by forcing Bob to choose a particular input and requires Alice to check each input for each transaction. We can simplify things by requiring Bob to tweak Alice's public key *A* with the sum of his input private keys: * Let *outpoints_hash = HASH(txid~1~ \|\| vout~1~ \|\| .. txid~n~ \|\| vout~n~)* * Let *inputs~priv~ = i~1~ + i~2~ .. + i~n~* * Let *D~0~ = HASH(outpoints_hash·inputs~priv~·A)·G + A* Alice now only needs to compute one tweak per transaction with the sum of the inputs, instead of computing a tweak per input. ### Spend and Scan Key Since Alice needs *a* to check for incoming payments, this requires her private key to be unencrypted in an online device. To mitigate this, Alice can instead publish an address of the form *(A, S)* where *A,S* are both public keys and Alice controls both private keys *a,s*. This allows Alice to keep *a* in offline cold storage and perform the scanning with the public key *A* and private key *s*. Bob performs the tweak using both of Alice's public keys in the following manner: * Let *D~0~ = HASH(outpoints_hash·inputs~priv~·S)·G + A* Alice detects this payment by calculating *D~0~ = HASH(outpoints_hash·inputs~pub~·s)·G + A* with her online device and can spend from her cold storage signing device using *a + HASH(outpoints_hash·inputs~pub~·s) mod P* as the private key. ### Labels For a single silent payment address of the form *(A,S)*, Alice may wish to differintiate incoming payments by using labels. Naively, Alice could publish multiple silent payment addresses, but this would require her to scan for each silent address, which becomes prohibitively expense. Instead, Alice can tweak the spend public key *A* with an integer *m* in the following way: * Let *A~m~ = A + m·G* * Publish *(A~0~, S)*, *(A~1~, S)* Bob performs the tweak same as before using one of the published *(A~m~,S)* pairs. Alice detects the labeled payment in the following manner: * Let *D = HASH(outpoints_hash·inputs~pub~·s)·G + A* * Compute *D~m~ = D + m·G* for each *m* * For each *D~m~* in {*D~0~ .. D~m~*}, check if they are present in the transaction outputs ## Specification Define notation and definitions here [WIP] * Define A scan, spend * Define G * Define the HASH function used (sha256) * Define the 8 byte truncation hash * Define Input Keys * Define wallet labels (max, integer) * Define additional outputs (vouts?) * Define sp identfier * Define a single byte for bit flags * (tagged hash??) ### Sender In order to send to a silent payment address, the sending wallet must be able to do the following: * Recognize the new silent payments address type * Generate new taproot output(s) for the recipient using the inputs of the transaction There is no scanning requirement for the sender. #### Selecting inputs The sending wallet performs coin selection as usual with the added restriction that the sending wallet must be able to produce a signature for each UTXO. This excludes any UTXOs not requiring a signature for spending as these do not represent elliptic curve points. Given that these types of scripts are not widely used, no changes to coin selection will be required for the majority of wallets. #### Creating the outputs After the inputs have been selected, the sender creates the receivers address in the following manner: * Collect each *outpoint* from the transaction, where an outpoint is the 36 byte little-endian representation of the previous output transaction id and vout index * Let *outpoints = outpoint~1~ \|\| outpoint~2~ \|\| .. \|\| outpoint~n~* * *outpoints* MUST be concatenated in the same order as they appear in the final transaction * Let *outpoint_hash = SHA256(outpoints), truncated to the first 8 bytes* * Let *inputs~priv~ = i~1~ + i~2~ + .. i~n~*, where each *i* is the 256-bit private key corresponding to the *ith* input public key of the transaction * Compute the tweak: * Let *A~m~ = Recipients 32 byte x-only spend public key, tweaked with an optional label m* * Let *S = Recipients 32 byte x-only scan public key* * Let *t~0~ = SHA256(SHA256(outpoint_hash·inputs~priv~·S \|\| 0))* * Optionally, if more outputs are desired: * Let *n = 1* * Let *N = desired number of recipient outputs* * While *n* is less than or equal to *N*: * Let *t~n~ = SHA256(SHA256(outpoint_hash·inputs~priv~·S \|\| n))* * Repeat with *n++* * For each *t~n~*: * Let *D~mn~ = t~n~·G + A~m~* * Encode *D~mn~* as a *bech32m* taproot address ### Receiver In order to receive silent payments, the receiving wallet must be able to do the following: * Generate a spend and scan key: * In the case of a cold storage signing device, export the scan private key to a watch only wallet or scanning service * Construct a silent payment address * Scan for silent payments, either by having access to the full blockchain or by outsourcing the scanning via the scan key * Support receiving and spending taproot outputs #### Address encoding A silent payment address is a 64 byte address, constructed in the following manner: * Let *HRP = sp1* * Let *A, S = 32 byte BIP340 public keys* * Let *A~m~ = A + m·G*, where *A* is the spend public key and *m* an optional integer tweak for labeling * The final address is a 64 byte address of the form *HRP \|\| A~l~ \|\| S* #### Key Derivation Two keys are needed to create a silent payments address: the spend key and the scan key. While these keys can be generated independently, it is strongly recommended implementations use BIP32 derivation to ensure compatibility across wallets. Deriving from a master key using hardened derivation also ensures that: * Both keys are recoverable from a single backup of the master key (BIP39 style or otherwise) * The spend private key is unknown even if the scan private key is leaked We propose the following derivation paths, using a BIP44 style purpose: * `m/[BIP-NUMBER]'/0'` for the spend private key * `m/[BIP-NUMBER]'/1'` for the scan private key A scan and spend key pair are defined in the following manner: * Let *spend~priv~ = m/BIP'/0'/k* * Let *scan~priv~ = m/BIP'/1'/k* Each value of *k* represents a pair of private keys needed for creating a silent payment address. In this way, multiple silent payment addresses can be derived from a single master key. If the master key is generated on an offline cold storage device, it will be necessary to export *scan~priv~* to an online scanning device. [is this sentence necessary?][footnote] #### Scanning For each transaction the receiving wallet suspects might be a silent payment to themselves, it must: * Collect each *outpoint* from the transaction, where an outpoint is the 36 byte little-endian representation of the previous output transaction id and vout index * Let *outpoints = outpoint~1~ \|\| outpoint~2~ \|\| .. \|\| outpoint~n~* * *outpoints* MUST be concatenated in the same order as they appear in the transaction * Let *outpoint_hash = SHA256(outpoints)*, truncated to the first 8 bytes * Let *inputs~pub~ = I~1~ + I~2~ + .. I~n~*, where each *I* is the public key corresponding to the *ith* input of the transaction * Compute the tweaks: * Let *M = the number of labels the Recipient wallet has used* * Let *A = Recipient's 32 byte x-only spend public key* * Let *s = Recipient's 256-bit scan private key* * Let *t~0~ = SHA256(SHA256(outpoint_hash·s·inputs~pub~ \|\| 0))* * Compute *D~00~ = A + T~0~·G* * If *M* greater than 0: * Let *m = 1*: * While *m* <= *M*: * Compute *D~m0~ = A + m·G + t~0~·G* * repeat with *m++* * For each public key *D~m0~* in {*D~00~ .. D~M0~*}: * If *D~m0~* is detected in the transaction outputs: * Save *D~m0~* * Let *n = 1* * Compute *t~n~ = SHA256(SHA256(outpoint_hash·inputs~pub~·s \|\| n))* * Check if *D~mn~ = A + m·G + t~n~·G* is present in the remaining outputs * If not, terminate * If found, save *D~mn~* and repeat with *n++* For each *D~mn~* output found, store the output and corresponding tweak data, *T~n~*, in the wallet. For spending: * Let *a = the private key corresponding to the scan public key, A* * Let *m = the optional integer label tweak* * Let *T~n~ = the tweak data corresponding to the output D~mn~* * *D~mn~* is spendable with the private key *d = a + m + T~n~ mod P* #### Backup and Recovery Since each silent payment output address is derived independently, we cannot rely on BIP32 derivation when recovering from a backup. Because of this, descriptor wallets are recommended along with regular backups. When recovering from a backup, the wallet will need to scan since the last backup to detect new payments. If using a seed phrase only style backup, the user can recover the wallet's current state from the UTXO set and can recover the wallet history by scanning the blockchain, starting from the wallet birthday. ##### Recovery from the UTXO set The wallet computes a tweak for every unspent transaction containing at least one unspent taproot output, where the unspent output was created after the wallet birthday. ##### Recovering transaction history All transactions created after the wallet birthday and with at least one taproot output will need to be scanned to recover the full transaction history. ### hacspec specification examples: * https://github.com/ElementsProject/cross-input-aggregation/blob/master/hacspec-halfagg/src/halfagg.rs * https://github.com/hacspec/hacspec/blob/master/examples/bip-340/src/bip-340.rs ## Test Vectors ## Rationale and References ## Acknowledgements