def __init__(self, pointer): logging.debug('Derive keys for subaccount={}, pointer={}'.format(subaccount, pointer)) self.subaccount = subaccount self.pointer = pointer # Derive the GreenAddress public key for this pointer value ga_key = gacommon.derive_hd_key(ga_xpub, [pointer, ], BIP32_FLAG_KEY_PUBLIC) self.ga_key = bip32_key_get_pub_key(ga_key) logging.debug("ga_key = {}".format(hex_from_bytes(self.ga_key))) # Derive the user private keys for this pointer value flags = BIP32_FLAG_KEY_PRIVATE user_key_paths = [(key, [pointer, ]) for key in user_keys] private_keys = [gacommon.derive_hd_key(*path, flags=flags) for path in user_key_paths] self.private_keys = [bip32_key_get_priv_key(key) for key in private_keys] # Derive the user public keys from the private keys user_public_keys = [ec_public_key_from_private_key(key) for key in self.private_keys] public_keys = [self.ga_key, ] + user_public_keys # Script could be segwit or not - generate both segwit and non-segwit addresses self.witnesses = {cls.type_: cls(public_keys, testnet) for cls in (P2SH, P2WSH)} logging.debug('p2sh address: {}'.format(self.witnesses['p2sh'].address)) logging.debug('p2wsh address: {}'.format(self.witnesses['p2wsh'].address))
def get_pubkey_for_pointer_hex(xpub): """Return hex encoded public key derived from xpub for pointer""" xpub = gacommon.derive_hd_key(xpub, [ pointer, ], BIP32_FLAG_KEY_PUBLIC) xpub = bip32_key_get_pub_key(xpub) return hex_from_bytes(xpub)
def createDerivedKeySet(ga_xpub, wallets, custom_xprv, testnet): """Return class instances which represent sets of derived keys Given a user's key material call createDerivedKeySet to create a class instances of which can be created by specifying the pointer value. Each such instance then represents a set of keys derived on the path specified by that pointer. """ # The GreenAddress extended public key (ga_xpub) also contains the subaccount index encoded # as the child_num subaccount = bip32_key_get_child_num(ga_xpub) # Given the subaccount the user keys can be derived. Optionally the user may provide a custom # extended private key as the backup user_keys = [derive_user_key(wallet, subaccount) for wallet in wallets] if custom_xprv: logging.debug("Using custom xprv") root_xprv = bip32_key_from_base58check(custom_xprv) branch = 1 xprv = gacommon.derive_hd_key(root_xprv, [branch, ], BIP32_FLAG_KEY_PRIVATE) user_keys.append(xprv) assert len(user_keys) == 2 class DerivedKeySet: """Represent sets of HD keys """ def __init__(self, pointer): logging.debug('Derive keys for subaccount={}, pointer={}'.format(subaccount, pointer)) self.subaccount = subaccount self.pointer = pointer # Derive the GreenAddress public key for this pointer value ga_key = gacommon.derive_hd_key(ga_xpub, [pointer, ], BIP32_FLAG_KEY_PUBLIC) self.ga_key = bip32_key_get_pub_key(ga_key) logging.debug("ga_key = {}".format(hex_from_bytes(self.ga_key))) # Derive the user private keys for this pointer value flags = BIP32_FLAG_KEY_PRIVATE user_key_paths = [(key, [pointer, ]) for key in user_keys] private_keys = [gacommon.derive_hd_key(*path, flags=flags) for path in user_key_paths] self.private_keys = [bip32_key_get_priv_key(key) for key in private_keys] # Derive the user public keys from the private keys user_public_keys = [ec_public_key_from_private_key(key) for key in self.private_keys] public_keys = [self.ga_key, ] + user_public_keys # Script could be segwit or not - generate both segwit and non-segwit addresses self.witnesses = {cls.type_: cls(public_keys, testnet) for cls in (P2SH, P2WSH)} logging.debug('p2sh address: {}'.format(self.witnesses['p2sh'].address)) logging.debug('p2wsh address: {}'.format(self.witnesses['p2wsh'].address)) return DerivedKeySet
def __init__(self, user_key, xpubs, a, testnet): subaccount = int(a["subaccount"]) pointer = int(a["pointer"]) logging.debug('Derive keys for subaccount={}, pointer={}'.format( subaccount, pointer)) self.subaccount = subaccount self.pointer = pointer # Derive the GreenAddress public key for this pointer value ga_key = gacommon.derive_hd_key(xpubs[0], [ pointer, ], BIP32_FLAG_KEY_PUBLIC) self.ga_key = bip32_key_get_pub_key(ga_key) logging.debug("ga_key = {}".format(hex_from_bytes(self.ga_key))) # Derive the user private keys for this pointer value flags = BIP32_FLAG_KEY_PRIVATE user_key_paths = [(user_key, [ pointer, ])] private_keys = [ gacommon.derive_hd_key(*path, flags=flags) for path in user_key_paths ] self.private_keys = [ bip32_key_get_priv_key(key) for key in private_keys ] # Derive the user public keys from the private keys user_public_keys = [ ec_public_key_from_private_key(key) for key in self.private_keys ] public_keys = [ self.ga_key, ] + user_public_keys self.witnesses = {"p2sh": P2SH(public_keys, testnet)} assert self.witnesses["p2sh"].address == a["ad"]
def derive_user_key(wallet, subaccount, branch=1): subaccount_path = gacommon.get_subaccount_path(subaccount) return gacommon.derive_hd_key(wallet, subaccount_path + [branch])
def get_pubkey_for_pointer_hex(xpub): """Return hex encoded public key derived from xpub for pointer""" xpub = gacommon.derive_hd_key(xpub, [pointer], wally.BIP32_FLAG_KEY_PUBLIC) return b2h(wally.bip32_key_get_pub_key(xpub))