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" ) if not self.testnet: version = param_query(NETWORK, 'hd_prv')[0] if private else param_query( NETWORK, 'hd_pub')[0] else: version = EX_TEST_PRIVATE[0] if private else EX_TEST_PUBLIC[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)
def WalletImportFormat(self): "Returns private key encoded for wallet import" if self.public: raise Exception( "Publicly derived deterministic keys have no private half") addressversion = param_query( NETWORK, 'wif_version') if not self.testnet else '\xef' raw = addressversion + self.k.to_string() + '\x01' # Always compressed return base58.check_encode(raw)
def fromExtendedKey(xkey, public=False,encoded=True): """ Create a HDKey by importing from extended private or public key string If public is True, return a public-only key regardless of input type. """ # Sanity checks if encoded: raw = base58.check_decode(xkey) else: raw = xkey if len(raw) != 78: raise ValueError("extended key format wrong length") # Verify address version/type version = raw[:4] if version in param_query(NETWORK,'hd_prv'): is_testnet = False is_pubkey = False elif version in EX_TEST_PRIVATE: is_testnet = True is_pubkey = False elif version in param_query(NETWORK,'hd_pub'): is_testnet = False is_pubkey = True elif version in EX_TEST_PUBLIC: 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 = HDKey(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
def Address(self, ip = False): "Return compressed public key address" addressversion = param_query(NETWORK,'address_version') if not ip else '\x66' vh160 = addressversion + self.Identifier() return base58.check_encode(vh160)
def parameters(self): '''load network parameters.''' return param_query(self.net)