Blowfish
========
Blowfish is a simple but effective block cipher designed
by Bruce Schneier. The design is a Feistel network with
key dependent S-boxes. Overall the algorithm is fast but
the relatively long key setup time could be an issue if
faced with lots of small files and frequent key changes.
"Blowfish is unpatented and license-free, and is available
free for all uses." As a result, Blowfish is well known
and in fairly widespread use.
key length: 32 to 448 bits (4 to 56 bytes)
blocksize: 64 bits (8 bytes)
rounds: 16
processor word-size: 32 bits
Of note, Bruce uses the value of Pi to set the initial
values of P and S.
More at: http://www.schneier.com/blowfish.html
http://en.wikipedia.org/wiki/Blowfish_(cipher)
This implementation of Blowfish is written in pure Python
so obviously speed was not the top requirement. In fact,
it could well take a couple of seconds to encrypt a 100K
of data. Most C implementations are much faster. If
indeed faster Python run times are desired, consider
selected optimizations such as reducing the frequency of
string-to-word and word-to-string conversions, or the
number of inner-loop function calls to perform them.
...AELFTS ;-) Please note, however, that the use of byte
strings for all data passing is intentional as a common
denominator for consistency between platforms and
languages.
This implementation of counter mode uses a nonce of up
to 8 bytes. Provided nonces will be truncated to 8 bytes
or padded with nulls as appropriate. The right-most bits
are incremented as the counter. If an initial value for
the nonce/counter is not provided, the system clock
(date-time) will be used.
blowfish.py
blowfish.py3
blowfish.py should run under any version of Python2.
(Versions 2.4 and earlier remain untested however.)
blowfish.py3 runs under Python 3.2 and is backward
compatible to 2.6 and 2.7.
Both versions also run under pypy 1.5 (2.7.1).
Sample usage:
key = 'open sesame'
ot = 'Now is the time for all good men....'
CTR encrypt:
bf = Blowfish(key)
ct = bf.CTR_final(ot) # send to recipient
counter0 = bf.get_counter0() # send to recipient
CTR decrypt:
bf = Blowfish(key, counter0)
pt = bf.CTR_final(ct)
Remember, counter mode requires a different, unique nonce
be used for each encryption using the same key, and that
the decrypter will need to know the initial counter value.
The nonce/counter need not be kept secret; it must simply
be unique. A common way to communicate the initial counter
value is to prepend it to the ciphertext.
A while back Michael Gilfix wrote a pure Python version
of Blowfish that was subsequently enhanced by Ivan Voras.
Use Google to find them. Because both implementations are
governed by the GPL, I was motivated to create a version
with fewer encumberances. Thus...
Copyright (c) 2011 by Larry Bugbee, Kent, WA, USA
ALL RIGHTS RESERVED.
blowfish.py IS EXPERIMENTAL SOFTWARE FOR EDUCATIONAL
PURPOSES ONLY. IT IS MADE AVAILABLE "AS-IS" WITHOUT
WARRANTY OR GUARANTEE OF ANY KIND. USE SIGNIFIES
ACCEPTANCE OF ALL RISK.
To make your learning and experimentation less cumbersome,
blowfish.py is free for any use. Feel free to extend,
modify, and experiment. I choose, however, to retain my
copyrights.
Enjoy,
Larry Bugbee
April 2011
------------------------------------------------------------------------
------------------------------------------------------------------------
------------------------------------------------------------------------