def test_wif_privkeys_valid(setup_keys): with open("test/base58_keys_valid.json", "r") as f: json_data = f.read() valid_keys_list = json.loads(json_data) for a in valid_keys_list: key, hex_key, prop_dict = a if prop_dict["isPrivkey"]: netval = "testnet" if prop_dict["isTestnet"] else "mainnet" jm_single().config.set("BLOCKCHAIN", "network", netval) print 'testing this key: ' + key assert chr(btc.get_version_byte( key)) in '\x80\xef', "not valid network byte" if "decode_privkey" in dir(btc): from_wif_key = btc.decode_privkey(key) expected_key = btc.decode_privkey(hex_key) else: comp = prop_dict["isCompressed"] from_wif_key = btc.from_wif_privkey( key, compressed=comp, vbyte=btc.get_version_byte(key)-128) expected_key = hex_key if comp: expected_key += '01' assert from_wif_key == expected_key, "Incorrect key decoding: " + \ str(from_wif_key) + ", should be: " + str(expected_key)
def test_wif_privkeys_valid(setup_keys): with open("test/base58_keys_valid.json", "r") as f: json_data = f.read() valid_keys_list = json.loads(json_data) for a in valid_keys_list: key, hex_key, prop_dict = a if prop_dict["isPrivkey"]: netval = "testnet" if prop_dict["isTestnet"] else "mainnet" jm_single().config.set("BLOCKCHAIN", "network", netval) print 'testing this key: ' + key assert chr(btc.get_version_byte( key)) in '\x80\xef', "not valid network byte" if "decode_privkey" in dir(btc): from_wif_key = btc.decode_privkey(key) expected_key = btc.decode_privkey(hex_key) else: comp = prop_dict["isCompressed"] from_wif_key = btc.from_wif_privkey( key, compressed=comp, vbyte=btc.get_version_byte(key) - 128) expected_key = hex_key if comp: expected_key += '01' assert from_wif_key == expected_key, "Incorrect key decoding: " + \ str(from_wif_key) + ", should be: " + str(expected_key)
def validate_utxo_data(utxo_datas, retrieve=False): """For each txid: N, privkey, first convert the privkey and convert to address, then use the blockchain instance to look up the utxo and check that its address field matches. If retrieve is True, return the set of utxos and their values. """ results = [] for u, priv in utxo_datas: print 'validating this utxo: ' + str(u) hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte()) addr = btc.privkey_to_address(hexpriv, magicbyte=get_p2pk_vbyte()) print 'claimed address: ' + addr res = jm_single().bc_interface.query_utxo_set([u]) print 'blockchain shows this data: ' + str(res) if len(res) != 1: print "utxo not found on blockchain: " + str(u) return False if res[0]['address'] != addr: print "privkey corresponds to the wrong address for utxo: " + str(u) print "blockchain returned address: " + res[0]['address'] print "your privkey gave this address: " + addr return False if retrieve: results.append((u, res[0]['value'])) print 'all utxos validated OK' if retrieve: return results return True
def generate_single_podle_sig(u, priv, i): """Make a podle entry for key priv at index i, using a dummy utxo value. This calls the underlying 'raw' code based on the class PoDLE, not the library 'generate_podle' which intelligently searches and updates commitments. """ #Convert priv to hex hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte()) podle = btc.PoDLE(u, hexpriv) r = podle.generate_podle(i) return (r['P'], r['P2'], r['sig'], r['e'], r['commit'])
def test_wif_privkeys_invalid(setup_keys): #first try to create wif privkey from key of wrong length bad_privs = ['\x01\x02'*17] #some silly private key but > 33 bytes #next try to create wif with correct length but wrong compression byte bad_privs.append('\x07'*32 + '\x02') for priv in bad_privs: with pytest.raises(Exception) as e_info: fake_wif = btc.wif_compressed_privkey(binascii.hexlify(priv)) #Create a wif with wrong length bad_wif1 = btc.bin_to_b58check('\x01\x02'*34, 128) #Create a wif with wrong compression byte bad_wif2 = btc.bin_to_b58check('\x07'*33, 128) for bw in [bad_wif1, bad_wif2]: with pytest.raises(Exception) as e_info: fake_priv = btc.from_wif_privkey(bw) #Some invalid b58 from bitcoin repo; #none of these are valid as any kind of key or address with open("test/base58_keys_invalid.json", "r") as f: json_data = f.read() invalid_key_list = json.loads(json_data) for k in invalid_key_list: bad_key = k[0] for netval in ["mainnet", "testnet"]: jm_single().config.set("BLOCKCHAIN", "network", netval) #if using py.test -s ; sanity check to see what's actually being tested print 'testing this key: ' + bad_key if "decode_privkey" in dir(btc): try: bad_key_format = btc.get_privkey_format(bad_key) print 'has correct format: ' + bad_key_format except: pass #should throw exception with pytest.raises(Exception) as e_info: if "decode_privkey" in dir(btc): from_wif_key = btc.decode_privkey(bad_key) else: from_wif_key = btc.from_wif_compressed_privkey( bad_key, btc.get_version_byte(bad_key)) #in case the b58 check encoding is valid, we should #also check if the leading version byte is in the #expected set, and throw an error if not. if chr(btc.get_version_byte(bad_key)) not in '\x80\xef': raise Exception("Invalid version byte") #the bitcoin library should throw #if the compression byte is not there (test not needed #for secp256k1 branch since the wif_compressed function checks) if "decode_privkey" in dir(btc): if "compressed" in btc.get_privkey_format(bad_key) and \ btc.b58check_to_bin(x)[-1] != '\x01': raise Exception("Invalid compression byte")
def test_wif_privkeys_invalid(setup_keys): #first try to create wif privkey from key of wrong length bad_privs = ['\x01\x02' * 17] #some silly private key but > 33 bytes #next try to create wif with correct length but wrong compression byte bad_privs.append('\x07' * 32 + '\x02') for priv in bad_privs: with pytest.raises(Exception) as e_info: fake_wif = btc.wif_compressed_privkey(binascii.hexlify(priv)) #Create a wif with wrong length bad_wif1 = btc.bin_to_b58check('\x01\x02' * 34, 128) #Create a wif with wrong compression byte bad_wif2 = btc.bin_to_b58check('\x07' * 33, 128) for bw in [bad_wif1, bad_wif2]: with pytest.raises(Exception) as e_info: fake_priv = btc.from_wif_privkey(bw) #Some invalid b58 from bitcoin repo; #none of these are valid as any kind of key or address with open("test/base58_keys_invalid.json", "r") as f: json_data = f.read() invalid_key_list = json.loads(json_data) for k in invalid_key_list: bad_key = k[0] for netval in ["mainnet", "testnet"]: jm_single().config.set("BLOCKCHAIN", "network", netval) #if using py.test -s ; sanity check to see what's actually being tested print 'testing this key: ' + bad_key if "decode_privkey" in dir(btc): try: bad_key_format = btc.get_privkey_format(bad_key) print 'has correct format: ' + bad_key_format except: pass #should throw exception with pytest.raises(Exception) as e_info: if "decode_privkey" in dir(btc): from_wif_key = btc.decode_privkey(bad_key) else: from_wif_key = btc.from_wif_compressed_privkey( bad_key, btc.get_version_byte(bad_key)) #in case the b58 check encoding is valid, we should #also check if the leading version byte is in the #expected set, and throw an error if not. if chr(btc.get_version_byte(bad_key)) not in '\x80\xef': raise Exception("Invalid version byte") #the bitcoin library should throw #if the compression byte is not there (test not needed #for secp256k1 branch since the wif_compressed function checks) if "decode_privkey" in dir(btc): if "compressed" in btc.get_privkey_format(bad_key) and \ btc.b58check_to_bin(x)[-1] != '\x01': raise Exception("Invalid compression byte")
def get_utxo_info(upriv): """Verify that the input string parses correctly as (utxo, priv) and return that. """ try: u, priv = upriv.split(',') u = u.strip() priv = priv.strip() txid, n = u.split(':') assert len(txid)==64 assert len(n) in range(1, 4) n = int(n) assert n in range(256) except: #not sending data to stdout in case privkey info print "Failed to parse utxo information for utxo" try: hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte()) except: print "failed to parse privkey, make sure it's WIF compressed format." return u, priv
def sign(utxo, priv, destaddrs): """Sign a tx sending the amount amt, from utxo utxo, equally to each of addresses in list destaddrs, after fees; the purpose is to create a large number of utxos. """ results = validate_utxo_data([(utxo, priv)], retrieve=True) if not results: return False assert results[0][0] == utxo amt = results[0][1] ins = [utxo] estfee = estimate_tx_fee(1, len(destaddrs)) outs = [] share = int((amt - estfee) / len(destaddrs)) fee = amt - share * len(destaddrs) assert fee >= estfee log.info("Using fee: " + str(fee)) for i, addr in enumerate(destaddrs): outs.append({'address': addr, 'value': share}) unsigned_tx = btc.mktx(ins, outs) return btc.sign(unsigned_tx, 0, btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte()))
def sign(utxo, priv, destaddrs): """Sign a tx sending the amount amt, from utxo utxo, equally to each of addresses in list destaddrs, after fees; the purpose is to create a large number of utxos. """ results = validate_utxo_data([(utxo, priv)], retrieve=True) if not results: return False assert results[0][0] == utxo amt = results[0][1] ins = [utxo] estfee = estimate_tx_fee(1, len(destaddrs)) outs = [] share = int((amt - estfee) / len(destaddrs)) fee = amt - share*len(destaddrs) assert fee >= estfee log.debug("Using fee: " + str(fee)) for i, addr in enumerate(destaddrs): outs.append({'address': addr, 'value': share}) unsigned_tx = btc.mktx(ins, outs) return btc.sign(unsigned_tx, 0, btc.from_wif_privkey( priv, vbyte=get_p2pk_vbyte()))
def get_key_from_addr(self, addr): self.ensure_wallet_unlocked() wifkey = jm_single().bc_interface.rpc('dumpprivkey', [addr]) return btc.from_wif_privkey(wifkey, vbyte=get_p2pk_vbyte())
print('WARNING: This imported key will not be recoverable with your 12 ' + 'word mnemonic seed. Make sure you have backups.') print('WARNING: Handling of raw ECDSA bitcoin private keys can lead to ' 'non-intuitive behaviour and loss of funds.\n Recommended instead ' 'is to use the \'sweep\' feature of sendpayment.py ') if len(args) > 3 and args[2] == \ 'cli-import-WARNING-DANGEROUS-DONT-USE-WITHOUT-UNDERSTANDING': privkeys = args[3] else: privkeys = raw_input('Enter private key(s) to import: ') privkeys = privkeys.split(',') if ',' in privkeys else privkeys.split() # TODO read also one key for each line for privkey in privkeys: # TODO is there any point in only accepting wif format? check what # other wallets do privkey_bin = btc.from_wif_privkey( privkey, vbyte=get_p2pk_vbyte()).decode('hex')[:-1] encrypted_privkey = encryptData(wallet.password_key, privkey_bin) if 'imported_keys' not in wallet.walletdata: wallet.walletdata['imported_keys'] = [] wallet.walletdata['imported_keys'].append({ 'encrypted_privkey': encrypted_privkey.encode('hex'), 'mixdepth': options.mixdepth }) if wallet.walletdata['imported_keys']: fd = open(wallet.path, 'w') fd.write(json.dumps(wallet.walletdata)) fd.close() print('Private key(s) successfully imported') elif method == 'dumpprivkey':
print(privkey, 'skipped') continue if privkey_format == 'wif': # TODO if they actually use an unc privkey, make sure the unc # address is used # r = raw_input('WARNING: Using uncompressed private key, the vast ' + # 'majority of JoinMarket transactions use compressed keys\n' + # 'being so unusual is bad for privacy. Continue? (y/n):') # if r != 'y': # sys.exit(0) print('Uncompressed privkeys not supported (yet)') print(privkey, 'skipped') continue if btc.secp_present: privkey_bin = btc.from_wif_privkey(privkey, vbyte=get_p2pk_vbyte()).decode('hex')[:-1] else: privkey_bin = btc.encode_privkey(privkey, 'hex').decode('hex') encrypted_privkey = encryptData(wallet.password_key, privkey_bin) if 'imported_keys' not in wallet.walletdata: wallet.walletdata['imported_keys'] = [] wallet.walletdata['imported_keys'].append( {'encrypted_privkey': encrypted_privkey.encode('hex'), 'mixdepth': options.mixdepth}) if wallet.walletdata['imported_keys']: fd = open(wallet.path, 'w') fd.write(json.dumps(wallet.walletdata)) fd.close() print('Private key(s) successfully imported') elif method == 'listwallets': # Fetch list of wallets