Exemple #1
0
    def ExtendedKey(self,
                    private=True,
                    encoded=True,
                    bip=44,
                    cointype="bitcoin"):
        "Return extended private or public key as string, optionally Base58 encoded"
        if self.public is True and private is True:
            raise Exception(
                "Cannot export an extended private key from a public-only deterministic key"
            )

        version = query_ver(private=private,
                            bip=bip,
                            cointype=cointype,
                            testnet=self.testnet)[0]

        depth = bytes(bytearray([self.depth]))
        fpr = self.parent_fpr
        child = struct.pack('>L', self.index)
        chain = self.C
        if self.public is True or private is False:
            data = self.PublicKey()
        else:
            data = b'\x00' + self.PrivateKey()
        raw = version + depth + fpr + child + chain + data
        if not encoded:
            return raw
        else:
            return Base58.check_encode(raw)
Exemple #2
0
 def WalletImportFormat(self):
     "Returns private key encoded for wallet import"
     if self.public:
         raise Exception(
             "Publicly derived deterministic keys have no private half")
     raw = '\x80' + self.k.to_string() + '\x01'  # Always compressed
     return Base58.check_encode(raw)
Exemple #3
0
 def WalletImportFormat(self):
     "Returns private key encoded for wallet import"
     if self.public:
         raise Exception(
             "Publicly derived deterministic keys have no private half")
     addressversion = b'\x4c' if not self.testnet else b'\xef'
     raw = addressversion + self.k.to_string(
     ) + b'\x01'  # Always compressed
     return Base58.check_encode(raw)
Exemple #4
0
    def fromExtendedKey(xkey, public=False):
        """
        Create a BIP32Key by importing from extended private or public key string

        If public is True, return a public-only key regardless of input type.
        """
        # Sanity checks
        raw = Base58.check_decode(xkey)
        if len(raw) != 78:
            raise ValueError("extended key format wrong length")

        # Verify address version/type
        version = raw[:4]
        if version == EX_MAIN_PRIVATE:
            keytype = 'xprv'
        elif version == EX_MAIN_PUBLIC:
            keytype = 'xpub'
        else:
            raise ValueError("unknown extended key version")

        # Extract remaining fields
        depth = ord(raw[4])
        fpr = raw[5:9]
        child = struct.unpack(">L", raw[9:13])[0]
        chain = raw[13:45]
        secret = raw[45:78]

        # Extract private key or public key point
        if keytype == 'xprv':
            secret = secret[1:]
        else:
            # Recover public curve point from compressed key
            lsb = ord(secret[0]) & 1
            x = string_to_int(secret[1:])
            ys = (x**3 + 7) % FIELD_ORDER  # y^2 = x^3 + 7 mod p
            y = sqrt_mod(ys, FIELD_ORDER)
            if y & 1 != lsb:
                y = FIELD_ORDER - y
            point = ecdsa.ellipticcurve.Point(SECP256k1.curve, x, y)
            secret = ecdsa.VerifyingKey.from_public_point(point,
                                                          curve=SECP256k1)

        is_pubkey = (keytype == 'xpub')
        key = BIP32Key(secret=secret,
                       chain=chain,
                       depth=depth,
                       index=child,
                       fpr=fpr,
                       public=is_pubkey)
        if not is_pubkey and public:
            key = key.SetPublic()
        return key
Exemple #5
0
 def P2WPKHoP2SHAddress(self):
     "Return P2WPKH over P2SH segwit address"
     pk_bytes = self.PublicKey()
     assert len(pk_bytes) == 33 and (pk_bytes.startswith(b"\x02") or pk_bytes.startswith(b"\x03")), \
         "Only compressed public keys are compatible with p2sh-p2wpkh addresses. " \
         "See https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki."
     pk_hash = hashlib.new('ripemd160', sha256(pk_bytes).digest()).digest()
     push_20 = bytes.fromhex('0014')
     script_sig = push_20 + pk_hash
     address_bytes = hashlib.new('ripemd160',
                                 sha256(script_sig).digest()).digest()
     prefix = b"\xc4" if self.testnet else b"\x05"
     return Base58.check_encode(prefix + address_bytes)
Exemple #6
0
    def fromExtendedKey(xkey, public=False):
        """
        Create a BIP32Key by importing from extended private or public key string

        If public is True, return a public-only key regardless of input type.
        """
        # Sanity checks
        raw = Base58.check_decode(xkey)
        if len(raw) != 78:
            raise ValueError("extended key format wrong length")

        # Verify address version/type
        version = raw[:4]
        if version == EX_MAIN_PRIVATE:
            keytype = 'xprv'
        elif version == EX_MAIN_PUBLIC:
            keytype = 'xpub'
        else:
            raise ValueError("unknown extended key version")

        # Extract remaining fields
        depth = ord(raw[4])
        fpr = raw[5:9]
        child = struct.unpack(">L", raw[9:13])[0]
        chain = raw[13:45]
        secret = raw[45:78]

        # Extract private key or public key point
        if keytype == 'xprv':
            secret = secret[1:]
        else:
            # Recover public curve point from compressed key
            lsb = ord(secret[0]) & 1
            x = string_to_int(secret[1:])
            ys = (x**3+7) % FIELD_ORDER # y^2 = x^3 + 7 mod p
            y = sqrt_mod(ys, FIELD_ORDER)
            if y & 1 != lsb:
                y = FIELD_ORDER-y
            point = ecdsa.ellipticcurve.Point(SECP256k1.curve, x, y)
            secret = ecdsa.VerifyingKey.from_public_point(point, curve=SECP256k1)

        is_pubkey = (keytype == 'xpub')
        key = BIP32Key(secret=secret, chain=chain, depth=depth, index=child, fpr=fpr, public=is_pubkey)
        if not is_pubkey and public:
            key = key.SetPublic()
        return key
Exemple #7
0
 def ExtendedKey(self, private=True, encoded=True):
     "Return extended private or public key as string, optionally Base58 encoded"
     if self.public is True and private is True:
         raise Exception("Cannot export an extended private key from a public-only deterministic key")
     version = EX_MAIN_PRIVATE if private else EX_MAIN_PUBLIC
     depth = chr(self.depth)
     fpr = self.parent_fpr
     child = struct.pack('>L', self.index)
     chain = self.C
     if self.public is True or private is False:
         data = self.PublicKey()
     else:
         data = '\x00' + self.PrivateKey()
     raw = version+depth+fpr+child+chain+data
     if not encoded:
         return raw
     else:
         return Base58.check_encode(raw)
Exemple #8
0
 def ExtendedKey(self, private=True, encoded=True):
     "Return extended private or public key as string, optionally Base58 encoded"
     if self.public is True and private is True:
         raise Exception(
             "Cannot export an extended private key from a public-only deterministic key"
         )
     version = EX_MAIN_PRIVATE if private else EX_MAIN_PUBLIC
     depth = chr(self.depth)
     fpr = self.parent_fpr
     child = struct.pack('>L', self.index)
     chain = self.C
     if self.public is True or private is False:
         data = self.PublicKey()
     else:
         data = '\x00' + self.PrivateKey()
     raw = version + depth + fpr + child + chain + data
     if not encoded:
         return raw
     else:
         return Base58.check_encode(raw)
Exemple #9
0
 def Address(self):
     "Return compressed public key address"
     vh160 = '\x00' + self.Identifier()
     return Base58.check_encode(vh160)
Exemple #10
0
 def WalletImportFormat(self):
     "Returns private key encoded for wallet import"
     if self.public:
         raise Exception("Publicly derived deterministic keys have no private half")
     raw = '\xBF' + self.k.to_string() + '\x01' # Always compressed
     return Base58.check_encode(raw)
Exemple #11
0
 def Address(self):
     "Return compressed public key address"
     vh160 = chr(25) + self.Identifier()
     leadingzbytes = len(re_match('^\x00*', vh160).group(0))
     return 'B' * leadingzbytes + Base58.check_encode(vh160)
 def Address(self):
     "Return compressed public key address"
     vh160 = '\x00'+self.Identifier()
     return Base58.check_encode(vh160)
Exemple #13
0
 def Address(self):
     "Return compressed public key address"
     addressversion = b'\x42' if not self.testnet else b'\x6f'
     vh160 = addressversion + self.Identifier()
     return Base58.check_encode(vh160)
Exemple #14
0
    def fromExtendedKey(xkey, public=False):
        """
        Create a BIP32Key by importing from extended private or public key string

        If public is True, return a public-only key regardless of input type.
        """
        # Sanity checks
        raw = Base58.check_decode(xkey)
        if len(raw) != 78:
            raise ValueError("extended key format wrong length")

        # Verify address version/type
        version = raw[:4]
        tversion = codecs.encode(version, "hex")
        if tversion in query_lsit(testnet=False):
            is_testnet = False
            is_pubkey = False
        elif tversion in query_lsit(testnet=True):
            is_testnet = True
            is_pubkey = False
        elif tversion in query_lsit(public=True):
            is_testnet = False
            is_pubkey = True
        elif tversion in query_lsit(public=True, testnet=True):
            is_testnet = True
            is_pubkey = True
        else:
            raise ValueError("unknown extended key version")

        # Extract remaining fields
        # Python 2.x compatibility
        if type(raw[4]) == int:
            depth = raw[4]
        else:
            depth = ord(raw[4])
        fpr = raw[5:9]
        child = struct.unpack(">L", raw[9:13])[0]
        chain = raw[13:45]
        secret = raw[45:78]

        # Extract private key or public key point
        if not is_pubkey:
            secret = secret[1:]
        else:
            # Recover public curve point from compressed key
            # Python3 FIX
            lsb = secret[0] & 1 if type(
                secret[0]) == int else ord(secret[0]) & 1
            x = string_to_int(secret[1:])
            ys = (x**3 + 7) % FIELD_ORDER  # y^2 = x^3 + 7 mod p
            y = sqrt_mod(ys, FIELD_ORDER)
            if y & 1 != lsb:
                y = FIELD_ORDER - y
            point = ecdsa.ellipticcurve.Point(SECP256k1.curve, x, y)
            secret = ecdsa.VerifyingKey.from_public_point(point,
                                                          curve=SECP256k1)

        key = BIP32Key(secret=secret,
                       chain=chain,
                       depth=depth,
                       index=child,
                       fpr=fpr,
                       public=is_pubkey,
                       testnet=is_testnet)
        if not is_pubkey and public:
            key = key.SetPublic()
        return key
Exemple #15
0
 def Address(self):
     "Return compressed public key address"
     vh160 = chr(25) + self.Identifier()
     leadingzbytes = len(re_match('^\x00*', vh160).group(0))
     return 'B' * leadingzbytes + Base58.check_encode(vh160)