Stealth Transactions and Reusable Payment Codes: How Bitcoin Addresses Can Be Hidden in Plain Sight
Bitcoin, right now, is not really anonymous. While Bitcoin addresses aren't necessarily linked to real-world identities, they can be. Monitoring the unencrypted peer-to-peer network, analysis of the public blockchain and know your customer (KYC) policy or anti-money laundering (AML) regulation can reveal a lot about who's using bitcoin and for what.
This is not great from a privacy perspective. Bitcoin users might not necessarily want the world to know where they spend their money, what they earn or how much they own, while businesses may not want to leak transaction details to competitors, to name some examples.
Additionally, bitcoins being traceable, possibly “tainted,” and potentially worth less than other bitcoins is at odds with fungibility. This could even challenge bitcoin's value proposition as money.
But there are potential solutions to increase privacy and improve fungibility.
In part to increase privacy (there are security benefits as well), it is recommended that Bitcoin users generate a brand new address for each transaction they receive. While this is not an airtight solution in itself, this can make it significantly harder to connect addresses to real world identities ‒ both on the sending and the receiving end of the transaction.
However, this also means that the receiver must share a new Bitcoin address with the sender each time a transaction is to be made. This can be a bit of a hassle and in some cases even impossible (think of donation addresses posted on websites). And it’s not ideal from a privacy perspective either: If the new addresses are shared over an insecure channel, privacy is potentially lost entirely.
Stealth Transactions, first proposed in 2014 by Bitcoin Core developer Peter Todd, are designed to solve these problems. They use several cryptographic tricks, mostly based on Diffie-Hellman key exchange, to let users accept payments on addresses they never generated, nor have even seen before.
Under the Hood
This is how Stealth Transactions work “under the hood.”
[Authors note: Since completion of this article, it was brought to my attention that there are actually several slightly different ways to construct Stealth Transactions. The strategy described here is only one particular option.]
Stealth Transactions require the sender and receiver of a transaction to have a (basically non-Bitcoin-related) cryptographic public and private key pair, each. We'll call these the “stealth private keys” and the “stealth public keys.” These “stealth keys” are used in several ways.
The first way is a fairly basic use-case of cryptography, which is, for example, used to encrypt emails. In short (and a bit simplified), the sender can take the receiver's stealth public key and use it to encrypt a message. The receiver – and only the receiver – will be able to decrypt this message with his stealth private key.
(This works the other way around as well, of course: The receiver could encrypt a message for the sender – but that's not really relevant for Stealth Transactions.)
The second trick is slightly more complex. But, again, in simplified form, both stealth private keys can be combined through a mathematical formula, to create a Bitcoin private key. This Bitcoin private key can, in turn, be used to generate a corresponding Bitcoin address. So, using each other’s stealth private key in combination with their own, both sender and receiver can generate this Bitcoin private key and Bitcoin address.
And there is a third trick, in simplified form: This Bitcoin address (but not the corresponding Bitcoin private key) can also be derived from one of the stealth private keys and one of the stealth public keys. As such, either the sender or the receiver can generate the Bitcoin address by combining their own stealth private key with the other's stealth public key.
To make a Stealth Transaction, these three tricks are cleverly combined:
Possibly even before any payment was going to be made, the receiver generates a stealth key pair. It's this stealth public key that he,for example, posts on his website as a donation address. (As such, it’s also called the “Stealth Address.”) He doesn't share his stealth private key with anyone at all.
When the sender wants to pay the receiver, he generates a “throwaway” stealth private key for himself; specifically for that one transaction. (It’s actually a “nonce”; just a random string of numbers – but has the same effect.) He then takes the receiver's stealth public key (or Stealth Address) and combines this with his own throwaway stealth private key, to generate a Bitcoin address and sends bitcoins to this Bitcoin address. (Well, almost... but let's assume that for a moment.)
At this point, no one can spend the bitcoins on this address because no one knows (nor is able to generate) the corresponding Bitcoin private key.
But here's the heart of the trick: the sender can allow the receiver to spend the bitcoins by sharing his throwaway stealth private key with him. With that throwaway stealth private key, the receiver would have both stealth private keys required to generate the Bitcoin private key.
Interestingly, this is accomplished all at once, within the transaction that funds the Bitcoin address. Specifically, the sender includes a so-called OP_RETURN “message” in that transaction. This message consists of his throwaway private key, but encrypted using the receiver's public key, so no one but the receiver can decrypt it.
To receive this transaction, the receiver monitors the blockchain for OP_RETURN transactions and tries to decrypt all of them. Once he finds a decryptable OP-RETURN message, he also finds the throwaway stealth private key to combine with his own stealth private key, with which he can generate the Bitcoin private key to spend the bitcoins in that transaction.
The receiver will have received a secure payment on an address he didn't even own until the actual payment was made. Meanwhile, the outside world might not even know it was a Stealth Transaction; all they see is a normal Bitcoin-transaction with an undecipherable OP_RETURN message attached.
Reusable Payment Codes
While Stealth Transactions offer a novel solution, the requirement to monitor the blockchain for OP_RETURN transactions do limit their potential. Specifically, light wallets typically don't store the entire blockchain and are, therefore, unable to receive Stealth Transactions. (DarkWallet, the only wallet that allows for Stealth Transactions so far, “outsources” this task to a server, which is not ideal for privacy.)
Reusable Payment Codes, introduced by Bitcoin developer Justus Ranvier in late 2015, are designed to solve this problem. They use another Bitcoin innovation designed by Bitcoin Core developer Dr. Pieter Wuille: The Hierarchical Deterministic (HD) key creation and transfer protocol. In short, this protocol allows for the creation of a series of seemingly independent Bitcoin private keys and addresses from a single seed.
With Reusable Payment Codes, the sender sends a so-called “extended public key” to the receiver through an otherwise normal transaction. With this extended public key and the (“stealth”) public key as published by the receiver, the sender is able to generate a series of Bitcoin addresses to send bitcoins to. The receiver, meanwhile, can use this extended public key to combine it with his own (“stealth”) private key to generate the corresponding Bitcoin private keys.
As such, the sender can send an almost unlimited amount of transactions to the receiver, to addresses that can only be “linked together” by the sender and the receiver. Onlookers will see normal Bitcoin transactions ‒ not knowing they all go to the same receiver; all while the receiver hasn’t published any of them anywhere.
However, since light wallets don’t monitor the blockchain, the initial “notification” transaction to serve as a “piggy back” for the seed-data is recognizable, as such, to the outside world. This might reveal who is transacting if the addresses can be linked to real-world identities. Even then, it would reveal only who is transacting; not how much or on which subsequent addresses.
Thanks to Martijn Meijering, Justus Ranvier, and Blockstream president Adam Back for info and feedback.