Ejemplo n.º 1
0
    def test_wif_exceptions(self):

        # not a 32-bytes private key
        badq = 33 * b'\x02'
        self.assertRaises(ValueError, wif_from_prvkey, badq, True)
        #wif_from_prvkey(badq, True)

        # private key not in (0, n)
        badq = ec.n
        self.assertRaises(ValueError, wif_from_prvkey, badq, True)
        #wif_from_prvkey(badq, True)

        # Not a private key WIF: missing leading 0x80
        payload = b'\x81' + octets_from_int(badq, ec.psize)
        badwif = base58.encode(payload)
        self.assertRaises(ValueError, prvkey_from_wif, badwif)
        #prvkey_from_wif(badwif)

        # Not a compressed WIF: missing trailing 0x01
        payload = b'\x80' + octets_from_int(badq, ec.psize) + b'\x00'
        badwif = base58.encode(payload)
        self.assertRaises(ValueError, prvkey_from_wif, badwif)
        #prvkey_from_wif(badwif)

        # Not a WIF: wrong size (35)
        payload = b'\x80' + octets_from_int(badq, ec.psize) + b'\x01\x00'
        badwif = base58.encode(payload)
        self.assertRaises(ValueError, prvkey_from_wif, badwif)
        #prvkey_from_wif(badwif)

        # Not a WIF: private key not in (0, n)
        payload = b'\x80' + octets_from_int(badq, ec.psize)
        badwif = base58.encode(payload)
        self.assertRaises(ValueError, prvkey_from_wif, badwif)
Ejemplo n.º 2
0
    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_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')
Ejemplo n.º 5
0
    def test_exceptions(self):

        # Invalid base58 address prefix b'\xf5'
        payload = b'\xf5'
        pubkey = '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352'
        payload += hash160(pubkey)
        invalid_address = base58.encode(payload)
        self.assertRaises(ValueError, h160_from_base58_address,
                          invalid_address)
        #_h160_from_base58_address(invalid_address)

        # Invalid SEC pubkey length: 34-bytes
        self.assertRaises(ValueError, p2pkh_address, pubkey + '00')
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    def test_exceptions(self):
        # int is not hex-string or bytes
        self.assertRaises(TypeError, base58.encode, 3)

        encoded = base58.encode(b"test")

        # unexpected decoded length
        wrong_length = len(encoded) - 1
        self.assertRaises(ValueError, base58.decode, encoded, wrong_length)

        # checksum is invalid
        invalidChecksum = encoded[:-4] + b'1111'
        self.assertRaises(ValueError, base58.decode, invalidChecksum, 4)

        # non-ascii character
        self.assertRaises(ValueError, base58.decode, "hèllo world")
Ejemplo n.º 8
0
def address_from_pubkey_bytes(inp, version=b'\x00'):
    vh160 = version + hash160(inp)
    return base58.encode(vh160)
Ejemplo n.º 9
0
print(h4.hex())

print(
    "\n*** [7] First 4 bytes of the second SHA-256 hash used as address checksum:"
)
print(h4[:4].hex())

print("\n*** [8] checksum added at the end of extended RIPEMD-160 hash:")
addr = vh160 + h4[:4]
print(addr.hex())

print("\n*** [9] Base58 encoded address from uncompressed PubKey")
address = base58._encode(addr)
print(address)
assert (address == b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM')
assert (base58.encode(vh160) == b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM')

print("\n*** steps [5]-[9] are also known as Base58Check encode")


def pubkey_bytes_from_prvkey(prvkey, compressed=True):
    PubKey = mult(prvkey)
    if compressed:
        prefix = b'\x02' if (PubKey[1] % 2 == 0) else b'\x03'
        return prefix + PubKey[0].to_bytes(32, byteorder='big')
    else:
        prefix = b'\x04'
        return prefix + PubKey[0].to_bytes(32, byteorder='big') + \
                        PubKey[1].to_bytes(32, byteorder='big')

Ejemplo n.º 10
0
h1 = sha256(payload).digest()
print(h1.hex())

print("\n*** [4] SHA-256 hashing of the SHA-256:")
h2 = sha256(h1).digest()
print(h2.hex())

print("\n*** [5] First 4 bytes of the double SHA-256 used as checksum:")
print(h2[:4].hex())

print("\n*** [6] checksum added at the end of extended key:")
checksummed_payload = payload + h2[:4]
print(checksummed_payload.hex())

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)
Ejemplo n.º 11
0
print("\n*** [6] SHA-256 hashing of the result of the previous SHA-256 hash:")
h4 = hashlib.sha256(h3).digest()
print(h4.hex())

print(
    "\n*** [7] First 4 bytes of the second SHA-256 hash used as address checksum:"
)
print(h4[:4].hex())

print("\n*** [8] checksum added at the end of extended RIPEMD-160 hash:")
addr = vh160 + h4[:4]
print(addr.hex())

print("\n*** [9] Base58 encoded address from uncompressed PubKey")
address = base58.encode(addr)
assert (address == b'16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM')
print(address)

print("\n*** steps [5]-[9] are also known as Base58Check encode")


def pubkey_bytes_from_prvkey(prvkey, compressed=True):
    PubKey = mult(ec, prvkey, ec.G)
    if compressed:
        prefix = b'\x02' if (PubKey[1] % 2 == 0) else b'\x03'
        return prefix + PubKey[0].to_bytes(32, byteorder='big')
    else:
        prefix = b'\x04'
        return prefix + PubKey[0].to_bytes(32, byteorder='big') + \
                        PubKey[1].to_bytes(32, byteorder='big')
 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'')
Ejemplo n.º 13
0
    def test_exceptions(self):
        # valid xprv
        xprv = b'xprv9s21ZrQH143K2oxHiQ5f7D7WYgXD9h6HAXDBuMoozDGGiYHWsq7TLBj2yvGuHTLSPCaFmUyN1v3fJRiY2A4YuNSrqQMPVLZKt76goL6LP7L'

        # master key provided
        self.assertRaises(ValueError, bip32.index, xprv)
        # bip32.index(xprv)

        # invalid index
        self.assertRaises(ValueError, bip32.ckd, xprv, 'invalid index')
        #bip32.ckd(xprv, 'invalid index')

        # a 4 bytes int is required, not 3
        self.assertRaises(ValueError, bip32.ckd, xprv, "800000")
        #bip32.ckd(xprv, "800000")

        # Invalid derivation path root: ""
        self.assertRaises(ValueError, bip32.derive, xprv, '/1')
        #bip32.derive(xprv, '/1')

        # object of type 'int' has no len()
        self.assertRaises(TypeError, bip32.derive, xprv, 1)
        #bip32.derive(xprv, 1)

        # invalid checksum
        xprv = b'xppp9s21ZrQH143K2oxHiQ5f7D7WYgXD9h6HAXDBuMoozDGGiYHWsq7TLBj2yvGuHTLSPCaFmUyN1v3fJRiY2A4YuNSrqQMPVLZKt76goL6LP7L'
        self.assertRaises(ValueError, bip32.ckd, xprv, 0x80000000)
        #bip32.ckd(xprv, 0x80000000)

        # invalid extended key version
        version = b'\x04\x88\xAD\xE5'
        xkey = version + b'\x00' * 74
        xkey = base58.encode(xkey)
        self.assertRaises(ValueError, bip32.ckd, xkey, 0x80000000)
        #bip32.ckd(xkey, 0x80000000)

        # invalid private version
        version = b'\x04\x88\xAD\xE5'
        seed = "5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39a88b76373733891bfaba16ed27a813ceed498804c0570"
        self.assertRaises(ValueError, bip32.rootxprv_from_seed, seed, version)
        #bip32.rootxprv_from_seed(seed, version)

        # extended key is not a private one
        xpub = b'xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy'
        self.assertRaises(ValueError, bip32.xpub_from_xprv, xpub)
        # bip32.xpub_from_xprv(xpub)

        # Absolute derivation path for non-master key
        self.assertRaises(ValueError, bip32.derive, xpub, "m/44'/0'/1'/0/10")
        #bip32.derive(xpub, "m/0/1")

        # empty derivation path
        self.assertRaises(ValueError, bip32.derive, xpub, "")
        #bip32.derive(xpub, "")

        # extended key is not a public one
        self.assertRaises(ValueError, bip32.p2pkh_address_from_xpub, xprv)
        # bip32.p2pkh_address_from_xpub(xprv)

        # xkey is not a public one
        xprv = b'xprv9s21ZrQH143K2ZP8tyNiUtgoezZosUkw9hhir2JFzDhcUWKz8qFYk3cxdgSFoCMzt8E2Ubi1nXw71TLhwgCfzqFHfM5Snv4zboSebePRmLS'
        self.assertRaises(ValueError, bip32.address_from_xpub, xprv)
        # bip32.address_from_xpub(xprv)
        self.assertRaises(ValueError, bip32.p2wpkh_address_from_xpub, xprv)
        # bip32.p2wpkh_address_from_xpub(xprv)
        self.assertRaises(ValueError, bip32.p2wpkh_p2sh_address_from_xpub,
                          xprv)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
child_number = b'\x00\x00\x00\x00'
# the fingerprint of the parent's public key (0x00000000 if master key)
fingerprint  = b'\x00\x00\x00\x00'
idf = depth + fingerprint + child_number

# master private key, master public key, chain code
hd = HMAC(b"Bitcoin seed", seed.to_bytes(seed_bytes, byteorder='big'), sha512).digest()
qbytes = hd[:32]
q = int(qbytes.hex(), 16) % ec.n
qbytes = b'\x00' + q.to_bytes(32, byteorder='big')
Q = mult(q, ec.G)
Qbytes = octets_from_point(Q, True)
chain_code = hd[32:]

#extended keys
ext_prv = encode(xprv + idf + chain_code + qbytes)
print("\nm")
print(ext_prv)
ext_pub = encode(xpub + idf + chain_code + Qbytes)
print("M")
print(ext_pub)
assert ext_prv == b"xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi", "failure"
assert ext_pub == b"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", "failure"

# ==first (0) hardened child==
depth = b'\x01'
child_n = 0 + 0x80000000 #hardened
child_number = child_n.to_bytes(4, byteorder='big')
fingerprint = h160(Qbytes)[:4]
idf = depth + fingerprint + child_number
Ejemplo n.º 16
0
h2 = sha256(h1).digest()
print(h2.hex())

print("\n*** [5] First 4 bytes of the double SHA-256 used as checksum:")
print(h2[:4].hex())

print("\n*** [6] checksum added at the end of extended key:")
checksummed_payload = payload + h2[:4]
print(checksummed_payload.hex())

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:]
Ejemplo n.º 17
0
h2 = sha256(h1).digest()
print(h2.hex())

print("\n*** [5] First 4 bytes of the double SHA-256 used as checksum:")
print(h2[:4].hex())

print("\n*** [6] checksum added at the end of the payload:")
checksummed_payload = payload + h2[:4]
print(checksummed_payload.hex())

print("\n*** [7] Base58 encoding")
wif = base58._encode(checksummed_payload)
print(wif)
assert wif == b'5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', "failure"
assert base58.encode(
    payload
) == b'5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ', "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] payload (checksum verified)")
payload, checksum = checksummed_payload[:-4], checksummed_payload[-4:]