Example #1
0
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