def __init__(self, raw_pubkey=None, raw_privkey=None): if raw_privkey: assert not raw_pubkey raw_pubkey = privtopub(raw_privkey) if raw_pubkey: assert len(raw_pubkey) == 64 _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey) else: pubkey_x, pubkey_y = None, None while True: pyelliptic.ECC.__init__(self, pubkey_x=pubkey_x, pubkey_y=pubkey_y, raw_privkey=raw_privkey, curve=self.curve) try: if self.raw_privkey: bitcoin.get_privkey_format( self.raw_privkey) # failed for some keys valid_priv_key = True except AssertionError: valid_priv_key = False if len(self.raw_pubkey) == 64 and valid_priv_key: break elif raw_privkey or raw_pubkey: raise Exception('invalid priv or pubkey') assert len(self.raw_pubkey) == 64
def __init__(self, raw_pubkey=None, raw_privkey=None): if raw_privkey: assert not raw_pubkey raw_pubkey = privtopub(raw_privkey) if raw_pubkey: assert len(raw_pubkey) == 64 _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey) else: pubkey_x, pubkey_y = None, None while True: pyelliptic.ECC.__init__(self, pubkey_x=pubkey_x, pubkey_y=pubkey_y, raw_privkey=raw_privkey, curve=self.curve) # XXX: when raw_privkey is generated by pyelliptic it sometimes # has 31 bytes so we try again! if self.raw_privkey and len(self.raw_privkey) != 32: continue try: if self.raw_privkey: bitcoin.get_privkey_format( self.raw_privkey) # failed for some keys valid_priv_key = True except AssertionError: valid_priv_key = False if len(self.raw_pubkey) == 64 and valid_priv_key: break elif raw_privkey or raw_pubkey: raise Exception('invalid priv or pubkey') assert len(self.raw_pubkey) == 64
def __init__(self, raw_pubkey=None, raw_privkey=None): if raw_privkey: assert not raw_pubkey raw_pubkey = privtopub(raw_privkey) if raw_pubkey: assert len(raw_pubkey) == 64 _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_pubkey) else: pubkey_x, pubkey_y = None, None while True: pyelliptic.ECC.__init__( self, pubkey_x=pubkey_x, pubkey_y=pubkey_y, raw_privkey=raw_privkey, curve=self.curve ) try: if self.raw_privkey: bitcoin.get_privkey_format(self.raw_privkey) # failed for some keys valid_priv_key = True except AssertionError: valid_priv_key = False if len(self.raw_pubkey) == 64 and valid_priv_key: break elif raw_privkey or raw_pubkey: raise Exception("invalid priv or pubkey") assert len(self.raw_pubkey) == 64
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 has_valid_keys(self): try: try: # failed for some keys bitcoin.get_privkey_format(self.raw_privkey) except AssertionError: raise exceptions.CryptoError('Invalid privkey') assert len(self.raw_pubkey) == 64 raw_check_result = self.raw_check_key( self.raw_privkey, *self._decode_pubkey(self.raw_pubkey)[1:3]) if raw_check_result != 0: raise exceptions.InvalidKeys() except (AssertionError, Exception): return False return True
def has_valid_keys(self): try: try: # failed for some keys bitcoin.get_privkey_format(self.raw_privkey) except AssertionError: raise exceptions.InvalidKeys('Invalid privkey') verify_pubkey(self.raw_pubkey) raw_check_result = self.raw_check_key( self.raw_privkey, *self._decode_pubkey(self.raw_pubkey)[1:3], ) if raw_check_result != 0: raise exceptions.InvalidKeys() except Exception: # pylint: disable=broad-except return False return True
def bip38_encrypt(privkey, passphrase): """ BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey. """ privformat = get_privkey_format(privkey) if privformat in ['wif_compressed','hex_compressed']: compressed = True flagbyte = b'\xe0' if privformat == 'wif_compressed': privkey = encode_privkey(privkey,'hex_compressed') privformat = get_privkey_format(privkey) if privformat in ['wif', 'hex']: compressed = False flagbyte = b'\xc0' if privformat == 'wif': privkey = encode_privkey(privkey,'hex') privformat = get_privkey_format(privkey) pubkey = privtopub(privkey) addr = pubtoaddr(pubkey) passphrase = normalize('NFC', unicode(passphrase)) if is_py2: ascii_key = addr passphrase = passphrase.encode('utf8') else: ascii_key = bytes(addr,'ascii') salt = sha256(sha256(ascii_key).digest()).digest()[0:4] key = scrypt.hash(passphrase, salt, 16384, 8, 8) derivedhalf1, derivedhalf2 = key[:32], key[32:] aes = AES.new(derivedhalf2) encryptedhalf1 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[0:32], 16) ^ long(hexlify(derivedhalf1[0:16]), 16)))) encryptedhalf2 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[32:64], 16) ^ long(hexlify(derivedhalf1[16:32]), 16)))) payload = b'\x01' + b'\x42' + flagbyte + salt + encryptedhalf1 + encryptedhalf2 checksum = sha256(sha256(payload).digest()).digest()[:4] # b58check for encrypted privkey privatkey = hexlify(payload + checksum).decode('ascii') return changebase(privatkey, 16, 58)
def _init_ecc(self, raw_public_key, raw_private_key): if raw_private_key: assert not raw_public_key raw_public_key = crypto_utils.private_to_public_key( raw_private_key) if raw_public_key: assert len(raw_public_key) == eth_common_constants.PUBLIC_KEY_LEN _, pubkey_x, pubkey_y, _ = self._decode_pubkey(raw_public_key) else: pubkey_x, pubkey_y = None, None while True: pyelliptic.ECC.__init__(self, pubkey_x=pubkey_x, pubkey_y=pubkey_y, raw_privkey=raw_private_key, curve=eth_common_constants.ECIES_CURVE) # when raw_private_key is generated by pyelliptic it sometimes has 31 bytes so we try again! if self.get_raw_private_key() and len(self.get_raw_private_key( )) != eth_common_constants.PRIVATE_KEY_LEN: continue try: if self.get_raw_private_key(): bitcoin.get_privkey_format( self.get_raw_private_key()) # failed for some keys valid_private_key = True except AssertionError: valid_private_key = False if len(self.get_raw_public_key( )) == eth_common_constants.PUBLIC_KEY_LEN and valid_private_key: break elif raw_private_key or raw_public_key: raise Exception("invalid private or public key") assert len( self.get_raw_public_key()) == eth_common_constants.PUBLIC_KEY_LEN
def __init__(self, private_key=None, compressed=False): """ Takes in a private key/secret exponent. """ self._compressed = compressed if not private_key: secret_exponent = random_secret_exponent(self._curve.order) else: secret_exponent = encode_privkey(private_key, 'decimal') if get_privkey_format(private_key).endswith('compressed'): self._compressed = True # make sure that: 1 <= secret_exponent < curve_order if not is_secret_exponent(secret_exponent, self._curve.order): raise IndexError(_errors["EXPONENT_OUTSIDE_CURVE_ORDER"]) self._ecdsa_private_key = ecdsa.keys.SigningKey.from_secret_exponent( secret_exponent, self._curve, self._hash_function)
def __init__(self, private_key=None, compressed=False): """ Takes in a private key/secret exponent. """ self._compressed = compressed if not private_key: secret_exponent = random_secret_exponent(self._curve.order) else: secret_exponent = encode_privkey(private_key, 'decimal') if get_privkey_format(private_key).endswith('compressed'): self._compressed = True # make sure that: 1 <= secret_exponent < curve_order if not is_secret_exponent(secret_exponent, self._curve.order): raise IndexError(_errors["EXPONENT_OUTSIDE_CURVE_ORDER"]) self._ecdsa_private_key = ecdsa.keys.SigningKey.from_secret_exponent( secret_exponent, self._curve, self._hash_function )
def sign(tx_hash: bytes, private_key: str): msg_hash = tx_hash z = bitcoin.hash_to_int(msg_hash) k = bitcoin.deterministic_generate_k(msg_hash, private_key) r, y = bitcoin.fast_multiply(bitcoin.G, k) s = bitcoin.inv(k, bitcoin.N) * ( z + r * bitcoin.decode_privkey(private_key)) % bitcoin.N v, r, s = 27 + ((y % 2) ^ (0 if s * 2 < bitcoin.N else 1) ), r, s if s * 2 < bitcoin.N else bitcoin.N - s if 'compressed' in bitcoin.get_privkey_format(private_key): v += 4 hex_str_r = hex(r)[2:] if len(hex_str_r) < 64: hex_str_r = ((64 - len(hex_str_r)) * "0") + hex_str_r hex_str_s = hex(s)[2:] if len(hex_str_s) < 64: hex_str_s = ((64 - len(hex_str_s)) * "0") + hex_str_s signature = hex_str_r + hex_str_s recovery = v - 27 return signature, recovery
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 " ) 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_format = btc.get_privkey_format(privkey) if privkey_format not in ["wif", "wif_compressed"]: print("ERROR: privkey not in wallet import format") 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")
words = mn_encode(hexseed) print('Wallet recovery seed\n\n' + ' '.join(words) + '\n') elif method == 'importprivkey': 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 ') 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 if not btc.secp_present: privkey_format = btc.get_privkey_format(privkey) if privkey_format not in ['wif', 'wif_compressed']: print('ERROR: privkey not in wallet import format') 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')
def test_verify_pri_key(): assert get_privkey_format(pri_key) == 'wif_compressed' assert decode_privkey(pri_key, 'wif_compressed') == key