Update: The complete answer is the Perl code:
my $cipher = Crypt::EksBlowFish->new($cost, $salt, $key);
is equivalent to this Python code:
bf = Eksblowfish()
bf.expandkey(salt, key)
for i in xrange(cost << 1):
bf.expandkey(0, key)
bf.expandkey(0, salt)
See this repo for example code: https://github.com/erantapaa/python-bcrypt-tests
Original answer:
A partial answer...
I'm assuming you are calling this Perl code like this:
use Crypt::EksBlowfish;
my $cipher = Crypt::EksBlowFish->new($cost, $salt, $key);
$encoded = $cipher->encrypt("some plaintext");
The new
method is implemented by the C function setup_eksblowfish_ks()
in lib/Crypt/EksBlowfish.xs. This looks like it is the same as the expandKey
method in the Python code (link)
The main difference is the $cost
parameter which is not present in the Python method. In the Perl code the $cost
parameter controls how many times this loop is executed after the key schedule has been set up:
for(count = 1U << cost; count--; ) {
for(j = 0; j != 2; j++) {
merge_key(j == 0 ? expanded_key : expanded_salt, ks);
munge_subkeys(ks);
}
}
The Perl ->encrypt()
method enciphers a 64-bit word. The equivalent Python code is:
bf.cipher(xl, xr, bf.ENCRYPT)
where xl and xr are integers representing the left 32-bits and right 32-bits respectively.
So the recipe should go something like this:
- Create the Python object:
bf = EksBlowfish()
- Initialize the key schedule:
bf.expandkey(salt, key)
- Further munge the key schedule using the cost parameter (TBD)
- Encrypt with
bf.cipher(xl, xr, bf.ENCRYPT)