def bip38_encrypt(private_key, passphrase, n=16384, r=8, p=8, compressed=False): # determine the flagbyte if compressed: flagbyte = '\xe0' else: flagbyte = '\xc0' # get the private key's address and equivalent in hex format and wif format k = BitcoinKeypair(private_key) address = k.address() hex_private_key = k.private_key() wif_private_key = k.wif_pk() # calculate the address's checksum address_checksum = sha256(sha256(address).digest()).digest()[0:4] # calculate the scrypt hash and split it in half scrypt_derived_key = scrypt.hash(passphrase, address_checksum, n, r, p) derived_half_1 = scrypt_derived_key[0:32] derived_half_2 = scrypt_derived_key[32:64] # combine parts of the private key and scrypt hash and AES encrypt them aes = AES.new(derived_half_2) encrypted_half_1 = aes.encrypt( binascii.unhexlify( '%0.32x' % (long(hex_private_key[0:32], 16) ^ long(binascii.hexlify(derived_half_1[0:16]), 16)) ) ) encrypted_half_2 = aes.encrypt( binascii.unhexlify( '%0.32x' % (long(hex_private_key[32:64], 16) ^ long(binascii.hexlify(derived_half_1[16:32]), 16)) ) ) # build the encrypted private key from the checksum and encrypted parts encrypted_private_key = ('\x42' + flagbyte + address_checksum + encrypted_half_1 + encrypted_half_2) # base 58 encode the encrypted private key b58check_encrypted_private_key = b58check_encode(encrypted_private_key, version_byte=1) # return the encrypted private key return b58check_encrypted_private_key
def bip38_decrypt(b58check_encrypted_private_key, passphrase, n=16384, r=8, p=8): # decode private key from base 58 check to binary encrypted_private_key = b58check_decode(b58check_encrypted_private_key) # parse the encrypted key different byte sections bip38_key_identification_byte = encrypted_private_key[0:1] flagbyte = encrypted_private_key[1:2] address_checksum = encrypted_private_key[2:6] encrypted_half_1 = encrypted_private_key[6:6+16] encrypted_half_2 = encrypted_private_key[6+16:6+32] # derive a unique key from the passphrase and the address checksum scrypt_derived_key = scrypt.hash(passphrase, address_checksum, n, r, p) derived_half_1 = scrypt_derived_key[0:32] derived_half_2 = scrypt_derived_key[32:64] # decrypt the encrypted halves aes = AES.new(derived_half_2) decrypted_half_1 = aes.decrypt(encrypted_half_1) decrypted_half_2 = aes.decrypt(encrypted_half_2) # get the original private key from the encrypted halves + the derived half decrypted_private_key = '%064x' % (long(binascii.hexlify(decrypted_half_1 + decrypted_half_2), 16) ^ long(binascii.hexlify(derived_half_1), 16)) # get the address corresponding to the private key k = BitcoinKeypair(decrypted_private_key) address = k.address() # make sure the address matches the checksum in the original encrypted key if address_checksum != sha256(sha256(address).digest()).digest()[0:4]: raise ValueError('Invalid private key and password combo.') # return the decrypted private key return k.private_key()
def __init__(self, passphrase="", type=0): self.passphrase = passphrase self.address = None self.public_key = None self.private_key = None try: if type == '1': keypair = BitcoinKeypair.from_private_key( self.passphrase.encode('ascii')) elif type == '2': keypair = BitcoinKeypair.from_private_key( deterministic.electrum_stretch( self.passphrase.encode('utf-8'))) else: keypair = BitcoinKeypair.from_passphrase( self.passphrase.encode('utf-8')) self.address = keypair.address() self.public_key = keypair.public_key() self.private_key = keypair.private_key() self.wif = keypair.wif_pk() except Exception as e: logging.warning( u"Failed to generate keypair for passphrase '{}'. Error: {}". format(passphrase, e.args)) raise
def __init__(self, passphrase, private_key=False): self.passphrase = passphrase if private_key: self.keypair = BitcoinKeypair.from_private_key( self.passphrase.encode('ascii')) else: try: self.keypair = BitcoinKeypair.from_passphrase(self.passphrase) except Exception: LOG.exception(u'Failed to generate keypair from {0}'.format( self.passphrase)) raise
def __init__(self, passphrase, is_private_key = False): self.passphrase = passphrase self.address = None self.public_key = None self.private_key = None try: if is_private_key: keypair = BitcoinKeypair.from_private_key(self.passphrase.encode('ascii')) else: keypair = BitcoinKeypair.from_passphrase(self.passphrase) self.address = keypair.address() self.public_key = keypair.public_key() self.private_key = keypair.private_key() except Exception as e: logging.warning(u"Failed to generate keypair for passphrase '{}'. Error: {}".format(passphrase, e.args)) raise
def __init__(self, passphrase, is_private_key=False): self.passphrase = passphrase self.address = None self.public_key = None self.private_key = None try: if is_private_key: keypair = BitcoinKeypair.from_private_key( self.passphrase.encode('ascii')) else: keypair = BitcoinKeypair.from_passphrase(self.passphrase) self.address = keypair.address() self.public_key = keypair.public_key() self.private_key = keypair.private_key() except Exception as e: logging.warning( u"Failed to generate keypair for passphrase '{}'. Error: {}". format(passphrase, e.args)) raise
def __init__(self, passphrase = "", type = 0): self.passphrase = passphrase self.address = None self.public_key = None self.private_key = None try: if type == '1': keypair = BitcoinKeypair.from_private_key(self.passphrase.encode('ascii')) elif type == '2': keypair = BitcoinKeypair.from_private_key(deterministic.electrum_stretch(self.passphrase.encode('utf-8'))) else: keypair = BitcoinKeypair.from_passphrase(self.passphrase.encode('utf-8')) self.address = keypair.address() self.public_key = keypair.public_key() self.private_key = keypair.private_key() self.wif = keypair.wif_pk() except Exception as e: logging.warning(u"Failed to generate keypair for passphrase '{}'. Error: {}".format(passphrase, e.args)) raise
def sweep_btc(transfer_user, LIVE=False): user_id = transfer_user['user_id'] new_user = new_users.find_one({"_id": user_id}) if new_user is None: return old_user = old_users.find_one({'username': new_user['username']}) if old_user is None: return new_btc_address = new_user['bitcoin_address'] old_btc_address = json.loads(old_user['profile'])['bitcoin']['address'] wif_pk = bip38_decrypt(str(transfer_user['encrypted_private_key']), WALLET_SECRET) keypair = BitcoinKeypair.from_private_key(wif_pk) if old_btc_address == keypair.address(): balance = fetch_balance(old_btc_address) if balance == float(0): return False log.debug(new_user['username']) log.debug("old btc address: " + old_btc_address) bitcoind.importprivkey(keypair.wif_pk()) if LIVE: log.debug("sending " + str(balance) + " to " + new_btc_address) tx = bitcoind.sendtoaddress(new_btc_address, balance) log.debug(tx) else: log.debug("need to send " + str(balance) + " to " + new_btc_address) log.debug("final balance: %s", balance) log.debug('-' * 5) return True return False
def findVanityInDic(fileName, prefix, maxTries = 0, length = 3, ignoreCase = False): if maxTries == 0: maxTries = 60**len(prefix) dictionary_encoding = "utf-8" info("Opening dictionary file {} and validating encoding is {}".format(fileName, dictionary_encoding)) try: f_dictionary = io.open(fileName, 'rt', encoding=dictionary_encoding) words = f_dictionary.readlines() f_dictionary.close() except Exception as e: error("Failed to open dictionary file {}. Make sure file is {} encoded.".format( fileName, dictionary_encoding)) exit(1) info("finished reading file {}, starting bruteforce...".format(fileName)) for i in range(maxTries): guess = ''.join(sample(words, length)).replace('\n', ' ') if isVanity(guess, prefix, ignoreCase): return guess, BitcoinKeypair.from_passphrase(guess).address() return None
def findVanityInDic(fileName, prefix, maxTries=0, length=3, ignoreCase=False): if maxTries == 0: maxTries = 60**len(prefix) dictionary_encoding = "utf-8" info("Opening dictionary file {} and validating encoding is {}".format( fileName, dictionary_encoding)) try: f_dictionary = io.open(fileName, 'rt', encoding=dictionary_encoding) words = f_dictionary.readlines() f_dictionary.close() except Exception as e: error( "Failed to open dictionary file {}. Make sure file is {} encoded.". format(fileName, dictionary_encoding)) exit(1) info("finished reading file {}, starting bruteforce...".format(fileName)) for i in range(maxTries): guess = ''.join(sample(words, length)).replace('\n', ' ') if isVanity(guess, prefix, ignoreCase): return guess, BitcoinKeypair.from_passphrase(guess).address() return None
def isVanity(seed, prefix, ignoreCase=False): key = BitcoinKeypair.from_passphrase(seed) if ignoreCase: return key.address().lower().startswith(prefix) else: return key.address().startswith(prefix)
def isVanity(seed, prefix, ignoreCase = False): key = BitcoinKeypair.from_passphrase(seed) if ignoreCase: return key.address().lower().startswith(prefix) else: return key.address().startswith(prefix)