def from_master_key(text): if is_xprv(text): k = from_xprv(text) elif is_old_mpk(text): k = from_old_mpk(text) elif is_xpub(text): k = from_xpub(text) else: raise BitcoinException('Invalid master key') return k
def deserialize_xkey(xkey, prv, *, net=None): if net is None: net = constants.net xkey = DecodeBase58Check(xkey) if len(xkey) != 78: raise BitcoinException('Invalid length for extended key: {}'.format( len(xkey))) depth = xkey[4] fingerprint = xkey[5:9] child_number = xkey[9:13] c = xkey[13:13 + 32] header = int('0x' + bh2u(xkey[0:4]), 16) headers = net.XPRV_HEADERS if prv else net.XPUB_HEADERS if header not in headers.values(): raise BitcoinException('Invalid extended key format: {}'.format( hex(header))) xtype = list(headers.keys())[list(headers.values()).index(header)] n = 33 if prv else 32 K_or_k = xkey[13 + n:] if prv and not ecc.is_secret_within_curve_range(K_or_k): raise BitcoinException('Impossible xprv (not within curve order)') return xtype, depth, fingerprint, child_number, c, K_or_k
def deserialize_privkey(key: str) -> (str, bytes, bool): if is_minikey(key): return 'p2pkh', minikey_to_private_key(key), True txin_type = None if ':' in key: txin_type, key = key.split(sep=':', maxsplit=1) if txin_type not in SCRIPT_TYPES: raise BitcoinException('unknown script type: {}'.format(txin_type)) try: vch = DecodeBase58Check(key) except BaseException: neutered_privkey = str(key)[:3] + '..' + str(key)[-2:] raise BitcoinException( "cannot deserialize privkey {}".format(neutered_privkey)) if txin_type is None: # keys exported in version 3.0.x encoded script type in first byte prefix_value = vch[0] - constants.net.WIF_PREFIX inverse_script_types = inv_dict(SCRIPT_TYPES) try: txin_type = inverse_script_types[prefix_value] except KeyError: raise BitcoinException( 'invalid prefix ({}) for WIF key (1)'.format(vch[0])) else: # all other keys must have a fixed first byte if vch[0] != constants.net.WIF_PREFIX: raise BitcoinException( 'invalid prefix ({}) for WIF key (2)'.format(vch[0])) if len(vch) not in [33, 34]: raise BitcoinException('invalid vch len for WIF key: {}'.format( len(vch))) compressed = len(vch) == 34 secret_bytes = vch[1:33] # we accept secrets outside curve range; cast into range here: secret_bytes = ecc.ECPrivkey.normalize_secret_bytes(secret_bytes) return txin_type, secret_bytes, compressed
def serialize_xprv(xtype, c, k, depth=0, fingerprint=b'\x00' * 4, child_number=b'\x00' * 4, *, net=None): if not ecc.is_secret_within_curve_range(k): raise BitcoinException('Impossible xprv (not within curve order)') xprv = xprv_header(xtype, net=net) \ + bytes([depth]) + fingerprint + child_number + c + bytes([0]) + k return EncodeBase58Check(xprv)
def address_to_script(addr, *, net=None): if net is None: net = constants.net witver, witprog = segwit_addr.decode(net.SEGWIT_HRP, addr) if witprog is not None: if not (0 <= witver <= 16): raise BitcoinException( 'impossible witness version: {}'.format(witver)) OP_n = witver + 0x50 if witver > 0 else 0 script = bh2u(bytes([OP_n])) script += push_script(bh2u(bytes(witprog))) return script addrtype, hash_160 = b58_address_to_hash160(addr) if addrtype == net.ADDRTYPE_P2PKH: script = '76a9' # op_dup, op_hash_160 script += push_script(bh2u(hash_160)) script += '88ac' # op_equalverify, op_checksig elif addrtype == net.ADDRTYPE_P2SH: script = 'a9' # op_hash_160 script += push_script(bh2u(hash_160)) script += '87' # op_equal else: raise BitcoinException('unknown address type: {}'.format(addrtype)) return script
def deserialize_drk(xkey, prv, *, net=None): if net is None: net = constants.net xkey = DecodeBase58Check(xkey) if len(xkey) != 78: raise BitcoinException('Invalid length for extended key: {}'.format( len(xkey))) depth = xkey[4] fingerprint = xkey[5:9] child_number = xkey[9:13] c = xkey[13:13 + 32] header = int('0x' + bh2u(xkey[0:4]), 16) if prv and header != net.DRKV_HEADER: raise BitcoinException('Invalid extended key format: {}'.format( hex(header))) if not prv and header != net.DRKP_HEADER: raise BitcoinException('Invalid extended key format: {}'.format( hex(header))) xtype = 'standard' n = 33 if prv else 32 K_or_k = xkey[13 + n:] if prv and not ecc.is_secret_within_curve_range(K_or_k): raise BitcoinException('Impossible drkv (not within curve order)') return xtype, depth, fingerprint, child_number, c, K_or_k
def address_to_script(addr, *, net=None): if net is None: net = constants.net addrtype, hash_160 = b58_address_to_hash160(addr) if addrtype == net.ADDRTYPE_P2PKH: script = '76a9' # op_dup, op_hash_160 script += push_script(bh2u(hash_160)) script += '88ac' # op_equalverify, op_checksig elif addrtype == net.ADDRTYPE_P2SH: script = 'a9' # op_hash_160 script += push_script(bh2u(hash_160)) script += '87' # op_equal else: raise BitcoinException('unknown address type: {}'.format(addrtype)) return script
def from_seed(seed, passphrase, is_p2sh): t = seed_type(seed) if t == 'old': keystore = Old_KeyStore({}) keystore.add_seed(seed) elif t in ['standard']: keystore = BIP32_KeyStore({}) keystore.add_seed(seed) keystore.passphrase = passphrase bip32_seed = Mnemonic.mnemonic_to_seed(seed, passphrase) der = "m/" xtype = 'standard' keystore.add_xprv_from_seed(bip32_seed, xtype, der) else: raise BitcoinException('Unexpected seed type {}'.format(t)) return keystore
def _CKD_priv(k, c, s, is_prime): try: keypair = ecc.ECPrivkey(k) except ecc.InvalidECPointException as e: raise BitcoinException( 'Impossible xprv (not within curve order)') from e cK = keypair.get_public_key_bytes(compressed=True) data = bytes([0]) + k + s if is_prime else cK + s I = hmac_oneshot(c, data, hashlib.sha512) I_left = ecc.string_to_number(I[0:32]) k_n = (I_left + ecc.string_to_number(k)) % ecc.CURVE_ORDER if I_left >= ecc.CURVE_ORDER or k_n == 0: raise ecc.InvalidECPointException() k_n = ecc.number_to_string(k_n, ecc.CURVE_ORDER) c_n = I[32:] return k_n, c_n
def xpubkey_to_address(x_pubkey): if x_pubkey[0:2] == 'fd': address = bitcoin.script_to_address(x_pubkey[2:]) return x_pubkey, address if x_pubkey[0:2] in ['02', '03', '04']: pubkey = x_pubkey elif x_pubkey[0:2] == 'ff': xpub, s = BIP32_KeyStore.parse_xpubkey(x_pubkey) pubkey = BIP32_KeyStore.get_pubkey_from_xpub(xpub, s) elif x_pubkey[0:2] == 'fe': mpk, s = Old_KeyStore.parse_xpubkey(x_pubkey) pubkey = Old_KeyStore.get_pubkey_from_mpk(mpk, s[0], s[1]) else: raise BitcoinException("Cannot parse pubkey. prefix: {}".format( x_pubkey[0:2])) if pubkey: address = public_key_to_p2pkh(bfh(pubkey)) return pubkey, address