Author

Topic: Reusable Payment Codes: How to compute Payment Code from HD Wallet private key (Read 524 times)

member
Activity: 65
Merit: 16
I would like to extract the chain code from an extended private key (BIP32)
and compute the Payment code to implement Reusable Payment Codes (BIP47)

I will use the 2 test vectors from BIP32 mediawiki (HD Wallet):
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

Test Vector 1:

Code:
prvkey = xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi

base58Check to string hex:

Code:
prvkey = 0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35e77e9d71

from the serialization format info on the same page, I can extract:

Code:
chain code  : 873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508
private key : e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35

And I can calculate the public key:
Code:
public key  : 0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2
If I do the same with the pubkey (xpub...), I get the same chain code which is what I should obtain.

Test Vector 2:

Code:
prvkey = xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U

Code:
chain code : 60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689
private key: 4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e
public key : 03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7


The next step is to create the Payment Code:

I will follow BIP47 mediawiki (binary serialization):
https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki

1)    Byte 0: version. required value: 0x01
2)    Byte 1: features bit field. All bits must be zero except where specified elsewhere in this specification
          Bit 0: Bitmessage notification
          Bits 1-7: reserved
3)    Byte 2: sign. required value: 0x02 or 0x03
4)    Bytes 3 - 34: x value, must be a member of the secp256k1 group
5)    Bytes 35 - 66: chain code
6)    Bytes 67 - 79: reserved for future expansion, zero-filled unless otherwise noted

Test vector 1:

Code:
1) 01
2) 00
3) 03
4) 39a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2
5) 873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508
6) 00000000000000000000000000

Code:
string1 : 01000339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800000000000000000000000000

Base58 Serialization

checksum = SHA256(SHA256(string1))
checkSum = 20A4FA8F1BDFA6D0AC185F5F5F5DF9A50F5183C3492D2102038FCF7F5A83878F
checkSum = 20a4fa8f

version byte = 47

Code:
string1: 4701000339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080000000000000000000000000020a4fa8f

string hex to base58Check :
Code:
PaymentCode: PM8TJZZ58ujgBFcwn2ii56ZDPVBmRTXqNBgqaRPhrqEaooQYKgsAUMkjmaXybz4zpMNVwgXSndvNNz7WTxFayVfbQQBCRroXqiN8tGMvJt9PaTwADf5Y


for test vector 2:

Code:
PaymentCode: PM8TJganX13rAQB9ZwomHFc8y8k8SoKJrgywreocjKE27Zjg3W72QVnyryaZzjknJXB7czkEufZC8QdRirThhETbQ4yCRb5QfGx1xYnn8ULN6URxrxox

I would like to know if those Payment Codes are correct.
Jump to: