Created
January 13, 2017 19:36
-
-
Save fivepiece/e3293733d99c4935332f8c5959d7472b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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