I found a simple pure python blowfish implementation that meets my needs for a particular project.
There’s just one part of it that bothers me:
def initialize(key):
"""
Use key to setup subkeys -- requires 521 encryptions
to set p and s boxes. key is a hex number corresponding
to a string of 32 up to 448 1s and 0s -- keylen says
how long
"""
# Note that parray and sboxes are globals that have been pre-initialized.
hexkey = hex(key)[2:]
if hexkey[-1]=='L':
hexkey = hexkey[:-1]
if len(hexkey)%2==1:
hexkey = '0'+hexkey
lenkey = len(hexkey)/8
if lenkey==0:
pos=0
# XOR key segments with P-boxes
for i in range(18):
if lenkey>0:
pos = (i%lenkey)*8 # offset into key gives subkey
subkey = eval('0x'+hexkey[pos:pos+8]+'L')
parray[i] ^= subkey # immediate XOR -- Python 2.0+ syntax
# encrypt 0-data, then keep re-encrypting and reassigning P-boxes
output = 0L
for i in range(0,17,2):
output = bfencrypt(output)
parray[i], parray[i+1] = output>>32, output & 0xFFFFFFFFL
# re-encrypt and reassign through all the S-boxes
for i in range(4):
for j in range(0,255,2):
output = bfencrypt(output)
sbox[i][j],sbox[i][j+1] = output>>32, output & 0xFFFFFFFFL
# print "Initialization complete"
subkey = eval('0x'+hexkey[pos:pos+8]+'L')? Please tell me there’s a better way to do this.
Isn’t there a way to refactor this to use an actual integer type rather than hex values in a string?
Yes. Use int() with a base of 16.
so:
should do the same thing without needing eval.
[Edit] In fact, there’s generally no reason why you’d need to convert to a string representation at all, given an integer – you can simply extract out each 32 bit value by ANDing with
0xffffffffand shifting the key right by 32 bits in a loop. eg:However, this initialization process seems a bit odd – it’s using the hex digits starting from the left, with no zero padding to round to a multiple of 8 hex digits (so the number
0x123456789would be split into0x12345678and0x9, rather than the more customary0x00000001and0x23456789. It also repeats these numbers, rather than treating it as a single large number. You should check that this code is actually performing the correct algorithm.