Skip to content

Instantly share code, notes, and snippets.

@fivepiece
Created January 13, 2017 19:36
Show Gist options
  • Save fivepiece/e3293733d99c4935332f8c5959d7472b to your computer and use it in GitHub Desktop.
Save fivepiece/e3293733d99c4935332f8c5959d7472b to your computer and use it in GitHub Desktop.
bip32 test vector 2:
seed : fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542
m : xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U
m/0 : xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt
m/0/42 : xprv9wSp6B7UBdybENFjzPMtDqKoddXxLZSijm538rhsNgSsnpD7VjcCc9XdzsBcWfS75TmeG27WLVsCEfaL7LzaEoNcKU8xUyzMqAS1DHHvTw6
m/0/42/2 : xprv9yidjfEMLNAmykgi1p3MVsP3huXJ17K55ywbpFSJYGUYJ5tTrz4aRJXMnUu4NJZVMTymi434adgFxfTwyr7YCQ3jQAaJiHNMd4uSR7bEXXE
---
# computing the xpriv at m/0 from the xpub M/0 and a child private key at a non-hardended depth of m/0/...
xpub M/0 : xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH
child_privkey : AE6FED23A05A225BBEAECF8705EA2A663FE04BF0D14490CC72708B257EC55905
# we find the pubkey of our known child private key
child_privkey * G = ( 6A62DFCC2CFC10275BC3D9829E89ACA828DB7A7421B42954D192191646F206EA ,
E239721203B9E9D44B8030B583E2365875C9A14BABC3053FA5D2AF9C83120CF1 )
compressed : 036A62DFCC2CFC10275BC3D9829E89ACA828DB7A7421B42954D192191646F206EA
# we have the public key, but we are missing the parent chain code and public key.
# we search the tree by deriving xpubs until we find an xpub that encodes our the compressed point.
# we find the xpub to be :
M/0/42/2 : xpub6Chz9AmFAjj5CEmB7qaMs1KnFwMnQa2vTCsCcdqv6c1XAtDcQXNpy6qqdmMbiTAXD9vG97XnQpPeZqFo7fR4rAio2RMWZ6JMBsWGsz5DuVk
# and naturally we figured out its parent :
M/0/42 : xpub6ASAVgeN21XtSrLD6QttayGYBfNSk2Aa6yzdwF7Uw1yrfcYG3GvT9wr7rA2gtmwbYgeJ1ShSvGxz4VP2xrsNtmxpWpC2qznwVyA8TJ3c1Nm
# we decode the xpubs and note the parent's chain code and pubkey, and the child private key's serialized index :
ser32_i(m/0/42/2) : 00000002 # (serialized child index)
parent_chain_code(M/0/42) : 076737C7331790248FEDF7C781B4BC19DEFB69AF9D15FA81886DDFA63BC357C2
parent_pubkey(M/0/42) : 0307F39C6950FC0CCFC1A9AC91CA362182F1D8CD1833B2AF4AEED9FC704BFED568
# to find the parent's private key from a child private key and the parent's chain code, we use hmac-sha512 and modular addition.
# first the hmac function :
# an hmac-sha512(parent_chain_code, parent_pubkey||child_index) is done :
hmac-sha512( 076737C7331790248FEDF7C781B4BC19DEFB69AF9D15FA81886DDFA63BC357C2 ,
0307F39C6950FC0CCFC1A9AC91CA362182F1D8CD1833B2AF4AEED9FC704BFED56800000002 )
==
959A6E6B519E835B93647D92B4BCCD7DB08B20F5AC0F5D591ABEF9AC2DCAC621E97BFC4B1CAF90729400B16AED1BBF8A65E76C230AC1E93E8132DEFD43F18A6E
# we take the first 32 bytes of the hash, call it I_L, and our child private key
I_L = 959A6E6B519E835B93647D92B4BCCD7DB08B20F5AC0F5D591ABEF9AC2DCAC621
child_privkey = AE6FED23A05A225BBEAECF8705EA2A663FE04BF0D14490CC72708B257EC55905
# we know that our known child private key was derived by simple addition mod n :
# parent_privkey + I_L = child_privkey % n
# we can re-arrange the above to be :
# parent_privkey = child_privkey - I_L % n
(AE6FED23A05A225BBEAECF8705EA2A663FE04BF0D14490CC72708B257EC55905 - 959A6E6B519E835B93647D92B4BCCD7DB08B20F5AC0F5D591ABEF9AC2DCAC621) % n
==
parent_privkey = 18D57EB84EBB9F002B4A51F4512D5CE88F552AFB2535337357B1917950FA92E4
# we find the pubkey for our returned value and check that the point matches the parent xpub's encoded pubkey
parent_privkey * G == 0307F39C6950FC0CCFC1A9AC91CA362182F1D8CD1833B2AF4AEED9FC704BFED568
# the point matches the parent xpub. now we can continue with m/0
# we know from our M/0/42 xpub :
ser32_i(M/0/42) : 0000002A
# we know from our M/0 xpub :
parent_chain_code(M/0) : F0909AFFAA7EE7ABE5DD4E100598D4DC53CD709D5A5C2CAC40E7412F232F7C9C
parent_pubkey(M/0) : 02FC9E5AF0AC8D9B3CECFE2A888E2117BA3D089D8585886C9C826B6B22A98D12EA
# and we found the private key for m/0/42 in the previous step :
child_privkey : 18D57EB84EBB9F002B4A51F4512D5CE88F552AFB2535337357B1917950FA92E4
# we can do the same trick :
hmac-sha512( F0909AFFAA7EE7ABE5DD4E100598D4DC53CD709D5A5C2CAC40E7412F232F7C9C ,
02FC9E5AF0AC8D9B3CECFE2A888E2117BA3D089D8585886C9C826B6B22A98D12EA0000002A )
==
6CEE341F57F3B4414B07C2A0D79E522E9FE8346960E4436DA7477BD70B845607076737C7331790248FEDF7C781B4BC19DEFB69AF9D15FA81886DDFA63BC357C2
I_L = 6CEE341F57F3B4414B07C2A0D79E522E9FE8346960E4436DA7477BD70B845607
child_privkey = 18D57EB84EBB9F002B4A51F4512D5CE88F552AFB2535337357B1917950FA92E4
(18D57EB84EBB9F002B4A51F4512D5CE88F552AFB2535337357B1917950FA92E4 - 6CEE341F57F3B4414B07C2A0D79E522E9FE8346960E4436DA7477BD70B845607) % n
==
parent_privkey = ABE74A98F6C7EABEE0428F53798F0AB8AA1BD37873999041703C742F15AC7E1E
parent_privkey * G == 02FC9E5AF0AC8D9B3CECFE2A888E2117BA3D089D8585886C9C826B6B22A98D12EA
# we now have the private key for the path m/0
# since we also have the xpub, we can easily encode the xpriv
# decoded, the xpub is :
0488B21E # magic (xpub)
01 # depth
BD16BEE5 # parent fingerprint
00000000 # serialized index
F0909AFFAA7EE7ABE5DD4E100598D4DC53CD709D5A5C2CAC40E7412F232F7C9C # chain code
02FC9E5AF0AC8D9B3CECFE2A888E2117BA3D089D8585886C9C826B6B22A98D12EA # pubkey
# we only need to change the magic bytes, prepend a 0x00 byte to the private key, and replace the pubkey with it
0488ADE4 # magic (xprv)
01
BD16BEE5
00000000
F0909AFFAA7EE7ABE5DD4E100598D4DC53CD709D5A5C2CAC40E7412F232F7C9C
00ABE74A98F6C7EABEE0428F53798F0AB8AA1BD37873999041703C742F15AC7E1E # privkey
# encoded, the xpriv is :
xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt
# we can now compute any private key on the m/0/... branch
# note that we can no longer go backwards in the path for more parent private keys
# we need to know the chain code and public key of the parent key (xpub of non-hardened index at depth M) to do the trick again
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment