def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) keys_wif = [ Key(secret_exponent=secret_exponent), Key.from_text(wif), Key.from_text(c_wif), ] key_sec = Key.from_sec(sec) key_sec_c = Key.from_sec(c_sec) keys_sec = [key_sec, key_sec_c] for key in keys_wif: self.assertEqual(key.secret_exponent(), secret_exponent) self.assertEqual(key.public_copy().secret_exponent(), None) v = repr(key) if key._prefer_uncompressed: self.assertEqual(key.wif(), wif) else: self.assertEqual(key.wif(), c_wif) self.assertEqual(key.wif(use_uncompressed=True), wif) self.assertEqual(key.wif(use_uncompressed=False), c_wif) for key in keys_wif + keys_sec: if key._prefer_uncompressed: self.assertEqual(key.sec(), sec) else: self.assertEqual(key.sec(), c_sec) self.assertEqual(key.sec(use_uncompressed=True), sec) self.assertEqual(key.sec(use_uncompressed=False), c_sec) if key._prefer_uncompressed: self.assertEqual(key.address(), address_b58) else: self.assertEqual(key.address(), c_address_b58) self.assertEqual(key.address(use_uncompressed=False), c_address_b58) self.assertEqual(key.address(use_uncompressed=True), address_b58) key_pub = Key.from_text(address_b58, is_compressed=False) key_pub_c = Key.from_text(c_address_b58, is_compressed=True) self.assertEqual(key_pub.address(), address_b58) self.assertEqual(key_pub.address(use_uncompressed=True), address_b58) self.assertEqual(key_pub.address(use_uncompressed=False), None) self.assertEqual(key_pub_c.address(), c_address_b58) self.assertEqual(key_pub_c.address(use_uncompressed=True), None) self.assertEqual(key_pub_c.address(use_uncompressed=False), c_address_b58)
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) keys_wif = [ Key(secret_exponent=secret_exponent), Key.from_text(wif), Key.from_text(c_wif), ] key_sec = Key.from_sec(sec) key_sec_c = Key.from_sec(c_sec) keys_sec = [key_sec, key_sec_c] for key in keys_wif: self.assertEqual(key.secret_exponent(), secret_exponent) self.assertEqual(key.public_copy().secret_exponent(), None) repr(key) if key._prefer_uncompressed: self.assertEqual(key.wif(), wif) else: self.assertEqual(key.wif(), c_wif) self.assertEqual(key.wif(use_uncompressed=True), wif) self.assertEqual(key.wif(use_uncompressed=False), c_wif) for key in keys_wif + keys_sec: if key._prefer_uncompressed: self.assertEqual(key.sec(), sec) else: self.assertEqual(key.sec(), c_sec) self.assertEqual(key.sec(use_uncompressed=True), sec) self.assertEqual(key.sec(use_uncompressed=False), c_sec) if key._prefer_uncompressed: self.assertEqual(key.address(), address_b58) else: self.assertEqual(key.address(), c_address_b58) self.assertEqual(key.address(use_uncompressed=False), c_address_b58) self.assertEqual(key.address(use_uncompressed=True), address_b58) key_pub = Key.from_text(address_b58, is_compressed=False) key_pub_c = Key.from_text(c_address_b58, is_compressed=True) self.assertEqual(key_pub.address(), address_b58) self.assertEqual(key_pub.address(use_uncompressed=True), address_b58) self.assertEqual(key_pub.address(use_uncompressed=False), None) self.assertEqual(key_pub_c.address(), c_address_b58) self.assertEqual(key_pub_c.address(use_uncompressed=True), None) self.assertEqual(key_pub_c.address(use_uncompressed=False), c_address_b58)
def masked_pcode_to_pcode(masked_pcode, first_pubkey, notif_node): first_pp = Key.from_sec(first_pubkey, netcode=NETCODE).public_pair() secret, sha_secret = secret_masks(first_pp, notif_node.secret_exponent()) masked_sec = masked_pcode[2:35] my_sign = my_sec[0] masked_xval = my_sec[1:] masked_cc = masked_pcode[36:68] unmasked_xval = xor_bytes(masked_xval, secret) unmasked_cc = xor_bytes(masked_cc, sha_secret) return pcode_nosuffix(my_sign, unmasked_xval, unmasked_cc)
def nano_get_pub_wallet(path, netcode='BTC'): """ get bip32 wallet with derivable public master key :param path: derivation path :param netcode: BTC for main net :return: wallet string in xpub.... format """ _, depth = parse_bip32_path(path) public_key, _, chain_code = nano_get_key( path, key_part_pub_key + key_part_chaincode) wallet = BIP32Node(netcode, chain_code, depth, public_pair=Key.from_sec(public_key, netcode).public_pair()) return wallet.wallet_key(as_private=False)
def parse_key(item, PREFIX_TRANSFORMS, network): key = parse_prefixes(item, PREFIX_TRANSFORMS) if key: return key secret_exponent = parse_as_secret_exponent(item) if secret_exponent: return Key(secret_exponent=secret_exponent, netcode=network) if SEC_RE.match(item): return Key.from_sec(h2b(item)) public_pair = parse_as_public_pair(item) if public_pair: return Key(public_pair=public_pair, netcode=network) if HASH160_RE.match(item): return Key(hash160=h2b(item), netcode=network) return None
def parse_key(item, PREFIX_TRANSFORMS, network): key = parse_prefixes(item, PREFIX_TRANSFORMS) if key: return key if HASH160_RE.match(item): return Key(hash160=h2b(item), netcode=network) secret_exponent = parse_as_secret_exponent(item) if secret_exponent: return Key(secret_exponent=secret_exponent, netcode=network) if SEC_RE.match(item): return Key.from_sec(h2b(item)) public_pair = parse_as_public_pair(item) if public_pair: return Key(public_pair=public_pair, netcode=network) return None
def parse_key(item, networks, generator): if item == 'create': return None, _create_bip32(generator) for network, key_info in key_info_from_text(item, networks=networks): return network, key_info["create_f"]() if HASH160_RE.match(item): return None, Key(hash160=h2b(item)) secret_exponent = parse_as_secret_exponent(item, generator) if secret_exponent: return None, Key(secret_exponent=secret_exponent, generator=generator) if SEC_RE.match(item): return None, Key.from_sec(h2b(item), generator) public_pair = parse_as_public_pair(item, generator) if public_pair: return None, Key(public_pair=public_pair) return None, None
def main(): networks = "MTLD" parser = argparse.ArgumentParser( description='Crypto coin utility ku ("key utility") to show' ' information about Bitcoin or other cryptocoin data structures.', epilog='Known networks codes:\n ' \ + ', '.join(['%s (%s)'%(i, full_network_name_for_netcode(i)) for i in NETWORK_NAMES]) ) parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true') parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true') parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true') parser.add_argument( '-u', "--uncompressed", help='show output in uncompressed form', action='store_true') parser.add_argument( '-P', "--public", help='only show public version of wallet keys', action='store_true') parser.add_argument('-j', "--json", help='output as JSON', action='store_true') parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)') parser.add_argument('-n', "--network", help='specify network (default: BTC = Bitcoin)', default='BTC', choices=NETWORK_NAMES) parser.add_argument("--override-network", help='override detected network type', default=None, choices=NETWORK_NAMES) parser.add_argument( 'item', nargs="+", help='a BIP0032 wallet key string;' ' a WIF;' ' a bitcoin address;' ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);' ' the literal string "create" to create a new wallet key using strong entropy sources;' ' P:wallet passphrase (NOT RECOMMENDED);' ' H:wallet passphrase in hex (NOT RECOMMENDED);' ' secret_exponent (in decimal or hex);' ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");' ' hash160 (as 40 hex characters)') args = parser.parse_args() if args.override_network: # force network arg to match override, but also will override decoded data below. args.network = args.override_network def _create(_): max_retries = 64 for _ in range(max_retries): try: return BIP32Node.from_master_secret(get_entropy(), netcode=args.network) except ValueError as e: continue # Probably a bug if we get here raise e PREFIX_TRANSFORMS = ( ("P:", lambda s: BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network)), ("H:", lambda s: BIP32Node.from_master_secret(h2b(s), netcode=args.network)), ("create", _create), ) for item in args.item: key = None for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: key = f(item[len(k):]) break except Exception: pass else: try: key = Key.from_text(item) except encoding.EncodingError: pass if key is None: secret_exponent = parse_as_secret_exponent(item) if secret_exponent: key = Key(secret_exponent=secret_exponent, netcode=args.network) if SEC_RE.match(item): key = Key.from_sec(h2b(item)) if key is None: public_pair = parse_as_public_pair(item) if public_pair: key = Key(public_pair=public_pair, netcode=args.network) if HASH160_RE.match(item): key = Key(hash160=h2b(item), netcode=args.network) if key is None: print("can't parse %s" % item, file=sys.stderr) continue if args.override_network: # Override the network value, so we can take the same xpubkey and view what # the values would be on each other network type. # XXX public interface for this is needed... key._netcode = args.override_network for key in key.subkeys(args.subkey or ""): if args.public: key = key.public_copy() output_dict, output_order = create_output(item, key) if args.json: print(json.dumps(output_dict, indent=3, sort_keys=True)) elif args.wallet: print(output_dict["wallet_key"]) elif args.wif: print(output_dict["wif_uncompressed" if args.uncompressed else "wif"]) elif args.address: print(output_dict["address" + ("_uncompressed" if args.uncompressed else "")]) else: dump_output(output_dict, output_order)
def main(): codes = network_codes() parser = argparse.ArgumentParser( description='Crypto coin utility ku ("key utility") to show' ' information about Bitcoin or other cryptocoin data structures.', epilog=('Known networks codes:\n ' + ', '.join( ['%s (%s)' % (i, full_network_name_for_netcode(i)) for i in codes]))) parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true') parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true') parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true') parser.add_argument('-u', "--uncompressed", help='show output in uncompressed form', action='store_true') parser.add_argument('-P', "--public", help='only show public version of wallet keys', action='store_true') parser.add_argument('-j', "--json", help='output as JSON', action='store_true') parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)') parser.add_argument('-n', "--network", help='specify network (default: BTC = Bitcoin)', default='BTC', choices=codes) parser.add_argument("--override-network", help='override detected network type', default=None, choices=codes) parser.add_argument( 'item', nargs="+", help='a BIP0032 wallet key string;' ' a WIF;' ' a bitcoin address;' ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);' ' the literal string "create" to create a new wallet key using strong entropy sources;' ' P:wallet passphrase (NOT RECOMMENDED);' ' H:wallet passphrase in hex (NOT RECOMMENDED);' ' E:electrum value (either a master public, master private, or initial data);' ' secret_exponent (in decimal or hex);' ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");' ' hash160 (as 40 hex characters)') args = parser.parse_args() if args.override_network: # force network arg to match override, but also will override decoded data below. args.network = args.override_network def _create(_): max_retries = 64 for _ in range(max_retries): try: return BIP32Node.from_master_secret(get_entropy(), netcode=args.network) except ValueError as e: continue # Probably a bug if we get here raise e PREFIX_TRANSFORMS = ( ("P:", lambda s: BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network)), ("H:", lambda s: BIP32Node.from_master_secret(h2b(s), netcode=args.network)), ("E:", lambda s: key_from_text(s)), ("create", _create), ) for item in args.item: key = None for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: key = f(item[len(k):]) break except Exception: pass else: try: key = Key.from_text(item) except encoding.EncodingError: pass if key is None: secret_exponent = parse_as_secret_exponent(item) if secret_exponent: key = Key(secret_exponent=secret_exponent, netcode=args.network) if SEC_RE.match(item): key = Key.from_sec(h2b(item)) if key is None: public_pair = parse_as_public_pair(item) if public_pair: key = Key(public_pair=public_pair, netcode=args.network) if HASH160_RE.match(item): key = Key(hash160=h2b(item), netcode=args.network) if key is None: print("can't parse %s" % item, file=sys.stderr) continue if args.override_network: # Override the network value, so we can take the same xpubkey and view what # the values would be on each other network type. # XXX public interface for this is needed... key._netcode = args.override_network for key in key.subkeys(args.subkey or ""): if args.public: key = key.public_copy() output_dict, output_order = create_output(item, key) if args.json: print(json.dumps(output_dict, indent=3, sort_keys=True)) elif args.wallet: print(output_dict["wallet_key"]) elif args.wif: print(output_dict["wif_uncompressed" if args. uncompressed else "wif"]) elif args.address: print(output_dict["address" + ( "_uncompressed" if args.uncompressed else "")]) else: dump_output(output_dict, output_order)
def verify(content, signature, pub_key): key = Key.from_sec(a2b_hex(pub_key)) return key.verify(double_hash256(content), a2b_hex(signature))
def main(): networks = "MTLD" parser = argparse.ArgumentParser( description='Crypto coin utility ku ("key utility") to show' ' information about Bitcoin or other cryptocoin data structures.') parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true') parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true') parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true') parser.add_argument( '-u', "--uncompressed", help='show output in uncompressed form', action='store_true') parser.add_argument( '-P', "--public", help='only show public version of wallet keys', action='store_true') parser.add_argument('-j', "--json", help='output as JSON', action='store_true') parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)') parser.add_argument('-n', "--network", help='specify network (one of %s)' % networks, default='M') parser.add_argument( 'item', nargs="+", help='a BIP0032 wallet key string;' ' a WIF;' ' a bitcoin address;' ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);' ' the literal string "create" to create a new wallet key using strong entropy sources;' ' P:wallet passphrase (NOT RECOMMENDED);' ' H:wallet passphrase in hex (NOT RECOMMENDED);' ' secret_exponent (in decimal or hex);' ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");' ' hash160 (as 40 hex characters)') args = parser.parse_args() PREFIX_TRANSFORMS = ( ("P:", lambda s: Key(hierarchical_wallet=Wallet.from_master_secret(s.encode("utf8"), netcode=args.network))), ("H:", lambda s: Key(hierarchical_wallet=Wallet.from_master_secret(h2b(s), netcode=args.network))), ("create", lambda s: Key(hierarchical_wallet=Wallet.from_master_secret(get_entropy(), netcode=args.network))), ) for item in args.item: key = None for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: key = f(item[len(k):]) break except Exception: pass else: try: key = Key.from_text(item) except encoding.EncodingError: pass if key is None: secret_exponent = parse_as_secret_exponent(item) if secret_exponent: key = Key(secret_exponent=secret_exponent, netcode=args.network) if SEC_RE.match(item): key = Key.from_sec(h2b(item)) if key is None: public_pair = parse_as_public_pair(item) if public_pair: key = Key(public_pair=public_pair, netcode=args.network) if HASH160_RE.match(item): key = Key(hash160=h2b(item), netcode=args.network) if key is None: print("can't parse %s" % item, file=sys.stderr) continue for key in key.subkeys(args.subkey or ""): if args.public: key = key.public_copy() output_dict, output_order = create_output(item, key) if args.json: print(json.dumps(output_dict, indent=3)) elif args.wallet: print(output_dict["wallet_key"]) elif args.wif: print(output_dict["wif_uncompressed" if args.uncompressed else "wif"]) elif args.address: print(output_dict[ "bitcoin_address_uncompressed" if args.uncompressed else "bitcoin_address"]) else: dump_output(output_dict, output_order)
def verify_signature(self, sha3hash, owner, signature): k = Key.from_sec(owner) result = k.verify(sha3hash, signature) return result
def create_multisig(self, escrow): logging.info("starting creation of multisig address") N, M = 2, 3 subkeydb = MONGOSUBKEYS.find_one() # first time running and we don't have a subkey set in the database if not subkeydb: subkeydb = MONGOSUBKEYS.insert({'subkey': 1}) # TODO: this has to be moved to the private key server # create the first public key. Needed for signing up from the website or the native client. subkey = subkeydb['subkey'] phrase = "sample core fitness wrong unusual inch hurry chaos myself credit welcome margin" seed = mnemonic.Mnemonic.to_seed(phrase) wallet = BIP32Node.from_master_secret(seed) subkeys = [] keys = [] if not escrow.has_key('sellerpubky') or not escrow['sellerpubkey']: logging.info( 'seller public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key1 = wallet.subkey_for_path(subkeystring) else: logging.info( 'seller public key was provided from the native client') key1 = Key.from_sec(h2b(escrow['sellerpubkey'])) keys.append(key1) if not escrow.has_key('buyerpubkey') or not escrow['buyerpubkey']: logging.info( 'buyer public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key2 = wallet.subkey_for_path(subkeystring) else: logging.info( 'buyer public key was provided from the native client.') key2 = Key.from_sec(h2b(escrow['buyerpubkey'])) keys.append(key2) # this is our own, no matter what subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key3 = wallet.subkey_for_path(subkeystring) keys.append(key3) redeemscript = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() multisigaddress = address_for_pay_to_script(redeemscript) logging.info('multi-sig address was made: %s' % multisigaddress) MONGOSUBKEYS.update({'_id': subkeydb['_id']}, {"$set": { 'subkey': subkey }}) if escrow.has_key('_id'): MONGODB.update({'_id': escrow['_id']}, { "$set": { 'multisigaddress': multisigaddress, 'subkeys': subkeys } }) return (multisigaddress, subkeys)