Progress pill
Understanding the challenges of other advanced confidentiality techniques

BIP47 and reusable payment codes

Privacy on Bitcoin

BIP47 and reusable payment codes

  • General principle of BIP47 and PayNym
  • The reusable payment code
  • Diffie-Hellman key exchange on elliptic curves (ECDH)
  • The notification transaction
  • The BIP47 confidentiality model
  • Building the notification transaction
  • Transaction notification: a practical study
  • What is XOR?
  • Receipt of notification transaction
  • The BIP47 payment transaction
  • Receipt of BIP47 payment and derivation of private key
  • Refund of BIP47 payment
As we saw in Part 3, address reuse is a significant obstacle to user confidentiality in the Bitcoin protocol. To mitigate these risks, it is strongly recommended to generate a blank receiving address for each new payment received in a wallet. Although generating a new address is now simplified by the use of modern software and hierarchical deterministic wallets, this practice may seem counterintuitive.
In the traditional banking system, for example, we are used to sharing our IBAN, which always remains the same. Once we've given it to someone, they can send us multiple payments without having to interact with us again. Neo-banks also offer more modern possibilities, such as using unique email addresses on PayPal or Revolut's RevTags. Even outside the financial sphere, our everyday identifiers, such as our postal address, telephone number, and email address, are also unique and permanent. We don't have to renew them for each new interaction.
However, Bitcoin works differently: a new receiving address must be generated for each incoming transaction. This compromise between ease of use and confidentiality goes back to the very origins of Bitcoin's White Paper. As early as the publication of the first version of his document at the end of 2008, Satoshi Nakamoto was already alerting us to this risk:
As an additional firewall, a new key pair could be used for each transaction to keep them unlinked to a common owner.
There are several ways to receive multiple payments using a single identifier without needing to reuse an address. Each has its own trade-offs and drawbacks. Among these methods is BIP47, a proposal developed by Justus Ranvier and published in 2015. This proposal aims to create reusable payment codes that enable multiple transactions to be carried out against the same person, while avoiding address reuse. In short, BIP47 aims to offer a payment system as intuitive as a unique identifier, while preserving the confidentiality of transactions.
BIP47 does not directly improve user confidentiality, as a BIP47 payment offers the same level of confidentiality as a classic Bitcoin transaction using blank addresses. However, it does make using Bitcoin more convenient and intuitive, an ease that would normally compromise confidentiality. Thanks to BIP47, this ease of use achieves the same level of confidentiality as a classic transaction. That's why BIP47 is such a valuable tool for preserving privacy.
Initially, BIP47 was proposed for integration into Bitcoin Core, but was never actually implemented. However, some software applications chose to implement it on their own. For example, the Samourai Wallet team has developed its own implementation of BIP47, called "PayNym".

General principle of BIP47 and PayNym

The aim of BIP47 is to enable the receipt of a large number of payments without reusing addresses. It is based on the use of a reusable payment code, which enables different issuers to send several payments to a single code belonging to another user. As a result, the recipient does not have to provide a new, blank address for each transaction, which greatly facilitates exchanges while preserving confidentiality.
A user can therefore share their payment code with complete freedom, whether on social networks or on their website, without risking any loss of confidentiality, unlike with a conventional recipient address or public key.
To carry out a transaction, both parties must have a Bitcoin wallet implementing BIP47, such as PayNym on Ashigaru or Sparrow Wallet. The combined use of their payment codes creates a secret channel between them. To establish this channel effectively, the sender must perform a specific transaction on the Bitcoin blockchain, known as a “notification transaction” (I will provide further details later).
Combining the payment codes of the two users generates shared secrets, which in turn create a large number of unique Bitcoin receiving addresses (exactly 2^32, or around 4 billion). In this way, payments made via BIP47 are not actually addressed to the payment code itself, but rather to classic receipt addresses derived from the payment codes of the users involved.
The payment code thus serves as a virtual identifier derived from the wallet seed. In the wallet's hierarchical derivation structure, the payment code is positioned at level 3, i.e., at the account level.
The derivation target for BIP47 is identified by the index 47' (0x8000002F), which refers to BIP47. An example of a derivation path for a reusable payment code would be as follows:
m/47'/0'/0'/
To give you an idea of what a payment code looks like, here's mine:
PM8TJSBiQmNQDwTogMAbyqJe2PE2kQXjtgh88MRTxsrnHC8zpEtJ8j7Aj628oUFk8X6P5rJ7P5qDudE4Hwq9JXSRzGcZJbdJAjM9oVQ1UKU5j2nr7VR5
This code can also be encoded as a QR code, making it easier to communicate, just like a conventional address.
Regarding PayNym Bots, those bots sometimes seen on X (Twitter), they are visual representations of the payment code created by Samourai Wallet. With Ashigaru, they are now slightly different, but the principle remains the same. They are generated through a hashing function, which grants them near-uniqueness. They appear as a small string of characters beginning with + :
+throbbingpond8B1 +twilightresonance487 +billowingfire340
These avatars can also be represented as images:
Although these robots have no specific technical functionality within the BIP47 framework, they do play a role in facilitating user interaction by offering an easily recognizable visual identity.

In the following sections of this chapter dedicated to BIP47, we'll take a detailed look at how it works, with particular emphasis on the cryptographic methods used. To fully grasp these somewhat technical explanations, it's essential to first understand the structure of HD wallets, key derivation procedures and the fundamentals of elliptic curve cryptography. If you'd like to delve deeper into these concepts, another free course is available on Plan ₿ Academy:
I'd still advise you to follow them, because understanding the technical operation of BIP47 will make it much easier for you to understand other, similar proposals, which we'll discuss in the following chapters

The reusable payment code

As mentioned earlier, the reusable payment code is located at depth 3 of the HD wallet, making it comparable to an xpub, in terms of both its position in the wallet structure and its role.
The 80-byte payment code breaks down as follows:
  • Byte 0: The version. For the first version of BIP47, this byte is set to 0x01.
  • Byte 1: The bit field. This space is reserved for integrating additional indications for specific uses. For classic PayNym use, this byte is set to 0x00.
  • The 2 byte: The parity of y. This byte is 0x02 or 0x03, indicating whether the ordinate of the public key is even or odd, as a compressed public key is used.
  • From byte 3 to byte 34: The value of x. These bytes represent the abscissa of the public key. The concatenation of x and the parity of y forms the complete compressed public key.
  • From byte 35 to byte 66: The string code. This space contains the string code associated with the public key.
  • From byte 67 to byte 79: The padding. This space is intended for possible future evolutions. For the current version, we simply place zeros here to reach the 80-byte size required for OP_RETURN output.
Here is the hexadecimal representation of my reusable payment code already presented in the previous section:
0x010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000
Next, the P prefix byte must be added at the beginning to clearly indicate that this is a payment code. This byte is represented by 0x47:
0x47010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000
Finally, to ensure the integrity of the payment code, a checksum calculation is performed using HASH256, which consists of a double hash using the SHA256 function. The first four bytes of this hash are then concatenated at the end of the payment code:
0x47010002a0716529bae6b36c5c9aa518a52f9c828b46ad8d907747f0d09dcd4d9a39e97c3c5f37c470c390d842f364086362f6122f412e2b0c7e7fc6e32287e364a7a36a00000000000000000000000000567080c4
Once these steps have been completed, the payment code is ready. All that remains is to convert it to base 58 to obtain the final version:
PM8TJSBiQmNQDwTogMAbyqJe2PE2kQXjtgh88MRTxsrnHC8zpEtJ8j7Aj628oUFk8X6P5rJ7P5qDudE4Hwq9JXSRzGcZJbdJAjM9oVQ1UKU5j2nr7VR5
In the process of creating the payment code, we use a compressed public key and a string code. Both are derived deterministically and hierarchically from the wallet seed. The derivation path used to achieve this is:
m/47'/0'/0'/
In concrete terms, to generate the compressed public key and string code associated with the reusable payment code, we start by calculating the master private key from the wallet seed. We then proceed to derive a pair of daughter keys using the index 47 + 2^31 (hardened derivation). This is followed by two further successive derivations of daughter pairs, each using the index 2^31 (hardened derivation).

Diffie-Hellman key exchange on elliptic curves (ECDH)

The cryptographic protocol at the heart of BIP47 is known by the acronym ECDH, for Elliptic-Curve Diffie-Hellman. This method is a variant of the original Diffie-Hellman key exchange.
Introduced in 1976, the Diffie-Hellman key agreement protocol enables two parties, each equipped with a key pair (public and private), to agree on a common secret even when communicating only via a public, unsecured channel.
This shared secret (in this case, the blue key) can then be used for other operations. Typically, this shared secret can be used to encrypt and decrypt a communication on an unsecured network:
To achieve this, Diffie-Hellman uses modular arithmetic to calculate the shared secret. Here's how it works in layman's terms:
  • Alice and Bob agree on a common color, in this case yellow, which is public data (the attackers know this color).
  • Alice selects a secret color, in this case red, and mixes the two to obtain orange.
  • Bob also chooses a secret color, in this case blue, and mixes it with yellow to obtain green.
  • They then exchange the resulting colors, orange and green. This exchange can take place on an insecure network and be observed by attackers.
  • By mixing Bob's green with her own secret color, Alice produces brown.
  • Bob, doing the same with Alice's orange and secret blue, also obtains brown.
In this analogy, the color brown represents the secret shared by Alice and Bob. Imagine that, in reality, it's impossible for the attacker to separate the colors orange and green, in order to find Alice's or Bob's secret colors.
Now let's take a look at how this protocol actually works, not with color analogies, but using real numbers and modular arithmetic!
Before we get into the Diffie-Hellman mechanisms, let me briefly remind you of two essential mathematical concepts we'll need:
  • A prime number is a natural number that has only two divisors: and itself. For example, is a prime number because it can only be divided by and . On the other hand, is not a prime number, since it is divisible by , , , and . It therefore has four positive integer divisors instead of two.
  • The modulo (noted or ) is a mathematical operation which, between two integers, returns the remainder of the Euclidean division of the first by the second. For example, 1$.
The Diffie-Hellman key exchange between Alice and Bob takes place as follows:
  • Alice and Bob agree on two common numbers: and . is a prime number, and the larger the value of , the more secure the Diffie-Hellman algorithm will be. is a primitive root of . These two numbers can be communicated openly on an unsecured network. They represent the equivalent of the color yellow in the previous analogy. It is therefore important that Alice and Bob use exactly the same values for and .
  • Once these parameters have been defined, Alice and Bob each choose a secret random number. Alice names her secret random number (equivalent to the color red) and Bob names his (equivalent to the color blue). These numbers must remain secret.
  • Instead of directly exchanging the numbers and , each party calculates and as follows:
is equal to raised to the power modulo :
is equal to raised to the power modulo :
  • The values (equivalent to the color orange) and (equivalent to the color green) are exchanged between the two parties. This exchange can take place in clear text on an unsecured network.
  • Alice, having received , calculates the value of as follows:
is equal to raised to the power modulo :
A reminder:
The result is:
By applying the power rules:
The result is:
  • From his side, Bob, having received , also calculates the value of as follows:
is equal to raised to the power modulo :
The result is:
Thanks to the distributivity of the modulo operator, Alice and Bob obtain exactly the same value . This number represents their common secret, equivalent to the color brown in the previous analogy with paint cans. They can now use this common secret to symmetrically encrypt their communications over an unsecured network.
An attacker, even in possession of , , , and (the public values), won't be able to calculate , , or (the private values). To achieve this, the exponentiation would have to be reversed, an operation that is impossible without trying all the possibilities one by one, as it amounts to calculating the discrete logarithm, i.e., the reciprocal of the exponential in a finite cyclic group.
So, as long as the values of , , and are large enough, the Diffie-Hellman protocol is secure. Typically, with parameters of 2048 bits (a 600-digit decimal number), testing all possibilities for and would be impractical. To date, with such numbers, this algorithm is considered secure.
Herein lies the main drawback of the Diffie-Hellman protocol. To be secure, the algorithm must use large numbers. That's why, these days, we prefer to use the ECDH (Elliptic Curve Diffie-Hellman) algorithm, a variant of Diffie-Hellman based on an algebraic curve, specifically an elliptic curve. This approach enables working with significantly smaller numbers while maintaining equivalent security, thereby reducing the resources required for calculation and storage.
The general principle of the algorithm remains the same. However, instead of using a random number and a number calculated from by modular exponentiation, we use a pair of keys established on an elliptic curve. Instead of relying on the distributivity of the modulo operator, we use the group law on elliptic curves, and more precisely, the associative property.
To briefly explain the principle of cryptography on elliptic curves, a private key is represented by a random number between and , where represents the order of the curve. The public key, on the other hand, is a specific point on this curve, obtained from the private key by adding and doubling points from the generating point, according to the equation:
In this formula, designates the public key, the private key, and the generator point.
An essential feature of these keys is the ease with which can be calculated from and , while it is virtually impossible to find from and . This asymmetry creates a one-way function. In other words, it's easy to calculate the public key if you know the private key, but retrieving the private key from the public key is impossible. This security is further underpinned by the computational difficulty of the discrete logarithm.
We'll use this property to adapt our Diffie-Hellman algorithm. The ECDH operating principle is as follows:
  • Alice and Bob agree on a cryptographically secure elliptic curve and its parameters. This information is public.
  • Alice generates a random number , which will be her private key. This private key must remain secret. She determines her public key by adding and doubling points on the chosen elliptic curve:
  • Bob also generates a random number , which will be his private key. He calculates the associated public key :
  • Alice and Bob exchange their public keys and on an unsecured public network.
  • Alice calculates a point on the curve by applying her private key to Bob's public key :
  • Bob calculates a point on the curve by applying his private key to Alice's public key :
  • Alice and Bob obtain the same point on the elliptic curve. The shared secret will be the abscissa of this point.
They get the same shared secret because:
A potential attacker observing the unsecured public network will only be able to obtain the public keys of each individual and the parameters of the chosen elliptic curve. As explained above, this information alone is not sufficient to determine the private keys. Consequently, the attacker cannot find the secret shared between Alice and Bob.
ECDH is therefore a key exchange algorithm. It is often used in conjunction with other cryptographic methods to establish a complete protocol. For example, ECDH is at the heart of TLS (Transport Layer Security), an encryption and authentication protocol used for the Internet transport layer. TLS uses ECDHE for key exchange, a variant of ECDH where keys are ephemeral, to provide persistent confidentiality. Additionally, TLS utilizes authentication algorithms, such as ECDSA, encryption algorithms, including AES, and hash functions, like SHA-256.
TLS is responsible for the s in https and the padlock in your browser's address bar - symbols of encrypted communications. By taking this course, you'll be using ECDH, and it's highly likely that you'll be using it on a daily basis without even knowing it.

The notification transaction

As we saw in the previous section, ECDH is a variant of the Diffie-Hellman exchange using key pairs established on an elliptic curve. It's a good thing we already have many key pairs that respect this standard in our Bitcoin wallets. The idea of BIP47 is to use the key pairs of both parties' hierarchical deterministic Bitcoin wallets to establish shared, ephemeral secrets between them. BIP47 uses ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) instead.
ECDHE is first used in BIP47 to transmit the payment code from the sender to the recipient. This is the famous notification transaction. This step is essential because for BIP47 to work effectively, parties involved (sender and receiver) need to know each other's payment codes. This knowledge enables the derivation of ephemeral public keys and, consequently, the associated blank receiving addresses.
Prior to this exchange, the sender is logically already aware of the recipient's payment code, having retrieved it off-chain, for example, from their website, invoice, or social networks. However, the recipient is not necessarily aware of the sender's payment code. However, the code must be transmitted to him; otherwise, he won't be able to derive the ephemeral keys needed to identify the addresses where his bitcoins are stored or access his funds. Although this transmission of the sender's code can technically be carried out off-chain by other means of communication, this poses a problem if the wallet is to be retrieved from the seed only.
This is because, unlike conventional addresses, BIP47 addresses are not derived directly from the recipient's seed - using an xpub would be simpler in this case - but rather result from a calculation combining the two payment codes: those of the sender and the recipient. Therefore, if the recipient loses their wallet and attempts to restore it from their seed, they will recover their own payment code, which is directly derived from their seed. However, to recover ephemeral addresses, he will also need the payment codes of all those who have sent him bitcoins via BIP47. Hence, the importance of the notification transaction lies in its ability to save this information on the Bitcoin blockchain, while still allowing it to be easily retrieved without requiring a search through the billions of transactions executed since its launch in 2009.
It would therefore be possible to implement BIP47 without using the notification transaction, provided that each user keeps a backup of their peers' payment codes. However, this method proves complex to manage until a simple, robust, and efficient solution for making, storing, and updating these backups is developed. As things stand, the notification transaction is almost unavoidable.
In the following chapters, however, we will look at other protocols with similar objectives to BIP47, but which do not require a notification transaction. These alternatives do, however, introduce their own trade-offs.
In addition to its role of saving payment codes, the notification transaction also has a notification function for the recipient, as its name suggests. It alerts the recipient's customer to the fact that a new payment tunnel has been established and suggests that they monitor the resulting ephemeral addresses.

The BIP47 confidentiality model

Before detailing the technical operation of the notification transaction, it is important to discuss the confidentiality model associated with BIP47, which justifies certain measures taken when creating this initial transaction.
The payment code itself does not present a direct risk to confidentiality. Unlike the traditional Bitcoin model, which aims to break the link between the user's identity and their transactions (which are public) by preserving the anonymity of keys and addresses, the payment code can be openly associated with an identity without posing a threat.
This is because the payment code is not used to directly derive the addresses receiving BIP47 payments. Instead, these addresses are generated via the ECDH application between the keys derived from the payment codes of the two parties involved.
Thus, a payment code in itself does not directly lead to a loss of confidentiality, since only the notification address is derived from it. Although this address can reveal certain information, it typically does not disclose the parties with whom you are transacting, unless a thorough chain analysis is conducted. Indeed, if the sender uses UTXOs that can be linked to his identity to carry out the notification transaction, then it becomes possible to deduce that his identity is probably linked to BIP47 payments to your payment code. This will not reveal the underlying transactions, but will indicate their likely existence.
It is therefore essential to maintain this strict separation between users' payment codes. With this in mind, the initial communication of the code is a critical moment for payment confidentiality, yet one that is essential for the protocol to function correctly. If one of the payment codes can be obtained publicly (as on a website), the second code, that of the sender, must under no circumstances be linked to the first.
Let's take a concrete example: I want to make a donation to a political movement via BIP47:
  • The organization has made its payment code public on its website or via its social networks.
  • This code is therefore linked to the political movement.
  • I get this payment code.
  • Before sending, I have to make sure they know my own payment code, which is also linked to my identity since I use it to receive transactions on my social networks.
How can I pass on my code without risk? Using conventional means of communication could lead to information leakage, and thus associate me with this political movement. The notification transaction offers a solution, thanks to a layer of encryption that prevents just such an association between two codes. Although it's not the only method of secretly transmitting the sender's payment code, it's a very effective one.
In the diagram below, the orange lines indicate the points where the flow of information must be interrupted, and the black arrows show the connections potentially observable by third parties:
In reality, Bitcoin's traditional confidentiality model often makes it complex to completely dissociate the flow of information between the key pair and the user, especially in remote transactions. For example, in the context of a donation campaign, the recipient must inevitably disclose an address or public key on their website or social networks. The correct use of BIP47, particularly with the notification transaction, enables a solution to this problem through ECDHE and the encryption layer we examine later.
Of course, Bitcoin's classic confidentiality model still applies to ephemeral public keys, which are derived from the combination of the two payment codes. The two models are, in fact, complementary. What I want to emphasize here is that, unlike the usual use of a public key to receive Bitcoins, the payment code can be linked to a specific identity, as the information "Alice is transacting with Bob" is broken at another stage. The payment code is used to generate payment addresses, but based solely on observation of the blockchain, it is impossible to link a BIP47 payment transaction to the payment codes used to execute it, unless the UTXOs involved were already linked to an identity previously, and the users associated their payment codes with their respective identities.
To sum up, the confidentiality model offered by BIP47 payments could be considered superior to Bitcoin's basic model, although this doesn't mean it's magic.

Building the notification transaction

Now let's see how this notification transaction works. Let's imagine that Alice wishes to send funds to Bob using BIP47. In my example, Alice acts as the sender and Bob as the receiver. Bob has published his payment code on his website. Alice, therefore, already knows Bob's payment code.
1- Alice calculates a shared secret with ECDH:
  • She selects a key pair from her HD wallet on a different branch from her payment code. Note that this pair must not be easily associated with Alice's notification address, nor with Alice's identity (see previous section);
  • Alice selects the private key for this pair. We call it (lowercase);
  • Alice retrieves the public key associated with Bob's notification address. This key is the first child derived from Bob's payment code (index ). We refer to this public key as (uppercase). The private key associated with this public key is denoted as (lowercase). is determined by adding and doubling points on the elliptic curve from (the generating point) with (the private key):
  • Alice calculates a secret point (uppercase) on the elliptic curve by adding and doubling points, applying her private key from Bob's public key .
  • Alice calculates the blinding factor that will be used to encrypt her payment code. To achieve this, she utilizes the HMAC-SHA512 function to generate a pseudo-random number. The second input to this function is a value that only Bob will be able to find: , which is the abscissa of the secret point calculated above. The first input is , which is the UTXO consumed as input to this transaction (outpoint).
2 - Alice converts her personal payment code to base 2 (binary)
3- She uses this blinding factor as a key to perform symmetrical encryption on the payload of her payment code. The encryption algorithm used is simply an XOR. The operation performed is comparable to the Vernam cipher, also known as the "One-Time Pad."
  • Alice first splits her blinding factor in two: the first 32 bytes are named and the last 32 bytes are named . This gives us:
  • Alice calculates the cipher of the abscissa of the public key of her payment code, and the cipher of her string code separately. and act as cipher keys, respectively. The operation used is XOR (or exclusive).
  • Alice replaces the real values of the public key abscissa and the string code in her payment code with the encrypted values and .
4- Alice therefore currently has her payment code with an encrypted payload. She will construct and broadcast a transaction involving her public key as input, an output to Bob's notification address, and an output OP_RETURN consisting of her payment code with the encrypted payload. This transaction serves as the notification transaction.
An OP_RETURN is an opcode that marks the output of a Bitcoin transaction as invalid. Today, it is used to broadcast or anchor information on the Bitcoin blockchain. It can store up to 80 bytes of data, which is then written to the chain and visible to all other users.
As we have seen in previous sections, ECDH is used to generate a shared secret between two users communicating over an insecure network, which may be potentially observed by attackers. In BIP47, ECDH is used to communicate on the Bitcoin network, which, by its very nature, is a transparent communication network and is observed by many attackers. The shared secret calculated through the ECDH key exchange is then used to encrypt the secret information to be transmitted, specifically the sender's payment code (Alice).
I'll summarize the steps we've just seen together to carry out a notification transaction:
  • Alice retrieves Bob's payment code and notification address.
  • Alice selects a UTXO from her HD wallet with the corresponding key pair.
  • She calculates a secret point on the elliptic curve using ECDH.
  • She uses this secret point to calculate an HMAC, which is the blinding factor.
  • She uses this blinding factor to encrypt the payload of her personal payment code.
  • She uses a OP_RETURN transaction output to communicate the hidden payment code to Bob.

Transaction notification: a practical study

To understand how it works in more detail, particularly the use of OP_RETURN, let's examine a real notification transaction. I carried out such a transaction on the testnet, which you can find by clicking here.
Looking at this transaction, we can already see that it has a single input and 4 outputs:
  • The first output is the OP_RETURN, which contains my hidden payment code.
  • The second output of 546 sats points to my recipient's notification address.
  • The third output of 15,000 sats represents the service fee, as I used Samourai Wallet to build this transaction.
  • The fourth output of 2 million sats represents the change, i.e., the remaining difference in my input, which returns to another address belonging to me.
The most interesting to study is obviously output 0 using OP_RETURN. Let's take a closer look at what it contains. Here's the scriptPubKey in hexadecimal:
6a4c50010002b13b2911719409d704ecc69f74fa315a6cb20fdd6ee39bc9874667703d67b164927b0e88f89f3f8b963549eab2533b5d7ed481a3bea7e953b546b4e91b6f50d800000000000000000000000000
This script consists of several parts. Firstly, the:
6a4c
Among the opcodes, we can recognize 0x6a, which designates the OP_RETURN, and 0x4c, which designates the OP_PUSHDATA1.
The byte following this last opcode indicates the size of the subsequent payload. It indicates 0x50, or 80 bytes:
6a4c50
Next, we have the metadata of my payment code in clear text:
010002
The encrypted abscissa of the public key of my payment code:
b13b2911719409d704ecc69f74fa315a6cb20fdd6ee39bc9874667703d67b164
The encrypted string code of my payment code:
927b0e88f89f3f8b963549eab2533b5d7ed481a3bea7e953b546b4e91b6f50d8
And finally, padding to 80 bytes, the standard size of an OP_RETURN:
00000000000000000000000000
To help you understand, here is my payment code in plain text in base 58:
PM8TJQCyt6ovbozreUCBrfKqmSVmTzJ5vjqse58LnBzKFFZTwny3KfCDdwTqAEYVasn11tTMPc2FJsFygFd3YzsHvwNXLEQNADgxeGnMK8Ugmin62TZU
And in base 16:
4701000277507c9c17a89cfca2d3af554745d6c2db0e7f6b2721a3941a504933103cc42add94881210d6e752a9abc8a9fa0070e85184993c4f643f1121dd807dd556d1dc000000000000000000000000008604e4db
If we compare my plaintext payment code with the OP_RETURN, we can see that the HRP (0x47) and the checksum (0x8604e4db) are not transmitted. This is normal, as this information is intended for humans.
Next, we can recognize the version (0x01), the bit field (0x00), and the parity of the public key (0x02). And, at the end of the payment code, the empty bytes (0x000000000000000000000000000000) allow padding to reach a total of 80 bytes. All this metadata is transmitted unencrypted.
Finally, we can observe that the public key abscissa (0x77507c9c17a89cfca2d3af554745d6c2db0e7f6b2721a3941a504933103cc42a) and the string code (0xdd94881210d6e752a9abc8a9fa0070e85184993c4f643f1121dd807dd556d1dc) have been encrypted. This is the payload of the payment code.

What is XOR?

We have seen in previous sections that the payment code is transmitted encrypted using the XOR operation. Let's take a closer look at how this operator works, as it is widely used in cryptography.
XOR is a bitwise logical operator based on Boolean algebra. Given two operands in bits, it returns 1 if the bits of the same rank are different, and it returns 0 if the bits of the same rank are equal. Here's the XOR truth table according to the values of the operands D and E:
DED XOR E
000
011
101
110
For example:
Or:
With ECDH, the use of XOR as an encryption layer is particularly consistent. Firstly, thanks to this operator, encryption is symmetrical. This means that the recipient can decrypt the payment code with the same key used for encryption. The encryption and decryption keys are calculated from the shared secret using ECDH. This symmetry is made possible by the commutativity and associativity properties of the XOR operator:
  • Other properties:
  • Commutativity:
  • Associativity:
If:
Then:
Secondly, this encryption method is very similar to the Vernam (One-Time Pad) cipher, the only encryption algorithm known to date that has unconditional (or absolute) security. For Vernam's cipher to have this feature, the encryption key must be perfectly random, of the same size as the message, and used only once. In the encryption method used here for BIP47, the key is indeed the same size as the message, and the blinding factor is exactly the same size as the concatenation of the abscissa of the public key with the string code of the payment code. This encryption key is used only once. On the other hand, this key is not derived from perfect randomness, since it is an HMAC. Rather, it is pseudo-random. So, it's not a Vernam cipher, but the method is similar.

Receipt of notification transaction

Now that Alice has sent the notification transaction to Bob, let's see how Bob interprets it. As a reminder, Bob must have access to Alice's payment code. Without this information, as we'll see in the next section, he won't be able to derive the key pairs created by Alice, and therefore won't be able to access his bitcoins received via BIP47. For the moment, Alice's payment code payload is encrypted. Let's see how Bob decrypts it.
1- Bob monitors transactions that create outputs with his notification address.
2- When a transaction has an output on its notification address, Bob analyzes it to see if it contains an OP_RETURN output that complies with the BIP47 standard.
3- If the first byte of the OP_RETURN payload is 0x01, Bob begins his search for a possible secret shared with ECDH:
  • Bob selects the input public key for the transaction. That is, Alice's public key named with:
  • Bob selects the private key associated with his personal notification address:
  • Bob calculates the secret point (shared secret ECDH) on the elliptic curve by adding and doubling points, applying his private key to Alice's public key :
  • Bob determines the blinding factor that will enable the payload of Alice's payment code to be decrypted. In the same way as Alice had calculated it previously, Bob will find by applying HMAC-SHA512 to , the abscissa value of the secret point , and to , the UTXO consumed as input to this notification transaction:
4- Bob interprets the OP_RETURN data in the notification transaction as a payment code. He will simply decrypt the payload of this potential payment code using the blinding factor:
  • Bob splits the blinding factor into 2 parts: the first 32 bytes of will be and the last 32 bytes will be ;
  • Bob decrypts the value of the encrypted abscissa from the public key of Alice's payment code:
  • Bob decrypts the value of the encrypted string code from Alice's payment code:
5- Bob checks whether the public key value of Alice's payment code is part of the secp256k1 group. If so, he interprets this as a valid payment code. If not, he ignores the transaction.
Now that Bob knows Alice's payment code, Alice can send him up to 2^32 payments, without ever having to repeat a notification transaction of this type.
Why does it work? How can Bob determine the same blinding factor as Alice, and thus decipher her payment code? Let's take a closer look at ECDH's action in what we've just described.
First of all, we're dealing with symmetrical encryption. This means that the encryption key and the decryption key are the same value. This key in the notification transaction is the blinding factor:
Alice and Bob must therefore obtain the same value for , without transmitting it directly, since an attacker could steal it and decrypt the secret information. This blinding factor is obtained by applying HMAC-SHA512 to 2 values:
  • the abscissa of a secret point;
  • and the UTXO consumed at the transaction input.
Bob, therefore, needs both these pieces of information to decrypt Alice's payment code payload. For the input UTXO, Bob can simply retrieve it by observing the notification transaction. For the secret point, Bob will need to use ECDH. As seen in the previous section on Diffie-Hellman, simply by exchanging their respective public keys and secretly applying their private keys to each other's public key, Alice and Bob can find a precise secret point on the elliptic curve. The notification transaction is based on this mechanism:
  • Bob's pair of keys:
  • Alice's key pair:
  • For a secret :
Now that Bob knows Alice's payment code, he'll be able to detect her BIP47 payments and derive the private keys that block the bitcoins received.
I'll summarize the steps we've just seen together to receive and interpret a notification transaction:
  • Bob monitors transaction output to his notification address.
  • When he detects one, he retrieves the information contained in the OP_RETURN.
  • Bob selects the public key as input and calculates a secret point using ECDH.
  • He uses this secret point to calculate an HMAC, which is the blinding factor.
  • He uses this blinding factor to decrypt Alice's payment code payload contained in the OP_RETURN.

The BIP47 payment transaction

Let's examine the payment process using BIP47. To remind you of the current situation:
  • Alice knows Bob's payment code, which she simply retrieved from his website.
  • Bob knows Alice's payment code from the notification transaction.
  • Alice will make her first payment to Bob. She can make many more in the same way.
Before explaining this process, it's essential to recall the indexes we're currently working on. The derivation path for a payment code is described as follows: m/47'/0'/0'. The following depth divides the indexes as follows:
  • The first normal (non-reinforced) daughter pair is the one used to generate the notification address discussed in the previous section: m/47'/0'/0'/0;
  • Normal daughter key pairs are used within ECDH to generate BIP47 payment receipt addresses, as we will see in this section: from m/47'/0'/0'/0 to m/47'/0'/0'/2,147,483,647;
  • Reinforced daughter key pairs are ephemeral payment codes: from m/47'/0'/0'/0' to m/47'/0'/0'/2,147,483,647'.
Each time Alice wants to send a payment to Bob, she derives a new, unique, blank address, once again using the ECDH protocol:
  • Alice selects the first private key derived from her personal reusable payment code:
  • Alice selects the first unused public key derived from Bob's payment code. We'll call this public key . It is associated with the private key known only to Bob:
  • Alice calculates a secret point on the elliptic curve by adding and doubling points by applying her private key from Bob's public key :
  • From this secret point, Alice calculates the shared secret (lowercase). To do this, she selects the abscissa of the secret point named , and passes this value to the SHA256 hash function:
  • Alice uses this shared secret to calculate a Bitcoin payment reception address. First, she checks that is contained in the order of the secp256k1 curve. If this is not the case, she increments Bob's public key index to derive another shared secret.
  • In a second step, she calculates a public key by adding the points and on the elliptic curve. In other words, Alice adds the public key derived from Bob's payment code to another point calculated on the elliptic curve by adding and doubling points with the shared secret from the secp256k1 curve generator point . This new point represents a public key, and we call it :
  • With this public key , Alice can derive a blank receive address in the standard way (e.g., SegWit V0 in bech32).
Once Alice has obtained Bob's receiving address, she can carry out a Bitcoin transaction in the standard way. To do this, she chooses a UTXO she owns, secured by a key pair from a different branch of her HD wallet, and consumes it to satisfy an output to Bob's address. It's essential to note that, once the address has been derived, this payment follows a standard process and no longer relies on the keys associated with BIP47.
I'll summarize the steps we've just seen together to send a BIP47 payment:
  • Alice selects the first daughter private key derived from her personal payment code.
  • She calculates a secret point on the elliptic curve using ECDH from the first unused daughter public key derived from Bob's payment code.
  • She uses this secret point to calculate a shared secret with SHA256.
  • She uses this shared secret to calculate a new secret point on the elliptic curve.
  • She adds this new secret point to Bob's public key.
  • She obtains a new ephemeral public key for which only Bob has the associated private key.
  • Alice can make a classic transaction to Bob with the derived ephemeral receive address.
If Alice wants to make a second payment, she'll follow the same steps as before, except that this time she'll select the second public key derived from Bob's payment code. Specifically, she will use the next unused key. She will thus obtain a new receiving address belonging to Bob, designated :
She can continue in this way and derive up to 2^32 blank addresses belonging to Bob.
From an outside perspective, examining the blockchain, it is theoretically impossible to distinguish a BIP47 payment from a conventional payment. Here's an example of a BIP47 payment transaction on Testnet:
94b2e59510f2e1fa78411634c98a77bbb638e28fb2da00c9f359cd5fc8f87254
It looks like a classic transaction with a consumed input, a payment output, and a change UTXO:

Receipt of BIP47 payment and derivation of private key

Alice has just made her first payment to a blank BIP47 address belonging to Bob. Now let's see how Bob receives this payment. We'll also see why Alice doesn't have access to the private key of the address she's just generated herself, and how Bob finds this key to spend the bitcoins he's just received.
As soon as Bob receives the notification transaction from Alice, he derives the public key BIP47 even before his correspondent has sent a payment. He therefore observes any payment to the associated address. In fact, he immediately derives several addresses that he observes (, , , ...). Here's how it derives this public key :
  • Bob selects the first daughter private key derived from his payment code. This private key is named . It is associated with the public key with which Alice made her calculations in the previous step:
  • Bob selects Alice's first public key derived from her payment code. This key is named . It is associated with the private key with which Alice made her calculations, and which is known only to Alice. Bob can carry out this process, since he knows Alice's payment code, which was sent to him with the notification transaction:
  • Bob calculates the secret point , by adding and doubling points on the elliptic curve, by applying his private key to Alice's public key . Here again, ECDH is used to guarantee that this point will be the same for both Bob and Alice:
  • In the same way as Alice, Bob isolates the abscissa of this point . We've named this value . He passes this value to the SHA256 function to find the shared secret (lowercase):
  • In the same way as Alice, Bob calculates the point on the elliptic curve. He then adds this secret point to his public key . He then obtains a new point on the elliptic curve, which he interprets as a public key :
Once Bob has obtained this public key , he can derive the associated private key to spend his bitcoins. Only he can generate this private key:
  • Bob adds up his daughter private key derived from his personal payment code. Only he can obtain the value of . He then adds to the shared secret to obtain , 's private key:
Thanks to the group law of the elliptic curve, Bob obtains exactly the private key corresponding to the public key used by Alice. We therefore have:
I'll summarize the steps we've just seen together to receive a BIP47 payment and calculate the corresponding private key:
  • Bob selects the first daughter private key derived from his personal payment code.
  • He calculates a secret point on the elliptic curve using ECDH from the first daughter's public key derived from Alice's string code.
  • He uses this secret point to calculate a shared secret with SHA256.
  • He uses this shared secret to calculate a new secret point on the elliptic curve;
  • He adds this new secret point to his personal public key;
  • He obtains a new ephemeral public key, the one to which Alice will send her first payment;
  • Bob calculates the private key associated with this ephemeral public key by adding his daughter private key derived from his payment code and the shared secret.
Since Alice cannot obtain (Bob's private key), she is unable to determine (the private key associated with Bob's BIP47 receiving address). Schematically, we can represent the calculation of the shared secret as follows:
Once the shared secret is found with ECDH, Alice and Bob calculate the BIP47 payment public key , and Bob also calculates the associated private key :

Refund of BIP47 payment

Since Bob knows Alice's reusable payment code, he already has all the necessary information to send her a refund. He won't need to contact Alice again to ask for any information. He simply needs to notify her with a notification transaction, so that she can retrieve her BIP47 addresses with her seed, and then he can also send her up to 2^32 payments.
The refund feature is specific to BIP47 and is one of its advantages over other methods, such as Silent Payments, which we'll look at in later chapters.
Bob can then reimburse Alice in the same way she sent him payments. The roles are reversed:
Many thanks to Fanis Michalakis for his proofreading and expert advice on the article that inspired the writing of this chapter!
Quiz
Quiz1/5
What is the main goal of BIP47?