Skip to content

BIP47 informal technical description

dimxy edited this page Sep 10, 2021 · 9 revisions

BIP47 Spec 'Reusable Payment Codes for Hierarchical Deterministic Wallets', How it Works

BIP47 is an extension of the BIP32 standard for hierarchical wallets.

BIP32 specification allows for a wallet app user to create many key pairs deterministically derived from the parent key pair stored in the wallet. This is needed to increase privacy in blockchain by not reusing addresses in transactions. BIP32 is good to generate addresses for transaction change but it is not clear how to allow for your partners who send you coins make such addresses (without disclosing the master xpub public key).

BIP47 spec solves the above problem by using the 'payment codes' concept. Its idea is to establish a secure channel between parties (Alice and Bob) by exchanging payment codes using which they could generate deterministically new destination pubkeys (and addresses) for each new transaction. This secure channel is set by generating a shared secret key with ECDH algorithm (Diffie-Hellman key exchange). This shared secret key is used by Alice to securely send her payment code to Bob. Both parties use the extended pubkeys from other party's payment code and their corresponding privkeys to derive new pubkeys (addresses) for transactions. As the extended pubkey in the payment code is unique for each pair of partners, knowing the extended pubkey for one pair won't allow to trace pubkeys for another users' pair (in comparison to BIP32 where a single parent xpub in a wallet is used to derive each child pubkey and if it's lost this would allow to trace all keys decreasing privacy).

This secure channel occurs in the blockchain by sending a transaction with data in the OP_RETURN output to a special notification address (obtained from the Bob's payment code).

Notes that PaymentCode derivation path starts from m/47/... so it won't overlap with BIP32 HD wallet path.

What is ECDH (Elliptic Curve Diffie-Hellman algorithm)? ECDH allows to generate a shared secret for two key pairs (this is a basic feature of the sec256k1 library existing in all bitcoin-based chains). Alice needs her private key and Bob's pubkey and Bob respectively needs his private key and Alice's pubkey. With this info they can create the same shared key on both sides, each doing this locally, without exchanging any other messages over the net.

How BIP47 protocol works to establish a secure channel between Alice and Bob for sending transactions

A payment code actually contains components of an extended pubkey which is used to derive new pubkeys.

Initially Alice gets Bob's payment code off-the-chain and this is out of the scope of the payment protocol.

The next task is to securely transfer Alice's payment code to Bob. As Alice has Bob's payment code she can make up Bob's notification address from it. She also obtains Bob's pubkey from his payment code and generates the ECDH secret shared key for their two key pairs. Alice sends her payment code obscured with the shared secret key (actually not encrypted but xor-ed it) in the transaction. When Bob receive this transaction on his notification address he obtains Alice pubkey from the transaction's first input and also is able to generate the same secret key to retrieve Alice's payment code (by xor-ing with the secret key).

Now both Alice and Bob have each other's payment code and they can use the pubkey from it to derive pubkeys (and addresses) for new transactions occurring between both of them. Obviously they both must remember the xpriv for his/her payment codes.

To create the next n-th transaction with coins to Bob, Alice selects the next unused n-th pubkey derived from Bob's payment code (by arbitrary child key indexing schema). However she does not directly use this next derived pubkey (seems this could be done an outsider too). Instead she makes a shared secret value from that selected Bob's pubkey and her privkey (again using ECDH). The same shared value is obtained by Bob with Alice pubkey from her payment code and his next n-th privkey. From the secret value a scalar value is calculated by both parties (by hashing) and is used to derive an ephemeral pubkey from Bob's selected pubkey, that is, an actual destination for the transaction sending coins.

This is kind of a unidirectional channel.

To send transactions back from Bob to Alice the process is the same: Bob first sends a notification transaction to Alice's notification address to inform Alice about his payment code.

They both use the wallet's BIP32 master key to create payment codes and keys for the secure channel and the master key could be kept private.

Some details how key derivation is done at low level

Derivation of a pubkey/privkey from another privkey/pubkey is done by two lib functions secp256k1_ec_privkey_tweak_add and secp256k1_ec_pubkey_tweak_add which add to a privkey and pubkey respectively some scalar value (in BIP32 it is obtained from the chain code and child key number). These functions guarantee that if the same value is added to the privkey and pubkey from a key pair those tweaked privkey and pubkey would form a new valid key pair.

My questions

BIP47 states that initially Alice gets Bob's payment code and how this is done is out of scope of the payment protocol. This is not quite well explained in BIP47. Could Bob publish his payment code on a web page or he must pass it to Alice securely off chain? If it is published then Bob's pubkey is revealed. Could derived keys be tracked then? But probably it can be published, because to derive the next pubkey not only Bob's pubkey is needed but also a secret value used to tweak Bob's pubkey.

Clone this wiki locally