def test_slip32(): # xkey is not a public one xprv = b"xprv9s21ZrQH143K2ZP8tyNiUtgoezZosUkw9hhir2JFzDhcUWKz8qFYk3cxdgSFoCMzt8E2Ubi1nXw71TLhwgCfzqFHfM5Snv4zboSebePRmLS" err_msg = "Not a public key: " with pytest.raises(ValueError, match=err_msg): slip32.address_from_xpub(xprv) address = slip32.address_from_xkey(xprv) xpub = bip32.xpub_from_xprv(xprv) address2 = slip32.address_from_xpub(xpub) assert address == address2
def test_slip32(self): """SLIP32 test vector https://github.com/satoshilabs/slips/blob/master/slip-0132.md """ mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" passphrase = "" path = "m/44'/0'/0'" prv = b"xprv9xpXFhFpqdQK3TmytPBqXtGSwS3DLjojFhTGht8gwAAii8py5X6pxeBnQ6ehJiyJ6nDjWGJfZ95WxByFXVkDxHXrqu53WCRGypk2ttuqncb" pub = b"xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj" address = b"1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA" rxprv = bip32.rootxprv_from_bip39mnemonic(mnemonic, passphrase, MAIN_xprv) mprv = bip32.derive(rxprv, path) self.assertEqual(mprv, prv) mpub = bip32.xpub_from_xprv(mprv) self.assertEqual(mpub, pub) pub = bip32.derive(mpub, "./0/0") addr = slip32.address_from_xpub(pub) self.assertEqual(address, addr) path = "m/49'/0'/0'" prv = b"yprvAHwhK6RbpuS3dgCYHM5jc2ZvEKd7Bi61u9FVhYMpgMSuZS613T1xxQeKTffhrHY79hZ5PsskBjcc6C2V7DrnsMsNaGDaWev3GLRQRgV7hxF" pub = b"ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP" address = b"37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf" rxprv = bip32.rootxprv_from_bip39mnemonic(mnemonic, passphrase, MAIN_yprv) mprv = bip32.derive(rxprv, path) self.assertEqual(mprv, prv) mpub = bip32.xpub_from_xprv(mprv) self.assertEqual(mpub, pub) pub = bip32.derive(mpub, "./0/0") addr = slip32.address_from_xpub(pub) self.assertEqual(address, addr) addr = base58address.p2wpkh_p2sh_from_xpub(pub) self.assertEqual(address, addr) path = "m/84'/0'/0'" prv = b"zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE" pub = b"zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs" address = b"bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu" rxprv = bip32.rootxprv_from_bip39mnemonic(mnemonic, passphrase, MAIN_zprv) mprv = bip32.derive(rxprv, path) self.assertEqual(mprv, prv) mpub = bip32.xpub_from_xprv(mprv) self.assertEqual(mpub, pub) pub = bip32.derive(mpub, "./0/0") addr = slip32.address_from_xpub(pub) self.assertEqual(address, addr)
def test_vectors(): fname = "electrum_test_vectors.json" filename = path.join(path.dirname(__file__), "test_data", fname) with open(filename, "r") as f: test_vectors = json.load(f) lang = "en" for test_vector in test_vectors: mnemonic = test_vector[0] passphrase = test_vector[1] mxprv = test_vector[2] mxpub = test_vector[3] address = test_vector[4] # "./0/0" if mnemonic != "": mxprv2 = bip32.mxprv_from_electrum_mnemonic(mnemonic, passphrase) assert mxprv2 == mxprv.encode() eversion, mnemonic = electrum.version_from_mnemonic(mnemonic) entr = int(electrum.entropy_from_mnemonic(mnemonic, lang), 2) mnem = electrum.mnemonic_from_entropy(entr, eversion, lang) assert mnem == mnemonic if mxprv != "": mxpub2 = bip32.xpub_from_xprv(mxprv) assert mxpub2 == mxpub.encode() xpub = bip32.derive(mxpub, "./0/0") address2 = slip32.address_from_xpub(xpub).decode("ascii") assert address2 == address
def test_slip32_test_vector(): """SLIP32 test vector https://github.com/satoshilabs/slips/blob/master/slip-0132.md """ mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" kpath = "./0/0" test_vectors = [ [ NETWORKS["mainnet"]["bip32_prv"], "m / 44h / 0h / 0h", "xprv9xpXFhFpqdQK3TmytPBqXtGSwS3DLjojFhTGht8gwAAii8py5X6pxeBnQ6ehJiyJ6nDjWGJfZ95WxByFXVkDxHXrqu53WCRGypk2ttuqncb", "xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj", "1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA", ], [ NETWORKS["mainnet"]["slip32_p2wsh_p2sh_prv"], "m / 49h / 0h / 0h", "yprvAHwhK6RbpuS3dgCYHM5jc2ZvEKd7Bi61u9FVhYMpgMSuZS613T1xxQeKTffhrHY79hZ5PsskBjcc6C2V7DrnsMsNaGDaWev3GLRQRgV7hxF", "ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP", "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf", ], [ NETWORKS["mainnet"]["slip32_p2wpkh_prv"], "m / 84h / 0h / 0h", "zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE", "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs", "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", ], ] for version, der_path, prv, pub, addr_str in test_vectors: rxprv = bip32.mxprv_from_bip39_mnemonic(mnemonic, "", version) mxprv = bip32.derive(rxprv, der_path) assert prv.encode() == mxprv mxpub = bip32.xpub_from_xprv(mxprv) assert pub.encode() == mxpub xpub = bip32.derive(mxpub, kpath) address = slip32.address_from_xpub(xpub) addr = addr_str.encode() assert addr == address address = slip32.address_from_xkey(xpub) assert addr == address xprv = bip32.derive(mxprv, kpath) address = slip32.address_from_xkey(xprv) assert addr == address if version == NETWORKS["mainnet"]["bip32_prv"]: address = base58address.p2pkh(xpub) assert addr == address address = base58address.p2pkh(xprv) assert addr == address elif version == NETWORKS["mainnet"]["slip32_p2wsh_p2sh_prv"]: address = base58address.p2wpkh_p2sh(xpub) assert addr == address address = base58address.p2wpkh_p2sh(xprv) assert addr == address elif version == NETWORKS["mainnet"]["slip32_p2wpkh_prv"]: address = bech32address.p2wpkh(xpub) assert addr == address address = bech32address.p2wpkh(xprv) assert addr == address
def test_slip32(self): # xkey is not a public one xprv = b'xprv9s21ZrQH143K2ZP8tyNiUtgoezZosUkw9hhir2JFzDhcUWKz8qFYk3cxdgSFoCMzt8E2Ubi1nXw71TLhwgCfzqFHfM5Snv4zboSebePRmLS' self.assertRaises(ValueError, slip32.address_from_xpub, xprv) address = slip32.address_from_xkey(xprv) xpub = bip32.xpub_from_xprv(xprv) address2 = slip32.address_from_xpub(xpub) self.assertEqual(address, address2)
def test_slip32_test_vector(self): """SLIP32 test vector https://github.com/satoshilabs/slips/blob/master/slip-0132.md """ mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" kpath = "./0/0" test_vectors = [ [ MAIN_xprv, "m / 44h / 0h / 0h", b'xprv9xpXFhFpqdQK3TmytPBqXtGSwS3DLjojFhTGht8gwAAii8py5X6pxeBnQ6ehJiyJ6nDjWGJfZ95WxByFXVkDxHXrqu53WCRGypk2ttuqncb', b'xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj', b'1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA' ], [ MAIN_yprv, "m / 49h / 0h / 0h", b'yprvAHwhK6RbpuS3dgCYHM5jc2ZvEKd7Bi61u9FVhYMpgMSuZS613T1xxQeKTffhrHY79hZ5PsskBjcc6C2V7DrnsMsNaGDaWev3GLRQRgV7hxF', b'ypub6Ww3ibxVfGzLrAH1PNcjyAWenMTbbAosGNB6VvmSEgytSER9azLDWCxoJwW7Ke7icmizBMXrzBx9979FfaHxHcrArf3zbeJJJUZPf663zsP', b'37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf' ], [ MAIN_zprv, "m / 84h / 0h / 0h", b'zprvAdG4iTXWBoARxkkzNpNh8r6Qag3irQB8PzEMkAFeTRXxHpbF9z4QgEvBRmfvqWvGp42t42nvgGpNgYSJA9iefm1yYNZKEm7z6qUWCroSQnE', b'zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs', b'bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu' ], ] for v in test_vectors: rxprv = bip32.rootxprv_from_bip39mnemonic(mnemonic, '', v[0]) mxprv = bip32.derive(rxprv, v[1]) self.assertEqual(v[2], mxprv) mxpub = bip32.xpub_from_xprv(mxprv) self.assertEqual(v[3], mxpub) xpub = bip32.derive(mxpub, kpath) address = slip32.address_from_xpub(xpub) self.assertEqual(v[4], address) address = slip32.address_from_xkey(xpub) self.assertEqual(v[4], address) xprv = bip32.derive(mxprv, kpath) address = slip32.address_from_xkey(xprv) self.assertEqual(v[4], address) if v[0] == MAIN_xprv: address = base58address.p2pkh(xpub) self.assertEqual(v[4], address) address = base58address.p2pkh(xprv) self.assertEqual(v[4], address) elif v[0] == MAIN_yprv: address = base58address.p2wpkh_p2sh(xpub) self.assertEqual(v[4], address) address = base58address.p2wpkh_p2sh(xprv) self.assertEqual(v[4], address) elif v[0] == MAIN_zprv: address = bech32address.p2wpkh(xpub) self.assertEqual(v[4], address) address = bech32address.p2wpkh(xprv) self.assertEqual(v[4], address)
def test_p2pkh_from_wif(self): seed = b"00" * 32 # better be random rxprv = bip32.rootxprv_from_seed(seed) path = "m/0h/0h/12" xprv = bip32.derive(rxprv, path) wif = wif_from_xprv(xprv) self.assertEqual( wif, b'KyLk7s6Z1FtgYEVp3bPckPVnXvLUWNCcVL6wNt3gaT96EmzTKZwP') address = p2pkh_from_wif(wif) xpub = bip32.xpub_from_xprv(xprv) address2 = slip32.address_from_xpub(xpub) self.assertEqual(address, address2) self.assertRaises(ValueError, wif_from_xprv, xpub)
def derive(mpub: str, start: int, length: int): """ Will generate list of derived addresses, starting at index <n> for <length>. :param mpub: master extended public key :param start: starting index to generate address list :param length: how many addresses to generate :return: a json list of derived addresses """ address_list = {} for index in range(start, start + length): xpub = bip32.derive(xkey=mpub, path=f"./0/{index}") address = slip32.address_from_xpub(xpub).decode("ascii") address_list[f"0/{index}"] = address return json.dumps(address_list)
def test_vectors(self): fname = "electrum_test_vectors.json" filename = path.join(path.dirname(__file__), "test_data", fname) with open(filename, "r") as f: test_vectors = json.load(f) lang = "en" for test_vector in test_vectors: mnemonic = test_vector[0] passphrase = test_vector[1] mxprv = test_vector[2] mxpub = test_vector[3] address = test_vector[4] # "./0/0" if mnemonic != "": mxprv2 = bip32.mxprv_from_electrum_mnemonic( mnemonic, passphrase) self.assertEqual(mxprv2, mxprv.encode()) eversion, mnemonic = electrum.version_from_mnemonic(mnemonic) entr = int(electrum.entropy_from_mnemonic(mnemonic, lang), 2) mnem = electrum.mnemonic_from_entropy(entr, eversion, lang) self.assertEqual(mnem, mnemonic) if mxprv != "": mxpub2 = bip32.xpub_from_xprv(mxprv) self.assertEqual(mxpub2, mxpub.encode()) xpub = bip32.derive(mxpub, "./0/0") address2 = slip32.address_from_xpub(xpub).decode("ascii") self.assertEqual(address2, address) # version 2fa_segwit mnemonic = ("slender flight session office noodle hand " "couple option office wait uniform morning") self.assertEqual("2fa_segwit", electrum.version_from_mnemonic(mnemonic)[0]) # version 2fa mnemonic = ("history recycle company awful donor fold " "beef nominee hard bleak bracket six") self.assertEqual("2fa", electrum.version_from_mnemonic(mnemonic)[0])
passphrase = "" seed = bip39.seed_from_mnemonic(mnemonic, passphrase) rxprv = bip32.rootxprv_from_seed(seed) rxpub = bip32.xpub_from_xprv(rxprv) assert rxpub == b"xpub661MyMwAqRbcFzL26X6G7bySxgU1oV6GviUrNnhbeAS3ULQq35KEV6uSf1aJXEHjFYy6LXUPrYnfR9bSKWdFZ5VnYaEb3AbHPmXFVAoKKYT", rxpub firmware_xprv = bip32.derive(rxprv, "m/0") firmware_xpub = bip32.derive(rxpub, "m/0") assert firmware_xpub == bip32.xpub_from_xprv(bip32.derive(rxprv, "m/0")) firmware_pubkey = bip32.deserialize(firmware_xpub)['key'] assert bytes_from_point(point_from_octets(firmware_pubkey), False).hex( ) == "042374b3b6b06b65a3b831f857634ea135bf10b014d5bba0f935cb9eb26a4b6547ed3b37f277427a0ab23bda0ca79c5785dc54d2387fa3f295f4d5674d5b637de2" assert bytes_from_point(point_from_octets(firmware_pubkey), True).hex( ) == "022374b3b6b06b65a3b831f857634ea135bf10b014d5bba0f935cb9eb26a4b6547" firmware_wif = base58wif.wif_from_xprv(firmware_xprv) firmware_address = slip32.address_from_xpub(firmware_xpub) app_xprv = bip32.derive(rxprv, "m/1") app_xpub = bip32.derive(rxpub, "m/1") assert app_xpub == bip32.xpub_from_xprv(bip32.derive(rxprv, "m/1")) app_pubkey = bip32.deserialize(app_xpub)['key'] assert bytes_from_point(point_from_octets(app_pubkey), False).hex( ) == "04ae3d0d5c669ed364636e79e72abc012a33be63e537babddf56bfd393256acf6dba0fac21da6386513674573a2d7baff4375c9b6d2498383853c52f0565f97f1a" app_wif = base58wif.wif_from_xprv(app_xprv) app_address = slip32.address_from_xpub(app_xpub) assert app_address == b'1J6674MtZBpfHytdNofLUX6sLHAUaG33uK' msg = "hello world" h = sha256(msg.encode()) h256 = h.digest() assert h256.hex().upper(