def test_hello_world(self): self.assertEqual(base58.encode(b'hello world'), b'StV1DL6CwTryKyV') self.assertEqual(base58.decode(b'StV1DL6CwTryKyV'), b'hello world') self.assertEqual(base58.decode(base58.encode(b'hello world')), b'hello world') self.assertEqual(base58.encode(base58.decode(b'StV1DL6CwTryKyV')), b'StV1DL6CwTryKyV')
def test_trailing_zeros(self): self.assertEqual(base58.encode(b'\x00\x00hello world'), b'11StV1DL6CwTryKyV') self.assertEqual(base58.decode(b'11StV1DL6CwTryKyV'), b'\x00\x00hello world') self.assertEqual(base58.decode(base58.encode(b'\0\0hello world')), b'\x00\x00hello world') self.assertEqual(base58.encode(base58.decode(b'11StV1DL6CwTryKyV')), b'11StV1DL6CwTryKyV')
def test_utils(self): # root key, zero depth xkey = b"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi" xdict = bip32.parse(xkey) decoded_key = base58.decode(xkey, 78) self.assertEqual(xdict["version"], decoded_key[:4]) self.assertEqual(xdict["depth"], decoded_key[4]) self.assertEqual(xdict["parent_fingerprint"], decoded_key[5:9]) self.assertEqual(xdict["index"], decoded_key[9:13]) self.assertEqual(xdict["chain_code"], decoded_key[13:45]) self.assertEqual(xdict["key"], decoded_key[45:]) # zero depth with non-zero parent_fingerprint f2 = b'\x01\x01\x01\x01' invalid_key = base58.encode(xkey[:5] + f2 + xkey[9:]) self.assertRaises(ValueError, bip32.parse, invalid_key) # bip32.parse(invalid_key) # zero depth with non-zero index i2 = b'\x01\x01\x01\x01' invalid_key = base58.encode(xkey[:9] + i2 + xkey[13:]) self.assertRaises(ValueError, bip32.parse, invalid_key) # bip32.parse(invalid_key) # non-zero depth (255) with zero parent_fingerprint d2 = b'ff' invalid_key = base58.encode(xkey[:4] + d2 + xkey[5:]) self.assertRaises(ValueError, bip32.parse, invalid_key) # bip32.parse(invalid_key) # master key provided self.assertRaises(ValueError, bip32.parent_fingerprint, xkey) # bip32.parent_fingerprint(xkey) f = bip32.fingerprint(xkey) child_key = bip32.ckd(xkey, 0) f2 = bip32.parent_fingerprint(child_key) self.assertEqual(f, f2) # Derivation path final depth 256>255 self.assertRaises(ValueError, bip32.derive, child_key, "." + 255 * "/0") #bip32.derive(child_key, "."+255*"/0") # Empty derivation path self.assertRaises(ValueError, bip32.derive, child_key, "") #bip32.derive(child_key, "") # Invalid derivation path root: ";" self.assertRaises(ValueError, bip32.derive, child_key, ";/0") #bip32.derive(child_key, ";/0") # Derivation path depth 256>255 self.assertRaises(ValueError, bip32.derive, child_key, "." + 256 * "/0") #bip32.derive(child_key, "." + 256*"/0") # xkey is not a public one self.assertRaises(ValueError, bip32.p2pkh_address_from_xpub, xkey)
def test_wif(self): # https://en.bitcoin.it/wiki/Wallet_import_format prvkey = 0xC28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D uncompressedKey = b'\x80' + prvkey.to_bytes(32, byteorder='big') uncompressedWIF = b'5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ' wif = base58.encode(uncompressedKey) self.assertEqual(wif, uncompressedWIF) key = base58.decode(uncompressedWIF) self.assertEqual(key, uncompressedKey) compressedKey = b'\x80' + \ prvkey.to_bytes(32, byteorder='big') + b'\x01' compressedWIF = b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617' wif = base58.encode(compressedKey) self.assertEqual(wif, compressedWIF) key = base58.decode(compressedWIF) self.assertEqual(key, compressedKey) # string compressedWIF = b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617' key = base58.decode(compressedWIF) self.assertEqual(key, compressedKey)
print("\n*** [7] Base58 encoding") wif = base58._encode(checksummed_payload) print(wif) assert wif == b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617', "failure" assert base58.encode( payload ) == b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617', "failure" print("\n****** WIF to private key ******") print("\n*** [1] Base58 WIF") print(wif) compressed = len(wif) - 51 print("compressed" if (compressed == 1) else "uncompressed") print("\n*** [2] Base58 decoding") checksummed_payload = base58._decode(wif) print(checksummed_payload.hex()) print("\n*** [3] Extended key (checksum verified)") payload, checksum = checksummed_payload[:-4], checksummed_payload[-4:] verified = (sha256(sha256(payload).digest()).digest()[:4] == checksum) print(payload.hex() + " (" + ("true" if verified else "false") + ")") print(base58.decode(wif).hex()) print("\n*** [4] Private key") p2 = payload[1:-1].hex() if compressed else payload[1:].hex() assert int(p2, 16) == q, "failure" print(p2)
def hash_160_from_address(addr): return base58.decode(addr)[1:21]
print("\n*** [7] Base58 encoding") wif = base58.encode(checksummed_payload) print(wif) assert wif == b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617', "failure" assert base58.encode_check( payload ) == b'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617', "failure" print("\n****** WIF to private key ******") print("\n*** [1] Base58 WIF") print(wif) compressed = len(wif) - 51 print("compressed" if (compressed == 1) else "uncompressed") print("\n*** [2] Base58 decoding") checksummed_payload = base58.decode(wif) print(checksummed_payload.hex()) print("\n*** [3] Extended key (checksum verified)") payload, checksum = checksummed_payload[:-4], checksummed_payload[-4:] verified = (sha256(sha256(payload).digest()).digest()[:4] == checksum) print(payload.hex() + " (" + ("true" if verified else "false") + ")") print(base58.decode_check(wif).hex()) print("\n*** [4] Private key") p2 = payload[1:-1].hex() if compressed else payload[1:].hex() assert int(p2, 16) == q, "failure" print(p2)
def test_empty(self): self.assertEqual(base58.encode(b''), b'') self.assertEqual(base58.decode(b''), b'') self.assertEqual(base58.decode(base58.encode(b'')), b'') self.assertEqual(base58.encode(base58.decode(b'')), b'')
def test_mainnet(self): # bitcoin core derivation style rootxprv = b'xprv9s21ZrQH143K2ZP8tyNiUtgoezZosUkw9hhir2JFzDhcUWKz8qFYk3cxdgSFoCMzt8E2Ubi1nXw71TLhwgCfzqFHfM5Snv4zboSebePRmLS' # m/0'/0'/463' addr1 = b'1DyfBWxhVLmrJ7keyiHeMbt7N3UdeGU4G5' indexes = [0x80000000, 0x80000000, 0x80000000 + 463] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(rootxprv, indexes))) self.assertEqual(addr, addr1) path = "m/0'/0'/463'" addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(rootxprv, path))) self.assertEqual(addr, addr1) # m/0'/0'/267' addr2 = b'11x2mn59Qy43DjisZWQGRResjyQmgthki' indexes = [0x80000000, 0x80000000, 0x80000000 + 267] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(rootxprv, indexes))) self.assertEqual(addr, addr2) path = "m/0'/0'/267'" addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(rootxprv, path))) self.assertEqual(addr, addr2) xkey_version = bip32._PRV_VERSIONS[0] seed = "bfc4cbaad0ff131aa97fa30a48d09ae7df914bcc083af1e07793cd0a7c61a03f65d622848209ad3366a419f4718a80ec9037df107d8d12c19b83202de00a40ad" seed = bytes.fromhex(seed) xprv = bip32.rootxprv_from_seed(seed, xkey_version) xpub = b'xpub661MyMwAqRbcFMYjmw8C6dJV97a4oLss6hb3v9wTQn2X48msQB61RCaLGtNhzgPCWPaJu7SvuB9EBSFCL43kTaFJC3owdaMka85uS154cEh' self.assertEqual(bip32.xpub_from_xprv(xprv), xpub) ind = [0, 0] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'1FcfDbWwGs1PmyhMVpCAhoTfMnmSuptH6g') ind = [0, 1] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'1K5GjYkZnPFvMDTGaQHTrVnd8wjmrtfR5x') ind = [0, 2] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'1PQYX2uN7NYFd7Hq22ECMzfDcKhtrHmkfi') ind = [1, 0] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'1BvSYpojWoWUeaMLnzbkK55v42DbizCoyq') ind = [1, 1] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'1NXB59hF4QzYpFrB7o6usLBjbk2D3ZqxAL') ind = [1, 2] addr = bip32.p2pkh_address_from_xpub( bip32.xpub_from_xprv(bip32.derive(xprv, ind))) self.assertEqual(addr, b'16NLYkKtvYhW1Jp86tbocku3gxWcvitY1w') # version/key mismatch in extended parent key temp = base58.decode(rootxprv) bad_xprv = base58.encode(temp[0:45] + b'\x01' + temp[46:]) self.assertRaises(ValueError, bip32.ckd, bad_xprv, 1) #bip32.ckd(bad_xprv, 1) # version/key mismatch in extended parent key xpub = bip32.xpub_from_xprv(rootxprv) temp = base58.decode(xpub) bad_xpub = base58.encode(temp[0:45] + b'\x00' + temp[46:]) self.assertRaises(ValueError, bip32.ckd, bad_xpub, 1) #bip32.ckd(bad_xpub, 1) # no private/hardened derivation from pubkey self.assertRaises(ValueError, bip32.ckd, xpub, 0x80000000)