예제 #1
0
    def from_base58(cls, encoded):
        """
        Creates a new HDNode from a extended key (xpub/xpriv)

        :param encoded: a base58check string
        :return: a new HDNode object
        """
        buffer = base58.b58decode_check(encoded)
        if len(buffer) != 78:
            raise ValueError("Invalid argument")
        version = int.from_bytes(buffer[:4], "big")
        n = [
            x for x in Network.get_supported_networks()
            if version in [x.version_pub, x.version_priv]
        ]
        if not n:
            raise ValueError("Network not supported")
        network = n[0]
        depth = buffer[4]
        parent_fingerprint = int.from_bytes(buffer[5:9], "big")
        index = int.from_bytes(buffer[9:13], "big")
        chain_code = buffer[13:45]
        key = buffer[45:]

        if version == network.version_pub:
            key_pair = ECPair(None, pubkey_buffer=key, network=network)
        else:
            #validate key[0] == 0x00
            key_pair = ECPair(key[1:], None, network=network)
        return cls(key_pair,
                   chain_code,
                   depth=depth,
                   index=index,
                   parent_fingerprint=parent_fingerprint)
예제 #2
0
 def test_to_wif_compressed_testnet(self):
     ecpair = ECPair(
         'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45',
         network=BITCOIN_TESTNET)
     self.assertEqual(
         ecpair.to_wif(),
         'cTqKweNhVkMznPiVgucDxYxer9qWDW3dY7xKq2JPbFgoQK8xhYqi')
예제 #3
0
 def test_to_wif_uncompressed(self):
     ecpair_uncomp = ECPair(
         'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45',
         compressed=False)
     self.assertEqual(
         ecpair_uncomp.to_wif(),
         '5KESiB48wksvA4141nwrJGjjC5szu81fd3T2J8SaKqVW2zmxdCr')
예제 #4
0
 def test_sign_verify_fail(self):
     wif = 'L3ULUjNr4gfjcxFEJVo6bETbDvY6Z3wwU5oribqt692o9a5SHV2R'
     wif2 = 'L3tJ46CAEaWr7YF5CZ6a1qg1cuhpeJEak5cr3esiVWA3To9PjWvn'
     ecpair = ECPair.from_wif(wif)
     ecpair2 = ECPair.from_wif(wif2)
     buffer = sha256(b"I am Satoshi Nakamoto")
     signature = ecpair.sign(buffer)
     self.assertFalse(ecpair2.verify(buffer, signature))
예제 #5
0
 def test_to_wif_uncompressed_testnet(self):
     ecpair_uncomp = ECPair(
         'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45',
         network=BITCOIN_TESTNET,
         compressed=False)
     self.assertEqual(
         ecpair_uncomp.to_wif(),
         '9315HusgXyx487WLe8qmAsHgqkEi4HYrxzJyNko5faEYp1dL1wL')
예제 #6
0
    def derive(self, index):
        """
        Child Extended Key Derivation.
        Given the parent extended key and an index, computes the corresponding
        child extended key.

        :param index: index for derivation
        :return: HDNode child
        """
        buffer = b""
        network = self.keypair.network
        hardened = index >= HARDENED_BIT

        if hardened:
            # hardened derivation
            if self.is_neutered():
                raise RuntimeError(
                    "Neutered node cannot derive hardnened child")
            buffer += b"\x00"
            buffer += self.keypair.privkey_buffer
            buffer += index.to_bytes(4, "big")
        else:
            # normal derivation
            buffer += self.keypair.pubkey_buffer
            buffer += index.to_bytes(4, "big")

        i = hashutils.hmac_sha512(self.chain_code, buffer)
        il = i[:32]  # key
        ir = i[32:]  # chaincode
        parse256_il = int.from_bytes(il, "big")  # parse256(IL)

        # In case parse256(IL) >= n
        if parse256_il >= ecutils.ORDER:
            return self.derive(index + 1)

        if self.is_neutered():
            # Public parent key ---> public child key
            try:
                pubkey_buf = ecutils.combine_pubkeys(
                    parse256_il, self.keypair.pubkey_buffer)
            except ValueError:  # POINT AT INFINITY
                return self.derive(index + 1)
            derived = ECPair(None, pubkey_buf, network=network)
        else:
            # private parent key ---> private child key
            new_key = (parse256_il + self.keypair.privkey) % ecutils.ORDER
            if new_key == 0:
                return self.derive(index + 1)
            derived = ECPair(new_key.to_bytes(32, "big"),
                             None,
                             network=network)

        return self.__class__(derived,
                              chaincode=ir,
                              depth=self.depth + 1,
                              index=index,
                              parent_fingerprint=int.from_bytes(
                                  self.get_fingerprint(), "big"))
예제 #7
0
 def test_msg2(self):
     m = b"A purely peer-to-peer version of electronic cash would allow " \
         b"online payments"
     r = 53416277923213062165260564277038918077705079659558875401218116132761110201958
     s = 86605321333558372720412441800808448223714537838874906966097860970072205178705
     ecpair = ECPair(privkey='45d0475126e983f3162c98b73d93585e9c7be66220ba1e95dae87bbbff2fb40e')
     self.assertVerify(ecpair.pubkey_buffer, r, s, m)
예제 #8
0
 def test_msg3(self):
     m = b"What is needed is an electronic payment system based on " \
         b"cryptographic proof instead of trust"
     r = 68734943327797312301443474635907363454601483827607971122239706615210184455578
     s = 101235560920937280916292394003527251888819329338326063465504738929993008856598
     ecpair = ECPair(privkey='eb2bc889499f757cc135bd2da7aea647b3132a2dd330d1ed033d731a4cf2a737')
     self.assertVerify(ecpair.pubkey_buffer, r, s, m)
예제 #9
0
 def test_msg1(self):
     # https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html
     m = b"Bitcoin: A Peer-to-Peer Electronic Cash System"
     r = 16585169871999922969978897389792393736153195404500074220463475545187239063880
     s = 101989596681849864701598391615792467471854786825375833846457837318456308008154
     ecpair = ECPair(privkey='73d286994b2ac1a0f160fb45816c1dd6605551eb0ea12d5595a440a3665ef89d')
     self.assertVerify(ecpair.pubkey_buffer, r, s, m)
예제 #10
0
 def assert_sign_verify(self, wif, message):
     ecpair = ECPair.from_wif(wif)
     buffer = sha256(message)
     wrong_message = message[1:]
     signature = ecpair.sign(buffer)
     self.assertTrue(ecpair.verify(buffer, signature))
     self.assertFalse(ecpair.verify(sha256(wrong_message), signature))
예제 #11
0
 def test_from_wif_uncompressed(self):
     ecpair = ECPair.from_wif(
         '5KESiB48wksvA4141nwrJGjjC5szu81fd3T2J8SaKqVW2zmxdCr')
     self.assertEqual(
         ecpair.privkey,
         int(
             'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45',
             16))
     self.assertFalse(ecpair.compressed)
예제 #12
0
 def test_from_wif_compressed(self):
     ecpair = ECPair.from_wif(
         'L3ULUjNr4gfjcxFEJVo6bETbDvY6Z3wwU5oribqt692o9a5SHV2R')
     self.assertEqual(
         ecpair.privkey,
         int(
             'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45',
             16))
     self.assertTrue(ecpair.compressed)
예제 #13
0
 def test_constructor_invalid_fingerprint(self):
     privkey_hexa = "4ccbf2a1c6ee9a5106cb19c6be343947701a4e4acb2c4311f5"\
                    "a10836109711a1"
     number = int(privkey_hexa, 16)
     ecpair = ECPair(number)
     with self.assertRaises(ValueError):
         HDNode(ecpair, chaincode=b'\x1a\xbe\xc1YTQ\xa3\xe7\xb5\xfet'
                                  b'\xad5)\x06\x99\x81x,R\xd7L\x1e$\x10'
                                  b'\xc4\xf5\x1e\xa2\x08oO',
                depth=0, index=0, parent_fingerprint=123)
예제 #14
0
    def neutered(self):
        """
        Returns a new node without the private key. (Removes the privkey)

        :return: a neutered HDNode
        """
        pub_key_buffer = self.keypair.pubkey_buffer
        # removing private key
        new_ecpair = ECPair(None, pub_key_buffer, network=self.keypair.network)
        return self.__class__(new_ecpair, self.chain_code, self.depth,
                              self.index, self.parent_fingerprint)
예제 #15
0
    def from_seed(cls, seed_bytes, network=DEFAULT_NETWORK):
        """
        Creates a new HDNode from a bip39 seed

        :param seed_bytes: binary bip39 seed
        :param network: Network object
        :return: new HDNode object
        """
        h = hashutils.hmac_sha512(BITCOIN_SEED, seed_bytes)
        privkey = h[:32]  # left
        chaincode = h[32:]  # right
        return cls(ECPair(privkey, network=network), chaincode)
예제 #16
0
 def test_from_wif_invalid(self):
     # 32 bytes
     with self.assertRaises(ValueError):
         ECPair.from_wif(
             'mdWSTVi6STwH9sLTF2zhRAg7AJUMKQsDgMeDc6sjaTgV7miXA')
     # 35 bytes
     with self.assertRaises(ValueError):
         ECPair.from_wif(
             '3Yi64vA349642Ch7sPXUcpdDNmmfQg7XAw3bx1mVNL6hCQrFV4XQgy')
     # 34 bytes not started with \x01
     with self.assertRaises(ValueError):
         ECPair.from_wif(
             'LWjVhLCGgaLZ3stB33SWvSFAvtkKWjsqET84r9Se5E96smt318gK')
예제 #17
0
 def test_create_pass_both_keys(self):
     number = int(PRIVKEY_HEXA, 16)
     b = number.to_bytes(32, "big")
     with self.assertRaises(ValueError):
         ECPair(b, COMPRESSED_PUBKEY)
예제 #18
0
 def test_no_network(self):
     with self.assertRaises(ValueError):
         ECPair(PRIVKEY_HEXA, network=None)
예제 #19
0
 def test_msg4(self):
     m = b"Maarten Bodewes generated this test vector on 2016-11-08"
     r = int('241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795', 16)
     s = int('021006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e', 16)
     ecpair = ECPair(privkey='ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f')
     self.assertVerify(ecpair.pubkey_buffer, r, s, m)
예제 #20
0
 def test_unsupported_network(self):
     with self.assertRaises(ValueError):
         ECPair(PRIVKEY_HEXA, network=Network('a', 'b', 'c', 'd', 'e'))
예제 #21
0
 def test_pubkey_uncompressed(self):
     ecpair = ECPair(None, pubkey_buffer=UNCOMPRESSED_PUBKEY)
     self.assertIsNotNone(ecpair)
     self.assertFalse(ecpair.compressed)
예제 #22
0
 def test_to_wif_compressed(self):
     ecpair = ECPair(
         'ba8c65b5e47143979b3506a742b4bd95c1ddb419195915c3679e38e9bffbeb45')
     self.assertEqual(
         ecpair.to_wif(),
         'L3ULUjNr4gfjcxFEJVo6bETbDvY6Z3wwU5oribqt692o9a5SHV2R')
예제 #23
0
 def test_to_str(self):
     ecpair = ECPair(PRIVKEY_HEXA, compressed=True)
     a = "{}".format(ecpair)
예제 #24
0
 def test_arg_compressed_true(self):
     ecpair = ECPair(PRIVKEY_HEXA, compressed=True)
     self.assertIsNotNone(ecpair)
예제 #25
0
 def test_arg_compressed_false(self):
     ecpair = ECPair(True, compressed=False)
     self.assertIsNotNone(ecpair)
예제 #26
0
 def test_arg_invalid_privkey(self):
     with self.assertRaises(ValueError):
         ecpair = ECPair([], compressed=True)
     with self.assertRaises(ValueError):
         ecpair = ECPair(bytes(random.getrandbits(8) for _ in range(35)),
                         compressed=True)
예제 #27
0
 def test_pubkey_ignore_compressed_passed(self):
     ecpair2 = ECPair(None,
                      pubkey_buffer=COMPRESSED_PUBKEY,
                      compressed=False)
     self.assertIsNotNone(ecpair2)
     self.assertTrue(ecpair2.compressed)
예제 #28
0
 def test_no_keys(self):
     with self.assertRaises(ValueError):
         ECPair(None, pubkey_buffer=None)
예제 #29
0
 def test_arg_compressed_invalid(self):
     with self.assertRaises(ValueError):
         ecpair = ECPair(PRIVKEY_HEXA, compressed=1)
예제 #30
0
 def test_pubkey_invalid_type(self):
     with self.assertRaises(ValueError):
         ECPair(None, pubkey_buffer='a')