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