def test_parse_incorrect_type(self): xpriv = "xprv9s21ZrQH143K3YFDmG48xQj4BKHUn15if4xsQiMwSKX8bZ6YruYK6mV6oM5Tbodv1pLF7GMdPGaTcZBno3ZejMHbVVvymhsS5GcYC4hSKag" self.assertEqual(PrvKeyNode.parse(xpriv).extended_private_key(), xpriv) self.assertEqual( PrvKeyNode.parse( decode_base58_checksum(xpriv)).extended_private_key(), xpriv) self.assertEqual( PrvKeyNode.parse(BytesIO( decode_base58_checksum(xpriv))).extended_private_key(), xpriv) self.assertRaises(ValueError, PrvKeyNode.parse, 1584784554)
def xprv(self, index: int = 0) -> str: """ Create extended private key from deterministic entropy specified by path. :param index: derivation index (default=0) :return: extended private key (XPRV) """ path = "m/83696968'/32'/{}'".format(index) entropy = self.entropy(path=path) left, right = entropy[:32], entropy[32:] self.correct_key(big_endian_to_int(right)) prv_node = PrvKeyNode(key=right, chain_code=left) return prv_node.extended_private_key()
def test_vector_5(self): # https://github.com/bitcoin/bips/pull/1030 # Chain m seed = "3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678" xpub = "xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa" xpriv = "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) self.assertEqual(m.extended_public_key(), xpub) self.assertEqual(m.extended_private_key(), xpriv) self.assertEqual(m.__repr__(), "m") # chain m/0' xpub = "xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m" xpriv = "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G" m0h = m.ckd(index=2**31) self.assertEqual(m0h.extended_public_key(), xpub) self.assertEqual(m0h.extended_private_key(), xpriv) self.assertEqual(m0h.__repr__(), "m/0'") # chain m/0'/1' xpub = "xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt" xpriv = "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1" m0h1h = m0h.ckd(index=1 + 2**31) self.assertEqual(m0h1h.extended_public_key(), xpub) self.assertEqual(m0h1h.extended_private_key(), xpriv) self.assertEqual(m0h1h.__repr__(), "m/0'/1'")
def test_vector_4(self): # https://blog.polychainlabs.com/bitcoin,/bip32,/bip39,/kdf/2021/05/17/inconsistent-bip32-derivations.html # https://github.com/btcsuite/btcutil/issues/172 # Chain m seed = "1cae71ac5ed584ff88a078a119512d12bb61e5398521785e123b6d08809d44b2" xpub = "xpub661MyMwAqRbcEmwzw5S7mHW26Urp4kngnBFwoZUXSgakbHGs5bgZ7RYsqX9nyCP3YKqrJ2gVfaJc6waZBJC2VFsnmJB7iPSNA5LvmZpcBcQ" xpriv = "xprv9s21ZrQH143K2HsXq3u7Q9ZHYT2KfJ4qQxLM1B4utM3miUwiY4NJZdEPzDpzbH7xxtMr3QfT2VH13rabABKkw1eLU83YC1QMeXsX3DBe2yP" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) self.assertEqual(m.extended_public_key(), xpub) self.assertEqual(m.extended_private_key(), xpriv) self.assertEqual(m.__repr__(), "m") # chain m/44' xpub = "xpub695cM7RLktQbMS9DgS2SmkGF6W4msU7dW3ZkshyPV5PVWsWyoNxtvSBtm6VPSbcBR3a1NSp9BYy3v3QhUTi8T1HDa6rMShYmF682N6BaYpk" xpriv = "xprv9v6FwbtSvWrJ8x4kaQVSQcKWYUEHU1Pn8peA5KZmvjrWe5BqFqeeNdsQuqDXN9JqeAxmAvs5v682JLDQZJsB8Up4guNVPSGidN19N2iH1Lr" m0h = m.ckd(index=44 + 2**31) self.assertEqual(m0h.extended_public_key(), xpub) self.assertEqual(m0h.extended_private_key(), xpriv) self.assertEqual(m0h.__repr__(), "m/44'") # chain m/44'/0' xpub = "xpub6Begh3MMx7oX2KoJb5D9sfJruuqsqsrqBZTBBznYMRfk7RBo8EcKDodYJm529ykTr2wrK1KBKXCbdSPu74pA37hZmPxkCP3hbEJBuqJgruy" xpriv = "xprv9xfLHXpU7kFDoqiqV3g9WXN8Mt1PSR8ypLXaPcNvo68mEcreahJ4g1K4TWqn4qu6HCKByGeivW9neAEzSS7idYdpGaGXJgvb79fxvV4qhse" m0h0h = m0h.ckd(index=2**31) self.assertEqual(m0h0h.extended_public_key(), xpub) self.assertEqual(m0h0h.extended_private_key(), xpriv) self.assertEqual(m0h0h.__repr__(), "m/44'/0'")
def test_parse(self): xpub = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH" xpriv = "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt" pub_node = PubKeyNode.parse(s=xpub) self.assertEqual(pub_node.extended_public_key(), xpub) self.assertEqual( PrvKeyNode.parse(s=xpriv).extended_private_key(), xpriv)
def test_vector_2(self): mnemonic = "banner list crush drill oxygen grit donate chair expect cloud artist window dignity company salad clinic follow drive narrow crater enlist tortoise stay rain" root_prv = "xprv9s21ZrQH143K427wU7WXG3doLsxkVbzVubaGShVYLHnYgb6EiiEyhhr2GEzz6UDNFrhNk9s6Ms9iPzA6xz2t6VjmGtQmATGSXDEJyGLGmbT" node = PrvKeyNode.master_key(bip39_seed=bip39_seed_from_mnemonic( mnemonic=mnemonic)) self.assertEqual(node.extended_private_key(), root_prv) privkey = "L2qaW9UoXt7vthCD7p1fk7NxFkw5gzR774L1vWyMQSdwgKspgUeu" pubkey = "0374b1b783ce4e78486ae54642a41732bb5a8980d4c50a688ad2faddcdb405b826" address = "19k8j3qbqshC7rEaeyq4SCtp2mYzTRsErk" # Account 0, first receiving address = m/44'/0'/0'/0/0 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 0, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address) privkey = "L5UMLuwuAqjzZUPxhqLoxNdACD1h9V4E4csMNnLadRN7F5aEqo7a" pubkey = "03fc56445a29609e96e9f0715462493e0e7541d07ec45880bd878b5715e150d89b" address = "1F4dQThjuxNPmBkVgZLayjCMsQLGciEw7f" # Account 0, second receiving address = m/44'/0'/0'/0/1 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 0, 1]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address) privkey = "KwPm4hYMLzraakKBthL2zN5VQTRQzWmwmh8SvLhBEro3EvsuziRT" pubkey = "02335d60362f168c567da9258c1366499d8bee2bf3425fa3b90a3ddedfddec89e2" address = "1Y8pXXGJMD5ZW4A3kbxCroxaf7xiFo4yp" # Account 0, first change address = m/44'/0'/0'/1/0 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 1, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address)
def test_vector_1(self): mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" root_prv = "xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu" node = PrvKeyNode.master_key(bip39_seed=bip39_seed_from_mnemonic( mnemonic=mnemonic)) self.assertEqual(node.extended_private_key(), root_prv) privkey = "L4p2b9VAf8k5aUahF1JCJUzZkgNEAqLfq8DDdQiyAprQAKSbu8hf" pubkey = "03aaeb52dd7494c361049de67cc680e83ebcbbbdbeb13637d92cd845f70308af5e" address = "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA" # Account 0, first receiving address = m/44'/0'/0'/0/0 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 0, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address) privkey = "KzJgGiEeGUVWmPR97pVWDnCVraZvM2fnrCVrg2irV4353HciE6Un" pubkey = "02dfcaec532010d704860e20ad6aff8cf3477164ffb02f93d45c552dadc70ed24f" address = "1Ak8PffB2meyfYnbXZR9EGfLfFZVpzJvQP" # Account 0, second receiving address = m/44'/0'/0'/0/1 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 0, 1]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address) privkey = "L1GfmUBVD88haCukMzGtmR5B5zuQVxd6cmUVe85d66Uq2V13orj3" pubkey = "03498b3ac8e882c5d693540c49adf22b7a1b99c1bb8047966739bfe8cdeb272e64" address = "1J3J6EvPrv8q6AC3VCjWV45Uf3nssNMRtH" # Account 0, first change address = m/44'/0'/0'/1/0 child = node.derive_path(index_list=[44 + 2**31, 2**31, 2**31, 1, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual(child.public_key.address(addr_type="p2pkh"), address)
def from_extended_key(cls, extended_key: str) -> "BaseWallet": """ Creates new wallet from extended key. :param extended_key: extended public or private key :return: wallet """ # just need version, key type does not matter in here version_int = PrvKeyNode.parse(s=extended_key).parsed_version version = Version.parse(version_int=version_int) if version.key_type == Key.PRV: node = PrvKeyNode.parse(extended_key, testnet=version.testnet) else: # is this just assuming? or really pub if not priv node = PubKeyNode.parse(extended_key, testnet=version.testnet) return cls(testnet=version.testnet, master=node)
def test_bip39_vectors(self): for data in self.test_data: data = TestData(data) mnemonic_sentence = mnemonic_from_entropy(data.entropy) self.assertEqual(data.mnemonic, mnemonic_sentence) seed = bip39_seed_from_mnemonic(mnemonic_sentence, password="******") self.assertEqual(data.bip39_seed, seed.hex()) master_k = PrvKeyNode.master_key(bip39_seed=seed) self.assertEqual(master_k.extended_private_key(), data.xprv)
def test_equality(self): xpriv = "xprv9s21ZrQH143K4EK4Fdy4ddWeDMy1x4tg2s292J5ynk23sn3hxSZ9MqqLZCTj2dHPP16CsTdAFeznbnNhSN3v66TtSKzJf4hPZSqDjjp9t42" m0 = PrvKeyNode.parse(s=xpriv) m1 = PrvKeyNode.parse(s=xpriv) self.assertEqual(m0, m1) xpub = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH" M0 = PubKeyNode.parse(s=xpub) M1 = PubKeyNode.parse(s=xpub) self.assertEqual(M0, M1) seed = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" m0 = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) m1 = PrvKeyNode.parse(s=m0.extended_private_key()) self.assertEqual(m0, m1) m0 = PrvKeyNode.parse(s=xpriv) M0 = PubKeyNode.parse(s=m0.extended_public_key()) self.assertNotEqual(m0, M0)
def test_vector_2(self): # Chain m seed = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" xpub = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB" xpriv = "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) self.assertEqual(m.extended_public_key(), xpub) self.assertEqual(m.extended_private_key(), xpriv) self.assertEqual(m.__repr__(), "m") # Chain m/0 xpub = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH" xpriv = "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt" m0 = m.ckd(index=0) self.assertEqual(m0.extended_public_key(), xpub) self.assertEqual(m0.extended_private_key(), xpriv) self.assertEqual(m0.__repr__(), "m/0") # Chain m/0/2147483647' xpub = "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a" xpriv = "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9" m02147483647h = m0.ckd(index=2**31 + 2147483647) self.assertEqual(m02147483647h.extended_public_key(), xpub) self.assertEqual(m02147483647h.extended_private_key(), xpriv) self.assertEqual(m02147483647h.__repr__(), "m/0/2147483647'") # Chain m/0/2147483647'/1 xpub = "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon" xpriv = "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef" m02147483647h1 = m02147483647h.ckd(index=1) self.assertEqual(m02147483647h1.extended_public_key(), xpub) self.assertEqual(m02147483647h1.extended_private_key(), xpriv) self.assertEqual(m02147483647h1.__repr__(), "m/0/2147483647'/1") # Chain m/0/2147483647'/1/2147483646' xpub = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL" xpriv = "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc" m02147483647h12147483646h = m02147483647h1.ckd(index=2**31 + 2147483646) self.assertEqual(m02147483647h12147483646h.extended_public_key(), xpub) self.assertEqual(m02147483647h12147483646h.extended_private_key(), xpriv) self.assertEqual(m02147483647h12147483646h.__repr__(), "m/0/2147483647'/1/2147483646'") # Chain m/0/2147483647'/1/2147483646'/2 xpub = "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt" xpriv = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j" m02147483647h12147483646h2 = m02147483647h12147483646h.ckd(index=2) self.assertEqual(m02147483647h12147483646h2.extended_public_key(), xpub) self.assertEqual(m02147483647h12147483646h2.extended_private_key(), xpriv) self.assertEqual(m02147483647h12147483646h2.__repr__(), "m/0/2147483647'/1/2147483646'/2")
def from_bip39_seed_bytes(cls, bip39_seed: bytes, testnet: bool = False): """ creates new wallet from bip39 seed. :param bip39_seed: bip39 seed :param testnet: whether this node is testnet node (default=False) :return: wallet """ return cls(master=PrvKeyNode.master_key(bip39_seed=bip39_seed, testnet=testnet), testnet=testnet)
def from_xprv(cls, xprv: str, testnet=False) -> "BIP85DeterministicEntropy": """ Creates new deterministic entropy object from extended private key. :param xprv: extended private key :param testnet: is testnet? (default=False) :return: deterministic entropy object """ return cls(master_node=PrvKeyNode.parse(s=xprv, testnet=testnet), testnet=testnet)
def test_vector_4(self): mnemonic = "fence test aunt appear calm supreme february fortune dog lunch dose volume envelope path must will vanish indicate switch click brush boy negative skate" root_prv = "vprv9DMUxX4ShgxMKyN621zFC9uyEyEPAngB2HEGpgzkhk99Bc313S6xi8ZdKf3nvk62wRFcCftLZnSovSNMMAmXra2vCmK52uikediy1Pspu3D" root_pub = "vpub5SLqN2bLY4WeYTSZ83XFZHrho14saFQ2PW9sd5QNG5g84QN9ayRDFvt7AvVCq9JDXJnsXhhn6Zh92fy3dExzMp2JTLpcD5P4mjPNHjHLNCa" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic), testnet=True ) self.assertEqual(node.extended_public_key(version=0x045f1cf6), root_pub) self.assertEqual(node.extended_private_key(version=0x045f18bc), root_prv) privkey = "cNFqn4Rr13V6mgTArc274BoD4PFMnPDpK18ZF7Q9DjvFvGViJK2J" pubkey = "02b70bae290aa611cf617b6349869f9615c7afb92dc1deb6108178e3f291dd68a8" address = "tb1q83lcrth7dgl0fld22t0vkpa5wcejge7ja0nq4y" # Account 0, first receiving address = m/84'/1'/0'/0/0 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 0, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address ) privkey = "cRkhE4yszcvpQFtjNc3t74268fbJf7EPtYLCTWstJU536GN1XPXG" pubkey = "03469b9a1520a0e9eb29879bc3c4c0e983991a2fa183535d2d2f0bc0007d1d3895" address = "tb1qtg7x8s5tfxjtrj476549p779a349f3mjvvv75c" # Account 0, second receiving address = m/84'/1'/0'/0/1 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 0, 1]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address ) privkey = "cQi6GaKDy3StULmYnV3QvRRoLxCgNuwE3hsLRLUhN3R5pJtMu9U5" pubkey = "021b957ed3a3d15cd4083c415eb6ed7ea00d23d844d154ef950b5bcfcdf4c5766e" address = "tb1qtqtyxy2a6r2ulw468n9jzmqt2z8n9htkh7g3cp" # Account 0, first change address = m/84'/0'/0'/1/0 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 1, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address )
def test_vector_3(self): mnemonic = "alone process notice pool egg gift foster session code bright service change" root_prv = "vprv9DMUxX4ShgxMMf69wwuvPuDoLNQec5t9WDkURn5kzoDMia4gd8ZuJEmVvSnJZSWtYeKtFto2SPDBWQg6ShkRBdza5DpbrrNtjVdnHnscZaa" root_pub = "vpub5SLqN2bLY4Wea9Ad3ySvm3AXtQF91YbzsSg5EAVNZ8kLbNPqAft9r35ymifdRaDHzhqi3bQ3fWtbDLV6aUVVHzCmErvLYkA6uc8MxA88EDm" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic), testnet=True ) self.assertEqual(node.extended_public_key(version=0x045f1cf6), root_pub) self.assertEqual(node.extended_private_key(version=0x045f18bc), root_prv) privkey = "cUoZgoxZFeYqzs8iFaH7ENTb9NRVYNYYR9RT9s8EQdsiEN6miTna" pubkey = "02cbe61535f7b1730e0ca98ad845dbd3a3f79401104fc388971e32124b606cfb2c" address = "tb1qpfz8s3yzkph276vh0k3l72apgg5g4ptrvas0sf" # Account 0, first receiving address = m/84'/1'/0'/0/0 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 0, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address ) privkey = "cSCJB57PH4DwNnNKkJabyJzAwG2kgwyP7RtVWXHnCcccHV9jBVpf" pubkey = "03a4495d811eb515cd047a304cb74708e7e9dc8d53359465f9c23a9bbb131b015b" address = "tb1q95pfzgslydz9mhl6ngjv74u5k74zg98ntc5ghe" # Account 0, second receiving address = m/84'/1'/0'/0/1 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 0, 1]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address ) privkey = "cV5iKGZAXmHJrb52DqiwaGvrFQboMBtu1yiR4uRGPApwTgq7jPu6" pubkey = "0348649e2c2623e62d7cbab33d02d15615528e31a09ea350ede98ba706ab72dc1a" address = "tb1qt52wa6r76n4evqps6a9wt30lh26ylpgnmddu6g" # Account 0, first change address = m/84'/0'/0'/1/0 child = node.derive_path( index_list=[84 + 2 ** 31, 1 + 2 ** 31, 2 ** 31, 1, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh", testnet=True), address )
def test_vector_2(self): mnemonic = "banner list crush drill oxygen grit donate chair expect cloud artist window dignity company salad clinic follow drive narrow crater enlist tortoise stay rain" root_prv = "zprvAWgYBBk7JR8GkcWB8q5mgDpogpFeNqyVjpci1VHK6JYJnnihE2a6wqAJJevA6HXD58vzF74DHBrpAZPEQNrugy6y1ZocLGuR4fMbkVtQBYJ" root_pub = "zpub6jftahH18ngZy6aeErcn3MmYEr68nJhM73YJosgvee5Hfb3qmZtMVdUn9vmFPn81ZLTMwbC6b2zLcw17wGfg97jjZMYftosaCFee3wNg4ih" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic) ) self.assertEqual(node.extended_public_key(version=0x04b24746), root_pub) self.assertEqual(node.extended_private_key(version=0x04b2430c), root_prv) privkey = "KwPVPXy7HXg7h575VFENH8VEZedSNKmVEww9SBwVcY97oWf4iXZb" pubkey = "027b2dedd385c39132883a9ee31a4176fc7951a3ce61bfa9138c3eb9f818391b74" address = "bc1q0xc3z0qkux40884uqzan8ny4hmth4srl9fm5f3" # Account 0, first receiving address = m/84'/0'/0'/0/0 child = node.derive_path( index_list=[84 + 2 ** 31, 2 ** 31, 2 ** 31, 0, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address ) privkey = "L3XXZ8mcJ4j2E39T6CC9GSk4coPKH6srRn9sGdj9UJahRfUasqNk" pubkey = "024c128fbc3d35d13de68fc6d641dd9a3f220117d2565546aeb9051c9f37617d14" address = "bc1qzhrav6ktxvgyet00uup8pw7lwr7s2p9z4p5uar" # Account 0, second receiving address = m/84'/0'/0'/0/1 child = node.derive_path( index_list=[84 + 2 ** 31, 2 ** 31, 2 ** 31, 0, 1]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address ) privkey = "L1tEGjKn8oCY5ZoAQFo9PQk9ttcidcV5qkwXsMZfum13LFizmdoQ" pubkey = "039d576e00f67c7953776d8bbd3f2f82b8eb139ab1251e284efb143a136be6c57b" address = "bc1qsr3a7v4cmnakvharlacssz034vjrqw8sd03cp9" # Account 0, first change address = m/84'/0'/0'/1/0 child = node.derive_path( index_list=[84 + 2 ** 31, 2 ** 31, 2 ** 31, 1, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address )
def test_vector_3(self): # Chain m seed = "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be" xpub = "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13" xpriv = "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) self.assertEqual(m.extended_public_key(), xpub) self.assertEqual(m.extended_private_key(), xpriv) self.assertEqual(m.__repr__(), "m") # chain m/0' xpub = "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y" xpriv = "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L" m0h = m.ckd(index=2**31) self.assertEqual(m0h.extended_public_key(), xpub) self.assertEqual(m0h.extended_private_key(), xpriv) self.assertEqual(m0h.__repr__(), "m/0'")
def test_vector_1(self): mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" root_prv = "zprvAWgYBBk7JR8Gjrh4UJQ2uJdG1r3WNRRfURiABBE3RvMXYSrRJL62XuezvGdPvG6GFBZduosCc1YP5wixPox7zhZLfiUm8aunE96BBa4Kei5" root_pub = "zpub6jftahH18ngZxLmXaKw3GSZzZsszmt9WqedkyZdezFtWRFBZqsQH5hyUmb4pCEeZGmVfQuP5bedXTB8is6fTv19U1GQRyQUKQGUTzyHACMF" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic) ) self.assertEqual(node.extended_public_key(version=0x04b24746), root_pub) self.assertEqual(node.extended_private_key(version=0x04b2430c), root_prv) privkey = "KyZpNDKnfs94vbrwhJneDi77V6jF64PWPF8x5cdJb8ifgg2DUc9d" pubkey = "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c" address = "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu" # Account 0, first receiving address = m/84'/0'/0'/0/0 child = node.derive_path(index_list=[84 + 2**31, 2**31, 2**31, 0, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address ) privkey = "Kxpf5b8p3qX56DKEe5NqWbNUP9MnqoRFzZwHRtsFqhzuvUJsYZCy" pubkey = "03e775fd51f0dfb8cd865d9ff1cca2a158cf651fe997fdc9fee9c1d3b5e995ea77" address = "bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g" # Account 0, second receiving address = m/84'/0'/0'/0/1 child = node.derive_path(index_list=[84 + 2**31, 2**31, 2**31, 0, 1]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address ) privkey = "KxuoxufJL5csa1Wieb2kp29VNdn92Us8CoaUG3aGtPtcF3AzeXvF" pubkey = "03025324888e429ab8e3dbaf1f7802648b9cd01e9b418485c5fa4c1b9b5700e1a6" address = "bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el" # Account 0, first change address = m/84'/0'/0'/1/0 child = node.derive_path(index_list=[84 + 2**31, 2**31, 2**31, 1, 0]) self.assertEqual(child.private_key.wif(), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2wpkh"), address )
def test_ckd_pub_ckd_priv_matches_public_key(self): seed = "b4385b54033b047216d71031bd83b3c059d041590f24c666875c980353c9a5d3322f723f74d1f5e893de7af80d80307f51683e13557ad1e4a2fe151b1c7f0d8b" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) master_xpub = m.extended_public_key() M = PubKeyNode.parse(s=master_xpub) m44 = m.ckd(index=44) M44 = M.ckd(index=44) self.assertEqual(m44.extended_public_key(), M44.extended_public_key()) self.assertEqual( m44.extended_public_key(), "xpub68gENos6i4PQxkSjJB2Ww79EfUVX8J4nrTHYzUWa3q6gMivLymbzHiu1MBoxi3fVDUQVi61Lv7brNs18sHjzdBVgCXocZxDwrsGrAf4GN3T" ) m440 = m44.ckd(index=0) M440 = M44.ckd(index=0) self.assertEqual(m440.extended_public_key(), M440.extended_public_key()) self.assertEqual( m440.extended_public_key(), "xpub6AotjNzqVqVCmdvqAsMi2zNEDCobz7s9zit2pfdKPPc9LQ2GwSGybYDKuqDGC7mVhSWNZBNeRwqtjvA7rX4ACKXa8GrnD5XQkGb542RuzZ5" ) m440thousand = m440.ckd(index=1000) M440thousand = M440.ckd(index=1000) self.assertEqual(m440thousand.extended_public_key(), M440thousand.extended_public_key()) self.assertEqual( m440thousand.extended_public_key(), "xpub6CqqMNRRTuyJNyP6VNCxY1SJWNY4t2QsmsWTsBmiZyUvbYDKMU77DaDJpeqMqNkzwCuTqXghQ58DbhNVpe9r2vtuvPSvwUWNB2Wc6RWh3US" ) m440thousand__ = m440thousand.ckd(index=2**31 - 1) M440thousand__ = M440thousand.ckd(index=2**31 - 1) self.assertEqual(m440thousand__.extended_public_key(), M440thousand__.extended_public_key()) self.assertEqual( m440thousand__.extended_public_key(), "xpub6EtrsXwXdacQ9iDpmqTeYpu8AstEBrwiXbpdoVU4Q1yhjmN5c8Niw2KvJRwSGS4VtndPgCuHH15SstUzENBksqpVP8YxzubWcERugoDafnq" ) m440thousand__0 = m440thousand__.ckd(index=0) M440thousand__0 = M440thousand__.ckd(index=0) self.assertEqual(m440thousand__0.extended_public_key(), M440thousand__0.extended_public_key()) self.assertEqual( m440thousand__0.extended_public_key(), "xpub6FymQUeMhBdyk57T6P9oAZVcPTniJyXWHYKxzurkT6u729eC8bdtzdP6i4RShvHrnKpiEhhZHY2kQBYxyKJPFUbUzum7w6a3W4JdADuCisC" )
def test_vector_3(self): mnemonic = "alone process notice pool egg gift foster session code bright service change" root_prv = "tprv8ZgxMBicQKsPf4hvHELfyj2nzS7kiqu9fzi2rzHzEnTbcNSE7pEn47TDt2s8ZdD3jN6GkwbuX4W5jqSy1JvPbAdNLYRkh2jvC3WVWe9hxQr" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic), testnet=True) self.assertEqual(node.extended_private_key(), root_prv) privkey = "cNutGXgQKYVrw9JJV6Fws7Js9SMojfpbxFaiF5cjeLrrkHbAhKTb" pubkey = "0381da8a81de5c2a42bc60bc0a649e2f08f53b594721da9ac2d212e0c3b7730edd" address = "mgLhaL9WAHMjxo2nQxTXb4uKQohkSDovwQ" # Account 0, first receiving address = m/44'/1'/0'/0/0 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 0, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address) privkey = "cNhtxSzH1upG3PDFHvYdJsm5kdDWEJpQxENJNwbtRRMcopCc336c" pubkey = "02c5859beb5bee582fe3a15f4515c3895d92034668748d8ced281ead49b5bb0449" address = "moGvMt2EbR3BkAhbbjpg1qKt11ioKJ9tox" # Account 0, second receiving address = m/44'/1'/0'/0/1 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 0, 1]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address) privkey = "cVb5BXW3tJ1gFuBmEH9HaV4CZE1SESTnaptqvgkqvpYF9w7abcmi" pubkey = "02104bdf90bbfbb3a34e96cf1152368bd492309f7808cb2f5f63173c2a8ab46002" address = "mxCa2PGGeUZbFvA1upGk4D1cn4DgXAhiLX" # Account 0, first change address = m/44'/0'/0'/1/0 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 1, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address)
def test_vector_4(self): mnemonic = "fence test aunt appear calm supreme february fortune dog lunch dose volume envelope path must will vanish indicate switch click brush boy negative skate" root_prv = "tprv8ZgxMBicQKsPdNyrMJQzmyixu2wVHYhBC4BqFuCywjPP5QQYY7mqU1FMHF8cvvnC891zhihDeTji9s9DumwWG6fiU5vDs65n7BbgECfeGwP" node = PrvKeyNode.master_key( bip39_seed=bip39_seed_from_mnemonic(mnemonic=mnemonic), testnet=True) self.assertEqual(node.extended_private_key(), root_prv) privkey = "cVjV1Ndx6LtrHMxbsYDv3q2CLXJNqYRiG9cwodx4v7mcwXrG8iSD" pubkey = "03f1a036d901530e56c6a6176ad36f3d1e1b9b8a916c2ed151b3935183c44e5393" address = "n1W8Lo4xzjSXhV2fEzTn2tRDsDcojmVG7G" # Account 0, first receiving address = m/44'/1'/0'/0/0 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 0, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address) privkey = "cPpJHF6ibT1GFncfmNHvtSYS3r97X3eFtN25vm2EGbTJuiEfzh4k" pubkey = "03995043232281e3b07c94607fe83850be854242446233a9343dd4416980c0ac49" address = "miomtTdPdDF7vkqaPYvQnmabQt4U1EiQbD" # Account 0, second receiving address = m/44'/1'/0'/0/1 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 0, 1]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address) privkey = "cN29ySsZcGfnzwjjW1SDRHXskZu74LCEFroYUncg36Z4cc7asN9b" pubkey = "0200d38aa76fd2b4c8cec5df529e9690ee911646c7879d35c2f11267efbca9b0ec" address = "mvgHvHAi5RYexicFmpvWKs8weiYFCdMkEH" # Account 0, first change address = m/44'/0'/0'/1/0 child = node.derive_path( index_list=[44 + 2**31, 1 + 2**31, 2**31, 1, 0]) self.assertEqual(child.private_key.wif(testnet=True), privkey) self.assertEqual(child.public_key.sec().hex(), pubkey) self.assertEqual( child.public_key.address(addr_type="p2pkh", testnet=True), address)
def test_vector_1(self): # Chain m seed = "000102030405060708090a0b0c0d0e0f" xpub = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8" xpriv = "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi" m = PrvKeyNode.master_key(bip39_seed=bytes.fromhex(seed)) self.assertEqual(m.extended_public_key(), xpub) self.assertEqual(m.extended_private_key(), xpriv) self.assertEqual(m.__repr__(), "m") # chain m/0' xpub = "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw" xpriv = "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7" m0h = m.ckd(index=2**31) self.assertEqual(m0h.extended_public_key(), xpub) self.assertEqual(m0h.extended_private_key(), xpriv) self.assertEqual(m0h.__repr__(), "m/0'") # chain M/0' M0h = PubKeyNode.parse(xpub) # chain M/0'/1 M0h1 = M0h.ckd(index=1) public_only_xpub = M0h1.extended_public_key() # chain m/0'/1 xpub = "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ" xpriv = "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs" m0h1 = m0h.ckd(index=1) self.assertEqual(public_only_xpub, xpub) self.assertEqual(m0h1.extended_public_key(), xpub) self.assertEqual(m0h1.extended_private_key(), xpriv) self.assertEqual(m0h1.__repr__(), "m/0'/1") # chain m/0'/1/2' xpub = "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5" xpriv = "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM" m0h12h = m0h1.ckd(index=2**31 + 2) self.assertEqual(m0h12h.extended_public_key(), xpub) self.assertEqual(m0h12h.extended_private_key(), xpriv) self.assertEqual(m0h12h.__repr__(), "m/0'/1/2'") # chain m/0'/1/2'/2 xpub = "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV" xpriv = "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334" m0h12h2 = m0h12h.ckd(index=2) self.assertEqual(m0h12h2.extended_public_key(), xpub) self.assertEqual(m0h12h2.extended_private_key(), xpriv) self.assertEqual(m0h12h2.__repr__(), "m/0'/1/2'/2") # chain M/0'/1/2'/2 M0h12h2 = PubKeyNode.parse(xpub) # chain M/0'/1/2'/2/1000000000 M0h12h21000000000 = M0h12h2.ckd(index=1000000000) public_only_xpub = M0h12h21000000000.extended_public_key() # chain m/0'/1/2'/2/1000000000 xpub = "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy" xpriv = "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76" m0h12h21000000000 = m0h12h2.ckd(index=1000000000) self.assertEqual(m0h12h21000000000.extended_public_key(), xpub) self.assertEqual(public_only_xpub, xpub) self.assertEqual(m0h12h21000000000.extended_private_key(), xpriv) self.assertEqual(m0h12h21000000000.__repr__(), "m/0'/1/2'/2/1000000000")