Bitcoin is one of the most pivotal hacks of the entire digital age in terms of transferring value from one person to another. No intermediaries required. It is secured by a decentralized quorum for miners and is validated by each participant on the network who chooses it in order to ensure the correctness of individual payments. The architecture of the system is designed to allow anyone from anywhere on the planet to receive money from anyone else, no matter where they are. Crowdfunding, charity or funding anything you want is instantly possible without anyone’s permission, without dealing with any guards, without any routine. It’s a great idea in theory, but in reality it suffers from a massive flaw: privacy.
As a payment-based payment system (no one is allowed to “withdraw” payments from you, you must explicitly authorize them and “pay” them to other people), Bitcoin requires the sender to obtain the information necessary to determine the destination of the money they are sending. This requires the recipient to somehow communicate with the sender with their Bitcoin address. In the event of an attempt to raise funds from the general public, this has serious consequences in terms of privacy or the need to maintain a permanent interactive online presence. Anyone is perfectly capable of posting a single Bitcoin address somewhere online, and from that point on, anyone who wants to send money to that person can do so, but there is no privacy in collecting money this way. Just take that address and search for it in the blockchain, and not only can you see how much money that person sent, but you can see the fingerprint on the blockchain of everyone who sent the money to them. Both the person trying to raise money and everyone who donated to them have no privacy whatsoever; Everything is completely open and connected for the whole world to see.
The only alternative to address reuse in the form of publicly posting a single static address would require running a server that stays online so that people can request a new, unused address every time someone new wants to donate money. While having something online all the time in the digital age may not seem like a problem, it does come at a cost and complexity, especially if someone is trying to run it themselves at home with their own devices. And what about people who only have a mobile device? It’s almost impossible these days, with current OS features, to optimize battery usage to keep something running in the background all day, and even if you could, it would drain your battery.
Enter BIP47 by Justus Ranvier. The purpose of this proposal is to enable a way for someone to be able to post enough information to the public to be able to receive money from anyone who chooses to do so, without this public information being sufficient (i) to track how much money the person who made the post received and (ii) Disclose to the public any information about who sent the money to the person requesting it. The basic idea is to take that publicly published information (or payment token), and from there, combine its payment token to create a new set of addresses for which the recipient can generate the private keys. This new set of addresses is specific to the relationship between an individual sender and receiver, every time a new sender uses this protocol to send money to the receiver, it will generate a new set of addresses unique to each.
At a high level, the public flow follows like this: a person who wants to receive funds generates a new extended public key from their HD wallet in a new derivation path and posts this publicly. This new public key acts as a ‘push token’. From here, someone who wants to send money to them will take this new payment code, and have all the information needed to create new addresses to send money to. However, the problem is that the sender needs to communicate their payment code information to the recipient, otherwise they won’t be able to generate the private key needed to actually spend the money sent to them. This requires a special Notification Transaction.
Let’s say Alice wants to deal with Bob using payment codes. Alice chooses a UTXO to send to Bob’s notification address, from here she takes the private key associated with that UTXO and the public key associated with Bob’s notification address. She hits them together to create a secret key that will blind. With this, she can encode her push token and encode it into the OP_RETURN output. This means that Bob, by taking the private key to his notice address and the public key to Alice’s spent entry, is the only person who can decrypt and read this information. This works because hitting Bob’s private Alice key produces the same value as hitting Bob’s private Alice’s public key.
Alice and Bob can now derive a new set of addresses that only the two of them know, and Alice can now send any amount of transactions to Bob using a new address each time without any outside observer being aware of their connection. There is a second variation, where instead of sending an output to Bob’s notification transaction, Alice creates a change output for herself using a 1-of-2 multisig where one key is her change address, and the second is Bob’s push token ID. The third figure uses a 1 in 3 multi-signal output to encode the necessary information in place of OP_RETURN. Other than that, things work the same way.
The only drawback with BIP47 is the need to use blockspace to send a special transaction to let the recipient know that they will receive the money before it is actually spent. This ends up being very inefficient in use cases where someone is trying to send only one batch. There is also the risk of effectively harming privacy if the UTXO used to process the notification is connected to the UTXO used to make payments to someone’s BIP47 addresses. Care must be taken to ensure segregation between these two matters to not create traceable on-chain and proprietary links to UTXOs generated by different payments.
Silent payments are the latest idea from Robin Sumsen. It effectively solves the same problem as BIP47 without the need for a notification transaction with the trade-off of having to scan more transactions to reveal which payments are made to the recipient. The idea is pretty much the same in the abstract: you publish a piece of public information, and from that, the sender is able to create a new address that only the recipient will be able to rebuild. The difference is in the implementation details.
The recipient publishes a “silent” public key to some accessible location, then the sender takes that public key and modifies that public key with the private key of one of the inputs it will spend to make a payment to the recipient. This is done by multiplying the sender’s private key with the receiver’s silent public key and then adding that silent public key again. This results in a new address, which the receiver can retrieve by hitting their private key with the sender’s public key entry, and adding their silent public key. Simply.
The big downside here is that supporting lightweight clients is very difficult, as the receiver has to examine every transaction in each block and calculate the combinations of inputs modified to their key to see if they match an output in the transaction. For a full node user, this is not an unbearable increase in validation costs, but for light wallets without a full node, this becomes very expensive. This can be further improved by scanning the UTXO array. Jonas Nick of Blockstream ran a benchmark test on an Intel i7 and found that it took about three and a half hours to scan the entire suite and run accounts to check addresses. This does not include the time it takes to search for the transaction that generated each UTXO to find the public input keys needed to run that account. This has not yet been measured or tested, so cost and time remain an open question.
An additional improvement that can be made is to use each public key entry for the transmission transaction as part of the disk, which lowers the cost of scanning to see if you’ve been paid by not requiring you to scan every single entry in the transaction and operating the account individually. This would further complicate doing so with CoinJoin transactions, as it would require every other participant to actively participate in the master tweaking. It would also leak them the output you’re paying for a naive implementation. However, it will prevent the recipient from knowing which input was used to pay them, and by cryptographically obfuscating the information shared with other CoinJoin participants, it will prevent them from knowing which output is the silent payment, thus alleviating all privacy concerns.
It is also possible to add a scan and spend key together in the derivation process so that the recipient can have a single key online which is all that is needed to detect incoming payments, while keeping the key necessary to spend the coins they have obtained offline and in cold storage. This will change the derivation to hitting the private key of the sender’s input with the scan key and then adding the key necessary for the spend. This will allow for more security in receiving payments, leaving your privacy only at risk if the recipient’s device is hacked.
Another major thing to consider is the possibility of the address being reused by the sender. In the basic implementation, if the sender has multiple UTXOs with the same public key, reusing them to send them to the same person with a silent push will result in the same silent address and constitute address reuse. This can be prevented by including the TXID and the input index of the transaction entries used in the scheme, which can be pre-computed before being sent to light clients to not create an additional computational burden on them.
In general, the idea is a significant improvement over BIP47 in all respects, except for the higher costs of validating the receiver to look up the money that has been sent. It preserves the deterministic feature of payback, realizes that the different payments sent to the recipient cannot be correlated, and removes the need for a notification transaction before the payments are made. Once again, Somsen has come up with a very powerful idea for a protocol that can be implemented to improve the usefulness of Bitcoin.
This is a guest post by Shinobi. The opinions expressed are their own and do not necessarily reflect the opinions of BTC Inc or Bitcoin Magazine.