def DecodeBase58Check(psz): vchRet = base_decode(psz, None, base=58) key = vchRet[0:-4] csum = vchRet[-4:] hash = Hash(key) cs32 = hash[0:4] if cs32 != csum: raise InvalidChecksum('expected {}, actual {}'.format( bh2u(cs32), bh2u(csum))) else: return key
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 parse(self, r): if self.error: return self.id = bh2u(util.sha256(r)[0:16]) try: self.data = pb2.PaymentRequest() self.data.ParseFromString(r) except: self.error = "cannot parse payment request" return self.details = pb2.PaymentDetails() self.details.ParseFromString(self.data.serialized_payment_details) if self.details.network == 'test': NetworkConstants.set_testnet() elif self.details.network == 'main': NetworkConstants.set_mainnet() else: self.error = "unknown network " + self.details.network return self.outputs = [] for o in self.details.outputs: out_type, addr = util.get_address_from_output_script(o.script) self.outputs.append((out_type, addr, o.amount)) self.memo = self.details.memo self.payment_url = self.details.payment_url
def address_to_script(addr): witver, witprog = segwit_addr.decode(NetworkConstants.SEGWIT_HRP, addr) if witprog is not None: assert (0 <= witver <= 16) 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 == NetworkConstants.ADDRTYPE_P2PKH: script = '76a9' # op_dup, op_hash_160 script += push_script(bh2u(hash_160)) script += '88ac' # op_equalverify, op_checksig elif addrtype == NetworkConstants.ADDRTYPE_P2SH: script = 'a9' # op_hash_160 script += push_script(bh2u(hash_160)) script += '87' # op_equal else: raise BaseException('unknown address type') return script
def checkPassphrase(line): passw = "" seed = util.bh2u(keystore.bip39_to_seed(line, passw)) seed = util.bfh(seed) xprv, _xpub = bitcoin.bip32_root(seed, "standard") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "44'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0") for i in range(MAX_ADDR_IDX): deriveAddresses(line, xprv, i)
def checkPassphrase(line): passw = "" seed = util.bh2u(keystore.bip39_to_seed(line, passw)) seed = util.bfh(seed) xprv, _xpub = bitcoin.bip32_root(seed, "standard") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "44'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0'") xprv, _xpub = bitcoin.bip32_private_derivation(xprv, "", "0") xprv2, btc_addr = bip39(seed, xprv, 0) return xprv2, btc_addr
def push_script(data: str) -> str: """Returns pushed data to the script, automatically choosing canonical opcodes depending on the length of the data. hex -> hex ported from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptbuilder.go#L128 """ data = bfh(data) from transaction import opcodes data_len = len(data) # "small integer" opcodes if data_len == 0 or data_len == 1 and data[0] == 0: return bh2u(bytes([opcodes.OP_0])) elif data_len == 1 and data[0] <= 16: return bh2u(bytes([opcodes.OP_1 - 1 + data[0]])) elif data_len == 1 and data[0] == 0x81: return bh2u(bytes([opcodes.OP_1NEGATE])) return op_push(data_len) + bh2u(data)
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_xkey(xkey, prv): xkey = DecodeBase58Check(xkey) if len(xkey) != 78: raise BaseException('Invalid length') 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 = XPRV_HEADERS if prv else XPUB_HEADERS if header not in headers.values(): raise BaseException('Invalid xpub format', hex(header)) xtype = list(headers.keys())[list(headers.values()).index(header)] n = 33 if prv else 32 K_or_k = xkey[13+n:] return xtype, depth, fingerprint, child_number, c, K_or_k
def verify_message(address, sig, message): assert_bytes(sig, message) try: h = Hash(msg_magic(message)) public_key, compressed = pubkey_from_signature(sig, h) # check public key using the address pubkey = point_to_ser(public_key.pubkey.point, compressed) for txin_type in ['p2pkh','p2wpkh','p2wpkh-p2sh']: addr = pubkey_to_address(txin_type, bh2u(pubkey)) if address == addr: break else: raise Exception("Bad signature") # check message public_key.verify_digest(sig[1:], h, sigdecode = ecdsa.util.sigdecode_string) return True except Exception as e: print_error("Verification error: {0}".format(e)) return False
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 script_num_to_hex(i: int) -> str: """See CScriptNum in Bitcoin Core. Encodes an integer as hex, to be used in script. ported from https://github.com/bitcoin/bitcoin/blob/8cbc5c4be4be22aca228074f087a374a7ec38be8/src/script/script.h#L326 """ if i == 0: return '' result = bytearray() neg = i < 0 absvalue = abs(i) while absvalue > 0: result.append(absvalue & 0xff) absvalue >>= 8 if result[-1] & 0x80: result.append(0x80 if neg else 0x00) elif neg: result[-1] |= 0x80 return bh2u(result)
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 get_public_key_hex(self, compressed=True): return bh2u(self.get_public_key_bytes(compressed))
def get_public_key(self, compressed=True): return bh2u(point_to_ser(self.pubkey.point, compressed))
def is_new_seed(x: str, prefix=version.SEED_PREFIX) -> bool: x = normalize_text(x) s = bh2u(hmac_oneshot(b"Seed version", x.encode('utf8'), hashlib.sha512)) return s.startswith(prefix)
def __init__(self, b): self.bytes = bytearray(b) der = ASN1_Node(b) root = der.root() cert = der.first_child(root) # data for signature self.data = der.get_all(cert) # optional version field if der.get_value(cert)[0] == 0xa0: version = der.first_child(cert) serial_number = der.next_node(version) else: serial_number = der.first_child(cert) self.serial_number = bytestr_to_int( der.get_value_of_type(serial_number, 'INTEGER')) # signature algorithm sig_algo = der.next_node(serial_number) ii = der.first_child(sig_algo) self.sig_algo = decode_OID( der.get_value_of_type(ii, 'OBJECT IDENTIFIER')) # issuer issuer = der.next_node(sig_algo) self.issuer = der.get_dict(issuer) # validity validity = der.next_node(issuer) ii = der.first_child(validity) self.notBefore = der.decode_time(ii) ii = der.next_node(ii) self.notAfter = der.decode_time(ii) # subject subject = der.next_node(validity) self.subject = der.get_dict(subject) subject_pki = der.next_node(subject) public_key_algo = der.first_child(subject_pki) ii = der.first_child(public_key_algo) self.public_key_algo = decode_OID( der.get_value_of_type(ii, 'OBJECT IDENTIFIER')) if self.public_key_algo != '1.2.840.10045.2.1': # for non EC public key # pubkey modulus and exponent subject_public_key = der.next_node(public_key_algo) spk = der.get_value_of_type(subject_public_key, 'BIT STRING') spk = ASN1_Node(bitstr_to_bytestr(spk)) r = spk.root() modulus = spk.first_child(r) exponent = spk.next_node(modulus) rsa_n = spk.get_value_of_type(modulus, 'INTEGER') rsa_e = spk.get_value_of_type(exponent, 'INTEGER') self.modulus = ecdsa.util.string_to_number(rsa_n) self.exponent = ecdsa.util.string_to_number(rsa_e) else: subject_public_key = der.next_node(public_key_algo) spk = der.get_value_of_type(subject_public_key, 'BIT STRING') self.ec_public_key = spk # extensions self.CA = False self.AKI = None self.SKI = None i = subject_pki while i[2] < cert[2]: i = der.next_node(i) d = der.get_dict(i) for oid, value in d.items(): value = ASN1_Node(value) if oid == '2.5.29.19': # Basic Constraints self.CA = bool(value) elif oid == '2.5.29.14': # Subject Key Identifier r = value.root() value = value.get_value_of_type(r, 'OCTET STRING') self.SKI = bh2u(value) elif oid == '2.5.29.35': # Authority Key Identifier self.AKI = bh2u(value.get_sequence()[0]) else: pass # cert signature cert_sig_algo = der.next_node(cert) ii = der.first_child(cert_sig_algo) self.cert_sig_algo = decode_OID( der.get_value_of_type(ii, 'OBJECT IDENTIFIER')) cert_sig = der.next_node(cert_sig_algo) self.signature = der.get_value(cert_sig)[1:]
def is_new_seed(x, prefix=version.SEED_PREFIX): from . import mnemonic x = mnemonic.normalize_text(x) s = bh2u(hmac_sha_512(b"Seed version", x.encode('utf8'))) return s.startswith(prefix)
def rev_hex(s): return bh2u(bfh(s)[::-1])
def script_to_scripthash(script): h = sha256(bytes.fromhex(script))[0:32] return bh2u(bytes(reversed(h)))
def p2wsh_nested_script(witness_script): wsh = bh2u(sha256(bfh(witness_script))) return '00' + push_script(wsh)
def p2wpkh_nested_script(pubkey): pkh = bh2u(hash_160(bfh(pubkey))) return '00' + push_script(pkh)
def public_key_from_private_key(pk, compressed): pkey = regenerate_key(pk) public_key = GetPubKey(pkey.pubkey, compressed) return bh2u(public_key)
def xpub2btc(xpub): _xtype, _depth, _fp, _cn, _c, K = bitcoin.deserialize_xpub(xpub) return bitcoin.pubkey_to_address("p2pkh", util.bh2u(K))
# "small integer" opcodes if data_len == 0 or data_len == 1 and data[0] == 0: return bh2u(bytes([opcodes.OP_0])) elif data_len == 1 and data[0] <= 16: return bh2u(bytes([opcodes.OP_1 - 1 + data[0]])) elif data_len == 1 and data[0] == 0x81: return bh2u(bytes([opcodes.OP_1NEGATE])) return op_push(data_len) + bh2u(data) def add_number_to_script(i: int) -> bytes: return bfh(push_script(script_num_to_hex(i))) hash_encode = lambda x: bh2u(x[::-1]) hash_decode = lambda x: bfh(x)[::-1] hmac_sha_512 = lambda x, y: hmac.new(x, y, hashlib.sha512).digest() def is_new_seed(x, prefix=version.SEED_PREFIX): from . import mnemonic x = mnemonic.normalize_text(x) s = bh2u(hmac_sha_512(b"Seed version", x.encode('utf8'))) return s.startswith(prefix) def is_old_seed(seed): from . import old_mnemonic, mnemonic seed = mnemonic.normalize_text(seed) words = seed.split()