dslinux/user/bitchx/dll/blowfish CREDITS Makefile.in README bf_tab.h blowfish.c blowfish.doc blowfish.h blowfish.sh bot-crypt.tcl op-crypt.tcl

stsp stsp at user.in-berlin.de
Sun Jul 2 15:18:33 CEST 2006

Update of /cvsroot/dslinux/dslinux/user/bitchx/dll/blowfish
In directory antilope:/tmp/cvs-serv9280/dll/blowfish

Added Files:
	CREDITS Makefile.in README bf_tab.h blowfish.c blowfish.doc 
	blowfish.h blowfish.sh bot-crypt.tcl op-crypt.tcl 
Log Message:
Adding pristine copy of BitchX so I can branch from it.

--- NEW FILE: Makefile.in ---

srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
topdir = @topdir@
prefix = @prefix@
exec_prefix = @exec_prefix@

bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = @oldincludedir@

local_dir = $(HOME)

# Where the BitchX binary will be installed.
# "make install" will compile and install the program.

# Where the BitchX library will be. Generally this is the place that
# you put the scripts, help pages and translation tables. It is
# very important that you set this correctly.

CC = @CC@

# Tcl library.

# These are for Tcl support.
# You don't have the following, so you'll want to leave this blank.

# Set this to -g if you want to be able to debug the client, otherwise
# use -O to have the compiler do some optimization instead.

# Set this to -s if you want the binary to be stripped.

# These are for the cd device player.

# This is the executable suffix for the target operating system.

# Extra files.

# Full path of the directory for BitchX help files.

# Full path of the directory for the BitchX scripts.

# Default setting for IRCPATH where BitchX will look for
# its script files if the environment variable is undefined.
# Usually, this should contain the same path as used for INSTALL_SCRIPT in
# the Makefile, but it can contain multiple path elements
# separated by colons. The path MUST lead to an existing directory,
# because the 'global' script is expected to be found there.

# Path for TRANSLATION variable.

# This command will be used to install the BitchX help files. If you don't
# want to install them, replace with the following:
# INSTALL_HELP_CMD = @echo The help files have not been installed.

# This is where the optional plugins will be copied to.

# Plugin flags.

# This command will be used to install the BitchX files on Win32/OS2EMX
# systems.

# This program allows you to use screen/xterm's to put new BitchX windows
# on new screen/xterm windows.

# This program allows you to screen BitchX and reattach to it later.

# Set gzip and bzip2 options.

# Standard programs.
RM = @RM@
LN = @LN_S@
CP = @CP@
MV = @MV@



	'local_dir=$(HOME)'			\
	'CC=$(CC)'				\
	'LIBS=$(LIBS)'				\
	'LN=$(LN)'				\
	'RM=$(RM)'				\
	'CD_PLAY=$(CD_PLAY)'			\
	'CD_SRCS=$(CD_SRCS)'			\
	'CD_OBJS=$(CD_OBJS)'			\
	'_VERSION_=$(_VERSION_)'		\

## Makefile starts here.

PLUGIN_NAME = blowfish

all: Makefile blowfish$(SHLIB_SUFFIX)

Makefile: Makefile.in
	cd $(topdir) \
	  && ./config.status

blowfish.o: $(srcdir)/blowfish.c
	$(CC) $(DEFS) $(CFLAGS) -c $(srcdir)/blowfish.c

blowfish$(SHLIB_SUFFIX): blowfish.o ../dllinit.o
	$(SHLIB_LD) blowfish.o ../dllinit.o $(SHLIB_CFLAGS) -o blowfish$(SHLIB_SUFFIX) $(TCL_LIBS)

	$(RM) *~ *.o blowfish$(SHLIB_SUFFIX) *.a *.dll *.def .#*

distclean: clean
	$(RM) Makefile


--- NEW FILE: blowfish.h ---
#include "irc.h"
#include "struct.h"
#include "ircaux.h"
#include "ctcp.h"
#include "status.h"
#include "lastlog.h"
#include "server.h"
#include "screen.h"
#include "vars.h"
#include "misc.h"
#include "output.h"
#include "module.h"
#include "hash2.h"

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>

#ifdef WANT_TCL
#	include <tcl.h>
#	include "tcl_bx.h"

#ifndef STDVAR
#	define STDVAR (ClientData cd, Tcl_Interp *irp, int argc, char *argv[])

#ifndef BADARGS
#define BADARGS(nl,nh,example) \
	if ((argc<(nl)) || (argc>(nh))) { \
		Tcl_AppendResult(intp,"wrong # args: should be \"",argv[0], \
		(example),"\"",NULL); \
		return TCL_ERROR; \
#endif /* BADARGS */

#endif /* WANT_TCL */

#include "modval.h"

#define MAXKEYBYTES 56          /* 448 bits */
#define bf_N             16
#define noErr            0
#define DATAERROR         -1
#define KEYBYTES         8

#define UBYTE_08bits  unsigned char
#define UWORD_16bits  unsigned short

#  define UWORD_32bits  unsigned int
#  if SIZEOF_LONG==4
#  define UWORD_32bits  unsigned long
#  endif
/* choose a byte order for your hardware */

/* ABCD - big endian - motorola */
union aword {
  UWORD_32bits word;
  UBYTE_08bits byte [4];
  struct {
    unsigned int byte0:8;
    unsigned int byte1:8;
    unsigned int byte2:8;
    unsigned int byte3:8;
  } w;
#endif  /* WORDS_BIGENDIAN */

/* DCBA - little endian - intel */
union aword {
  UWORD_32bits word;
  UBYTE_08bits byte [4];
  struct {
    unsigned int byte3:8;
    unsigned int byte2:8;
    unsigned int byte1:8;
    unsigned int byte0:8;
  } w;
#endif  /* !WORDS_BIGENDIAN */

--- NEW FILE: op-crypt.tcl ---
if {![info exists blowfish_version]} {
	putscr "You MUST load the blowfish encryption module prior to loading this!"
global crypt_timeout cryptfile
set crypt_timeout 60
set cryptfile "/home/by-tor/.BitchX/cryptkeys"

#borrowed from alltools.tcl
proc randstring {count} {
  set rs ""
  for {set j 0} {$j < $count} {incr j} {
     set x [rand 62]
     append rs [string range "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" $x $x]
  unset x
  unset j
  return $rs

proc crop {n args} {
	global cryptkeeper cryptlist crypt_timeout
	set ln [string tolower $n]
	if {([onchan $n [_T]]) && ([isop $n [_T]])} {
		if {![info exists cryptkeeper($ln)]} {
			putscr "You must first set a pair of crypt keys before using this."
			putscr "Try /addcrypt <nick> <key1> <key2>"
		putserv "privmsg $n :crypt_op"
		set cryptlist($ln) [utimer $crypt_timeout "killcrypt $n"]
	} {
		putscr "$n is not on [_T], or is not an op."

proc killcrypt {n} {
	global cryptlist
	if [info exists cryptlist($n)] { unset cryptlist($n) }

bind msg -1 crypt_op crypt_response

proc crypt_response {n u h a} {
	global cryptkeeper cryptlist
	set ln [string tolower $n]
	if {![info exists cryptlist($ln)]} {
		putscr "$n requesting UNAUTHORIZED crypt verification!"
	} {
		killutimer $cryptlist($ln)
		unset cryptlist($ln)
		putserv "privmsg $n :crypt_reply [encrypt [lindex $cryptkeeper($ln) 1] [decrypt [lindex $cryptkeeper($ln) 0] $a]]"

proc addcrypt {n k1 k2 args} {
	global cryptkeeper
	set cryptkeeper([string tolower $n]) "$k1 $k2"
	putscr "Added $n to the crypt keeper with keys $k1 and $k2."

proc savecrypt {} {
	global cryptfile cryptkeeper filekey
	if {![info exists cryptkeeper]} { return 0 }
	if [set fd [open $cryptfile w]] {
		if [info exists filekey] {
			puts $fd "encrypted"
			puts $fd [encrypt $filekey verified]
			foreach name [array names cryptkeeper] {
				puts $fd [encrypt $filekey "$name $cryptkeeper($name)"]
		} {
			foreach name [array names cryptkeeper] {
				puts $fd "$name $cryptkeeper($name)"
		close $fd

proc readcrypt {args} {
	global cryptfile cryptkeeper filekey
	if [file exists $cryptfile] {
		if [info exists cryptkeeper] { unset cryptkeeper }
		set fd [open $cryptfile r]
		set text [gets $fd]
		# Is our file encrypted? (Maximum security here!)
		if {![string compare "encrypted" $text]} {
			set text [gets $fd]
			if {[llength $args] < 1} {
				return "You must supply a file key for the encrypted file."
			set filekey [lindex $args 0]
			if {![string compare "verified" [decrypt $filekey $text]]} {
				while {![eof $fd]} {
					set text [decrypt $filekey [gets $fd]]
					if {[llength $text] == 3} {
						set cryptkeeper([lindex $text 0]) [lrange $text 1 end]
			} {
				return "Invalid cryptfile key."
		while {![eof $fd]} {
			set text [gets $fd]
			if {[llength $text] == 3} {
				set cryptkeeper([lindex $text 0]) [lrange $text 1 end]

proc filekey {args} {
	global filekey cryptkeeper
	if {[llength $args] > 0} {
		set filekey [lindex $args 0]
		if [info exists cryptkeeper] { savecrypt }
		return "Set crypt file key to \"$filekey\""
	} {
		return "You must supply a key!"


--- NEW FILE: blowfish.doc ---
 Description of a New Variable-Length Key, 64-Bit Block Cipher    

                          Bruce Schneier
   Counterpane Systems, 730 Fair Oaks Ave, Oak Park, IL  60302
                        schneier at chinet.com


Blowfish, a new secret-key block cipher, is proposed.  It is a
Feistel network, iterating a simple encryption function 16 times. 
The block size is 64 bits, and the key can be any length up to
448 bits.  Although there is a complex initialization phase
required before any encryption can take place, the actual
encryption of data is very efficient on large microprocessors.

The cryptographic community needs to provide the world with a new
encryption standard.  DES [16], the workhorse encryption
algorithm for the past fifteen years, is nearing the end of its
useful life.  Its 56-bit key size is vulnerable to a brute-force
attack [22], and recent advances in differential cryptanalysis
[1] and linear cryptanalysis [10] indicate that DES is vulnerable
to other attacks as well.

Many of the other unbroken algorithms in the literatureþKhufu
[11,12], REDOC II [2,23, 20], and IDEA [7,8,9]þare protected by
patents.  RC2 and RC4, approved for export with a small key size,
are proprietary [18].  GOST [6], a Soviet government algorithm,
is specified without the S-boxes.  The U.S. government is moving
towards secret algorithms, such as the Skipjack algorithm in the
Clipper and Capstone chips [17].

If the world is to have a secure, unpatented, and freely-
available encryption algorithm by the turn of the century, we
need to develop several candidate encryption algorithms now. 
These algorithms can then be subjected to years of public
scrutiny and cryptanalysis.  Then, the hope is that one or more
candidate algorithms will survive this process, and can
eventually become a new standard.

This paper discusses the requirements for a standard encryption
algorithm.  While it may not be possible to satisfy all
requirements with a single algorithm, it may be possible to
satisfy them with a family of algorithms based on the same
cryptographic principles.


A standard encryption algorithm must be suitable for many
different applications:

         Bulk encryption.  The algorithm should be efficient in
                 encrypting data files or a continuous data stream.

         Random bit generation.  The algorithm should be efficient in
                 producing single random bits.

         Packet encryption.  The algorithm should be efficient in
                 encrypting packet-sized data.  (An ATM packet has a 48-
                 byte data field.)  It should implementable in an
                 application where successive packets may be encrypted
                 or decrypted with different keys.

         Hashing.  The algorithm should be efficient in being
                 converted to a one-way hash function.


A standard encryption algorithm must be implementable on a
variety of different platforms, each with their own requirements. 
These include:

         Special hardware.  The algorithm should be efficiently
                 implementable in custom VLSI hardware.

         Large processors.  While dedicated hardware will always be
                 used for the fastest applications, software
                 implementations are more common.  The algorithm should
                 be efficient on 32-bit microprocessors with 4 kbyte
                 program and data caches.

         Medium-size processors.  The algorithm should run on
                 microcontrollers and other medium-size processors, such
                 as the 68HC11.

         Small processors.  It should be possible to implement the
         algorithm on smart cards, even inefficiently.

The requirements for small processors are the most difficult. 
RAM and ROM limitations are severe for this platform.  Also,
efficiency is more important on these small machines. 
Workstations double their capacity almost annually.  Small
embedded systems are the same year after year, and there is
little capacity to spare.  If there is a choice, the extra
computation burden should be on large processors rather than
small processors.


These additional requirements should, if possible, be levied on a
standard encryption algorithm.

         The algorithm should be simple to code.  Experiences with
         DES [19] show that programmers will often make
         implementation mistakes if the algorithm is complicated.  If
         possible, the algorithm should be robust against these

         The algorithm should have a flat keyspace, allowing any
         random bit string of the required length to be a possible
         key.  There should be no weak keys.

         The algorithm should facilitate easy key-management for
         software implementations.  Software implementations of DES
         generally use poor key management techniques.  In
         particular, the password that the user types in becomes the
         key.  This means that although DES has a theoretical
         keyspace of 256, the actual keyspace is limited to keys
         constructed with the 95 characters of printable ASCII. 
         Additionally, keys corresponding to words and near words are
         much more likely.

         The algorithm should be easily modifiable for different
         levels of security, both minimum and maximum requirements.

         All operations should manipulate data in byte-sized blocks. 
         Where possible, operations should manipulate data in 32-bit


Based on the above parameters, we have made these design
decisions.  The algorithm should:

         Manipulate data in large blocks, preferably 32 bits in size
         (and not in single bits, such as DES).

         Have either a 64-bit or a 128-bit block size.

         Have a scalable key, from 32 bits to at least 256 bits.

         Use simple operations that are efficient on microprocessors: 
         e.g., exclusive-or, addition, table lookup, modular-
         multiplication.  It should not use variable-length shifts or
         bit-wise permutations, or conditional jumps.

         Be implementable on an 8-bit processor with a minimum of 24
         bytes of RAM (in addition to the RAM required to store the
         key) and 1 kilobyte of ROM.

         Employ precomputable subkeys.  On large-memory systems,
         these subkeys can be precomputed for faster operation.  Not
         precomputing the subkeys will result in slower operation,
         but it should still be possible to encrypt data without any

         Consist of a variable number of iterations.  For
         applications with a small key size, the trade-off between
         the complexity of a brute-force attack and a differential
         attack make a large number of iterations superfluous. 
         Hence, it should be possible to reduce the number of
         iterations with no loss of security (beyond that of the
         reduced key size).

         If possible, have no weak keys.  If not possible, the
         proportion of weak keys should be small enough to make it
         unlikely to choose one at random.  Also, any weak keys
         should be explicitly known so they can be weeded out during
         the key generation process.

         Use subkeys that are a one-way hash of the key.  This would
         allow the use of long passphrases for the key without
         compromising security.

         Have no linear structures (e.g., the complementation
         propertie of DES) that reduce the complexity of exhaustive
         search [4].

         Use a design that is simple to understand.  This will
         facilitate analysis and increase the confidence in the
         algorithm.  In practice, this means that the algorithm will
         be a Feistel iterated block cipher [21].

Most of these design decisions are not new.  Almost all block
ciphers since Lucifer [5,21] are Feistel ciphers, and all have a
flat keyspace (with the possible exception of a few weak keys). 
FEAL [13,14,15] and Khufu [11] use a variable number of
iterations.  Khufu [11] has a large number of subkeys that are a
one-way function of the key.  RC2 [18] has a variable-length key. 
GOST [6] uses a 32-bit word length and a 64-bit block size.  MMB
[2] uses a 32-bit word length and a 128-bit block size.


There are a number of building blocks that have been demonstrated
to produce strong ciphers.  Many of these can be efficiently
implemented on 32-bit microprocessors.

         Large S-boxes.  Larger S-boxes are more resistant to
         differential cryptanalysis.  An algorithm with a 32-bit word
         length can use 32-bit S-boxes.  Khufu and REDOC III both use
         a 256-entry, 32-bit wide S-box [11,20].

         Key-dependent S-boxes.  While fixed S-boxes must be designed
         to be resistant to differential and linear cryptanalysis,
         key-dependent S-boxes are much more resistant to these
         attacks.  They are used in the Khufu algorithm [11]. 
         Variable S-boxes, which could possibly be key dependent, are
         used in GOST [6].

         Combining operations from different algebraic groups.  The
         IDEA cipher introduced this concept, combining XOR mod 216,
         addition mod 216, and multiplication mod 216+1 [7].  The MMB
         cipher uses a 32-bit word, and combines XOR mod 232 with
         multiplication mod 232-1 [2].

         Key-dependent permutations.  The fixed initial and final
         permutations of DES have been long regarded as
         cryptographically worthless.  Khufu XORs the text block with
         key material at the beginning and the end of the algorithm


Blowfish is a variable-length key block cipher.  It does not meet
all the requirements for a new cryptographic standard discussed
above: it is only suitable for applications where the key does
not change often, like a communications link or an automatic file
encryptor.  It is significantly faster than DES when implemented
on 32-bit microprocessors with large data caches, such as the
Pentium and the PowerPC.


Blowfish is a variable-length key, 64-bit block cipher.  The
algorithm consists of two parts: a key-expansion part and a data-
encryption part.  Key expansion converts a key of at most 448
bits into several subkey arrays totaling 4168 bytes. 

Data encryption occurs via a 16-round Feistel network.  Each
round consists of a key-dependent permutation, and a key- and
data-dependent substitution.  All operations are XORs and
additions on 32-bit words.  The only additional operations are
four indexed array data lookups per round.


Blowfish uses a large number of subkeys.  These keys must be
precomputed before any data encryption or decryption.

         1.  The P-array consists of 18 32-bit subkeys:
                 P1, P2,..., P18.

         2.  There are four 32-bit S-boxes with 256 entries each:
                 S1,0, S1,1,..., S1,255; 
                 S2,0, S2,1,..,, S2,255;
                 S3,0, S3,1,..., S3,255;
                 S4,0, S4,1,..,, S4,255.

The exact method used to calculate these subkeys will be
described later.


Blowfish is a Feistel network consisting of 16 rounds (see Figure
1).  The input is a 64-bit data element, x.

         Divide x into two 32-bit halves:  xL, xR
         For i = 1 to 16:
                 xL = xL XOR Pi
                 xR = F(xL) XOR xR
                 Swap xL and xR
         Swap xL and xR  (Undo the last swap.)
         xR = xR XOR P17
         xL = xL XOR P18
         Recombine xL and xR

         Function F (see Figure 2):
                 Divide xL into four eight-bit quarters:  a, b, c, and d
                 F(xL) = ((S1,a + S2,b mod 232) XOR S3,c) + S4,d mod 232

Decryption is exactly the same as encryption, except that P1,
P2,..., P18 are used in the reverse order.

Implementations of Blowfish that require the fastest speeds
should unroll the loop and ensure that all subkeys are stored in

Generating the Subkeys:

The subkeys are calculated using the Blowfish algorithm.  The
exact method is as follows:

         1.  Initialize first the P-array and then the four S-boxes,
         in order, with a fixed string.  This string consists of the
         hexadecimal digits of pi (less the initial 3).  For example:

                 P1 = 0x243f6a88
                 P2 = 0x85a308d3 
                 P3 = 0x13198a2e
                 P4 = 0x03707344 

         2.  XOR P1 with the first 32 bits of the key, XOR P2 with the
         second 32-bits of the key, and so on for all bits of the key
         (possibly up to P14).  Repeatedly cycle through the key bits
         until the entire P-array has been XORed with key bits.  (For
         every short key, there is at least one equivalent longer
         key; for example, if A is a 64-bit key, then AA, AAA, etc.,
         are equivalent keys.)

         3.  Encrypt the all-zero string with the Blowfish algorithm,
         using the subkeys described in steps (1) and (2).

         4.  Replace P1 and P2 with the output of step (3).

         5.  Encrypt the output of step (3) using the Blowfish
         algorithm with the modified subkeys.

         6.  Replace P3 and P4 with the output of step (5).

         7.  Continue the process, replacing all entries of the P-
         array, and then all four S-boxes in order, with the output
         of the continuously-changing Blowfish algorithm.

In total, 521 iterations are required to generate all required
subkeys.  Applications can store the subkeys rather than execute
this derivation process multiple times.


The following mini versions of Blowfish are defined solely for
cryptanalysis.  They are not suggested for actual implementation. 
Blowfish-32 has a 32-bit block size and subkey arrays of 16-bit
entries (each S-box has 16 entries).  Blowfish-16 has a 16-bit
block size and subkey arrays of 8-bit entries (each S-box has 4


The underlying philosophy behind Blowfish is that simplicity of
design yields an algorithm that is both easier to understand and
easier to implement.  Through the use of a streamlined Feistel
networkþa simple S-box substitution and a simple P-box
substitutionþI hope that the design will not contain any flaws.

A 64-bit block size yields a 32-bit word size, and maintains
block-size compatibility with existing algorithms.  Blowfish is
easy to scale up to a 128-bit block, and down to smaller block
sizes.  Cryptanalysis of the mini-Blowfish variants may be
significantly easier than cryptanalysis of the full version.

The fundamental operations were chosen with speed in mind.  XOR,
ADD, and MOV from a cache are efficient on both Intel and
Motorola architectures.  All subkeys fit in the cache of a 80486,
68040, Pentium, and PowerPC.

The Feistel network that makes up the body of Blowfish is
designed to be as simple as possible, while still retaining the
desirable cryptographic properties of the structure.  Figure 3 is
round i of a general Feistel network:  Rn,i are reversible
functions of text and key, and Ni is a non-reversible function of
text and key.  For speed and simplicity, I chose XOR as my
reversible function.  This let me collapse the four XORs into a
single XOR, since:

         Rþ1,i+1 = R1,i+1 XOR R2,i-1 XOR R3,i XOR R4,i

This is the P-array substitution in Blowfish.  The XOR can also
be considered to be part of the non-reversible function, Ni,
occurring at the end of the function.  (Although equivalent, I
chose not to illustrate them in this way because it simplifies
description of the subkey-generation process.)  There are two
XORs that remain after this reduction: R1 in the first round and
R2 in the last round.  I chose not to eliminate these in order to
hide the input to the first non-reversible function.

I considered a more complicated reversible function, one with
modular multiplications and rotations.  However, these operations
would greatly increase the algorithm's execution time.  Since
function F is the primary source of the algorithm's security, I
decided to save time-consuming complications for that function.

Function F, the non-reversible function, gives Blowfish the best
possible avalanche effect for a Feistel network:  every text bit
on the left half of the round affects every text bit on the right
half.  Additionally, since every subkey bit is affected by every
key bit, the function also has a perfect avalanche effect between
the key and the right half of the text after every round.  Hence,
the algorithm exhibits a perfect avalanche effect after three
rounds and again every two rounds after that.

I considered adding a reversible mixing function, more
complicated than XOR, before the first and after the last round. 
This would further confuse the entry values into the Feistel
network and ensure a complete avalanche effect after the first
two rounds.  I eventually discarded the addition as a time-
consuming complication with no clear cryptographic benefits.

The non-reversible function is designed for strength, speed, and
simplicity.  Ideally, I wanted a single S-box with 232 32-bit
words, but that was impractical.  My eventual choice of 256-entry
S-boxes was a compromise between my three design goals.  The
small-number of bits to large-number of bits may have weaknesses
with respect to linear cryptanalysis, but these weaknesses are
hidden both by combining the output of four S-boxes and making
them dependent on the key.

I used four different S-boxes instead of one S-box primarily to
avoid symmetries when different bytes of the input are equal, or
when the 32-bit input to function F is a bytewise permutation of
another 32-bit input.  I could have used one S-box and made each
of the four different outputs a non-trivial permutation of the
single output, but the four S-box design is faster, easier to
program, and seems more secure.

The function that combines the four S-box outputs is as fast as
possible.  A simpler function would be to XOR the four values,
but mixing addition mod 232 and XOR combines two different
algebraic groups with no additional instructions.  The
alternation of addition and XOR ends with an addition operation
because an XOR combines the final result with xR.

If the four indexes chose values out of the same S-box, a more
complex combining function would be required to eliminate
symmetries.  I considered using a more complex combining function
in Blowfish (using modular multiplications, rotations, etc.), but
chose not to because the added complication seemed unnecessary.

The key-dependent S-boxes protect against differential and linear
cryptanalysis.  Since the structure of the S-boxes is completely
hidden from the cryptanalyst, these attacks have a more difficult
time exploiting that structure.  While it would be possible to
replace these variable S-boxes with four fixed S-boxes that were
designed to be resistant to these attacks, key-dependent S-boxes
are easier to implement and less susceptible to arguments of
"hidden" properties.  Additionally, these S-boxes can be created
on demand, reducing the need for large data structures stored
with the algorithm.

Each bit of xL is only used as the input to one S-box.  In DES
many bits are used as inputs to two S-boxes, which strengthens
the algorithm considerably against differential attacks.  I feel
that this added complication is not as necessary with key-
dependent S-boxes.  Additionally, larger S-boxes would take up
considerably more memory space.

Function F does not depend on the iteration.  I considered adding
this dependency, but did not feel that it had any cryptographic
merit.  The P-array substitution can be considered to be part of
this function, and that is already iteration-dependent.

The number of rounds is set at 16 primarily out of desire to be
conservative.  However, this number affects the size of the P-
array and therefore the subkey-generation process; 16 iterations
permits key lengths up to 448 bits.  I expect to be able to
reduce this number, and greatly speed up the algorithm in the
process, as I accumulate more cryptanalysis data.

In algorithm design, there are two basic ways to ensure that the
key is long enough to ensure a particular security level.  One is
to carefully design the algorithm so that the entire entropy of
the key is preserved, so there is no better way to cryptanalyze
the algorithm other than brute force.  The other is to design the
algorithm with so many key bits that attacks that reduce the
effective key length by several bits are irrelevant.  Since
Blowfish is designed for large microprocessors with large amounts
of memory, I chose the latter.

The subkey generation process is designed to preserve the entire
entropy of the key and to distribute that entropy uniformly
throughout the subkeys.  It is also designed to distribute the
set of allowed subkeys randomly throughout the domain of possible
subkeys.  I chose the digits of pi as the initial subkey table
for two reasons: because it is a random sequence not related to
the algorithm, and because it could either be stored as part of
the algorithm or derived when needed.  There is nothing sacred
about pi; any string of random bitsþdigits of e, RAND tables,
output of a random number generatorþwill suffice.  However, if
the initial string is non-random in any way (for example, ASCII
text with the high bit of every byte a 0), this non-randomness
will propagate throughout the algorithm.

In the subkey generation process, the subkeys change slightly
with every pair of subkeys generated.  This is primarily to
protect against any attacked of the subkey generation process
that exploit the fixed and known subkeys.  It also reduces
storage requirements.  The 448 limit on the key size ensures that
the every bit of every subkey depends on every bit of the key. 
(Note that every bit of P15, P16, P17, and P18 does not affect every
bit of the ciphertext, and that any S-box entry only has a .06
probability of affecting any single ciphertext block.)

The key bits are repeatedly XORed with the digits of pi in the
initial P-array to prevent the following potential attack: 
Assume that the key bits are not repeated, but instead padded
with zeros to extend it to the length of the P-array.  An
attacker might find two keys that differ only in the 64-bit value
XORed with P1 and P2 that, using the initial known subkeys,
produce the same encrypted value.  If so, he can find two keys
that produce all the same subkeys.  This is a highly tempting
attack for a malicious key generator.

To prevent this same type of attack, I fixed the initial
plaintext value in the subkey-generation process.  There is
nothing special about the all-zeros string, but it is important
that this value be fixed.

The subkey-generation algorithm does not assume that the key bits
are random.  Even highly correlated key bits, such as an
alphanumeric ASCII string with the bit of every byte set to 0,
will produce random subkeys.  However, to produce subkeys with
the same entropy, a longer alphanumeric key is required.

The time-consuming subkey-generation process adds considerable
complexity for a brute-force attack.  The subkeys are too long to
be stored on a massive tape, so they would have to be generated
by a brute-force cracking machine as required.  A total of 522
iterations of the encryption algorithm are required to test a
single key, effectively adding 29 steps to any brute-force


I am exploring several possible simplifications, aimed at
decreasing memory requirements and execution time.  These are
outlined below:

         Fewer and smaller S-boxes.  It may be possible to reduce the
         number of S-boxes from four to one.  Additionally, it may be
         possible to overlap entries in a single S-box: entry 0 would
         consist of bytes 0 through 3, entry 1 would consist of bytes
         1 through 4, etc.  The former simplification would reduce
         the memory requirements for the four S-boxes from 4096 bytes
         to 1024 bytes, the latter would reduce the requirements for
         a single S-box from 1024 bytes to 259 bytes.  Additional
         steps may be required to eliminate the symmetries that these
         simplifications would introduce.  Additionally, four
         different 10- or 12-bit indexes into a single large S-box
         could be used instead of the current series of S-boxes.

         Fewer iterations.  It is probably safe to reduce the number
         of iterations from 16 to 8 without compromising security. 
         The number of iterations required for security may be
         dependent on the length of the key.  Note that with the
         current subkey generation procedure, an 8-iteration
         algorithm cannot accept a key longer than 192 bits.

         On-the-fly subkey calculation.  The current method of subkey
         calculation requires all subkeys to be calculated advance of
         any data encryption.  In fact, it is impossible to calculate
         the last subkey of the last S-box without calculating every
         subkey that comes before.  An alternate method of subkey
         calculation would be preferable:  one where every subkey can
         be calculated independently of any other.  High-end
         implementations could still precompute the subkeys for
         increased speed, but low-end applications could only compute
         the required subkeys when needed.


I conjecture that the most efficient way to break Blowfish is
through exhaustive search of the keyspace.  I encourage all
cryptanalytic attacks, modifications, and improvements to the
algorithm.  Attacks on mini versions of Blowfish, those with a
32- or even a 16-bit block size, are also encouraged.  Source
code in C and test data can be provided to anyone wishing to
implement the algorithm, in accordance with U.S. export laws.

The software magazine Dr. Dobbs Journal is sponsoring $1000
contest for the best cryptanalysis of Blowfish received before
April 1995.  Please contact me for details.

Blowfish is unpatented, and will remain so in all countries.  The
algorithm is hereby placed in the public domain, and can be
freely used by anyone.


Much of the motivation for this algorithm, as well as the design
criteria, was developed with Niels Fergusen.  I would also like
to thank Eli Biham, Agnes Chan, Peter Gutmann, Angel Johnston,
Lars Kundsen, and Matt Robshaw for their helpful suggestions.


1.  E. Biham and A. Shamir, Differential Cryptanalysis of the
         Data Encryption Standard, Springer-Verlag, 1993.

2.  T.W. Cusick and M.C. Wood, "The REDOC-II Cryptosystem,"
         Advances in CryptologyþCRYPTO '90 Proceedings, Springer-
         Verlag, 1991, pp. 545-563.

3.  J. Deamen, R. Govaerts, and J. Vandewalle, "Block Ciphers
         Based on Modular Arithmetic," Proceedings of the 3rd
         Symposium on State and Progress of Research in Cryptography,
         Rome, Italy, 15-16 Feb 1993, pp. 80-89.

4.  J.-H. Evertse, "Linear Structures in Blockciphers,"  Advances
         in CryptologyþEUROCRPYT '87, Springer-Verlag, 1988, pp. 249-

5.  H. Feistel, "Cryptography and Computer Privacy," Scientific
         American, v. 228, n. 5, May 73, pp. 15-23.

6.  GOST 28147-89, "Cryptographic Protection for Data Processing
         Systems,"  "Cryptographic Transformation Algorithm,"
         Government Standard of the U.S.S.R., Inv. No. 3583, UDC
         681.325.6:006.354.  (in Russian)

7.  X. Lai, J. Massey, and S. Murphy, "Markov Ciphers and
         Differential Cryptanalysis," Advances in
         CryptologyþEUROCRYPT '91 Proceedings, Springer-Verlag, 1991,
         pp. 17-38.

8.  J.L. Massey and X. Lai, "Device for Converting a Digital
         Block and the Use Thereof," International Patent
         PCT/CH91/00117, 16 May 1991.

9.  J.L. Massey and X. Lai, "Device for the Conversion of a
         Digital Block and Use of Same," U.S. Patent 5,214,703, 25
         May 1993.

10.  M. Matsui, "Linear Cryptanalysis Method for DES Cipher,"
         Advances in CryptologyþCRYPTO '93 Proceedings, Springer-
         Verlag, 1994, in preparation.

11.  R.C. Merkle, "Fast Software Encryption Functions," Advances
         in CryptologyþCRYPTO '90 Proceedings, Springer-Verlag, 1991,
         pp. 476-501.

12.  R.C. Merkle, "Method and Apparatus for Data Encryption,"
         U.S. Patent 5,003,597, 26 Mar 1991.

13.  S. Miyaguchi, "The FEAL-8 Cryptosystem and Call for Attack,"
         Advances in CryptologyþCRYPTO '89 Proceedings, Springer-
         Verlag, 1990, pp. 624-627.

14.  S. Miyaguchi, "Expansion of the FEAL Cipher," NTT Review, v.
         2, n. 6, Nov 1990.

15.  S. Miyaguchi, "The FEAL Cipher Family," Advances in
         CryptologyþCRYPTO '90 Proceedings, Springer-Verlag, 1991,
         pp. 627-638.

16.  National Bureau of Standards, Data Encryption Standard, U.S.
         Department of Commerce, FIPS Publication 46, Jan 1977.

17.  National Institute of Standards and Technology, "Clipper
         Chip Technology," 30 Apr 1993.
18.  RSA Laboratories, Answers to Frequently Asked Questions
         About Today's Cryptography, Revision 2.0, RSA Data Security
         Inc., 5 Oct 1993.

19.  B. Schneier, "Data Guardians," MacWorld, Feb 1993, 145-151.

20.  B. Schneier, Applied Cryptography, John Wiley & Sons, New
         York, 1994.

21.  J.L Smith, The Design of Lucifer, A Cryptographic Device for
         Data Communication, RC 3326, White Plains: IBM Research.

22.  M.J. Weiner, "Efficient DES Key Search," Advances in
         CryptologyþCRYPTO '93 Proceedings, Springer-Verlag, in

23.  M.C. Wood, "Method of Cryptographically Transforming
         Electronic Digital Data from One Form to Another," U.S.
         Patent 5,003,596, 26 Mar 1991.

--- NEW FILE: blowfish.c ---
		blowfish.c -- handles:
		encryption and decryption of passwords

		The first half of this is very lightly edited from public domain
		sourcecode.	For simplicity, this entire module will remain public

#include "blowfish.h"
#include "bf_tab.h"		/* P-box P-array, S-box	*/

#define BOXES	3

/* #define S(x,i) (bf_S[i][x.w.byte##i])	*/
#define S0(x) (bf_S[0][x.w.byte0])
#define S1(x) (bf_S[1][x.w.byte1])
#define S2(x) (bf_S[2][x.w.byte2])
#define S3(x) (bf_S[3][x.w.byte3])
#define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x))
#define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n])

/* keep a set of rotating P & S boxes */
static struct box_t {
	UWORD_32bits *P;
	UWORD_32bits **S;
	char key[81];
	char keybytes;
	time_t lastuse;
} blowbox[BOXES];

	static UWORD_32bits bf_P[bf_N+2];
	static UWORD_32bits bf_S[4][256];

static UWORD_32bits *bf_P;
static UWORD_32bits **bf_S;

static char blowfish_version[] = "BitchX blowfish encryption module v1.0";

static void blowfish_encipher (UWORD_32bits * xl, UWORD_32bits * xr)
	union aword Xl;
	union aword Xr;

	Xl.word = *xl;
	Xr.word = *xr;

	Xl.word ^= bf_P[0];
	ROUND(Xr, Xl, 1);
	ROUND(Xl, Xr, 2);
	ROUND(Xr, Xl, 3);
	ROUND(Xl, Xr, 4);
	ROUND(Xr, Xl, 5);
	ROUND(Xl, Xr, 6);
	ROUND(Xr, Xl, 7);
	ROUND(Xl, Xr, 8);
	ROUND(Xr, Xl, 9);
	ROUND(Xl, Xr, 10);
	ROUND(Xr, Xl, 11);
	ROUND(Xl, Xr, 12);
	ROUND(Xr, Xl, 13);
	ROUND(Xl, Xr, 14);
	ROUND(Xr, Xl, 15);
	ROUND(Xl, Xr, 16);
	Xr.word ^= bf_P[17];

	*xr = Xl.word;
	*xl = Xr.word;

static void blowfish_decipher (UWORD_32bits * xl, UWORD_32bits * xr)
	union aword Xl;
	union aword Xr;

	Xl.word = *xl;
	Xr.word = *xr;

	Xl.word ^= bf_P[17];
	ROUND(Xr, Xl, 16);
	ROUND(Xl, Xr, 15);
	ROUND(Xr, Xl, 14);
	ROUND(Xl, Xr, 13);
	ROUND(Xr, Xl, 12);
	ROUND(Xl, Xr, 11);
	ROUND(Xr, Xl, 10);
	ROUND(Xl, Xr, 9);
	ROUND(Xr, Xl, 8);
	ROUND(Xl, Xr, 7);
	ROUND(Xr, Xl, 6);
	ROUND(Xl, Xr, 5);
	ROUND(Xr, Xl, 4);
	ROUND(Xl, Xr, 3);
	ROUND(Xr, Xl, 2);
	ROUND(Xl, Xr, 1);
	Xr.word ^= bf_P[0];

	*xl = Xr.word;
	*xr = Xl.word;

static void blowfish_init (UBYTE_08bits * key, short keybytes)
	int i, j, bx;
	time_t lowest;
	UWORD_32bits data;
	UWORD_32bits datal;
	UWORD_32bits datar;
	union aword temp;

	/* is buffer already allocated for this? */
	for (i = 0; i < BOXES; i++)
		if (blowbox[i].P != NULL) 
			if ((blowbox[i].keybytes == keybytes) &&
				(strncmp((char *) (blowbox[i].key), (char *) key, keybytes) == 0)) 
				blowbox[i].lastuse = now;
				bf_P = blowbox[i].P;
				bf_S = blowbox[i].S;
		/* no pre-allocated buffer: make new one */
		/* set 'bx' to empty buffer */
	bx = (-1);
	for (i = 0; i < BOXES; i++) 
		if (blowbox[i].P == NULL) 
			bx = i;
			i = BOXES + 1;
	if (bx < 0) 
		/* find oldest */
		lowest = now;
		for (i = 0; i < BOXES; i++)
			if (blowbox[i].lastuse <= lowest) 
				lowest = blowbox[i].lastuse;
				bx = i;
		for (i = 0; i < 4; i++)
	/* initialize new buffer */
	/* uh... this is over 4k */
	blowbox[bx].P = (UWORD_32bits *) new_malloc((bf_N + 2) * sizeof(UWORD_32bits));
	blowbox[bx].S = (UWORD_32bits **) new_malloc(4 * sizeof(UWORD_32bits *));
	for (i = 0; i < 4; i++)
		blowbox[bx].S[i] = (UWORD_32bits *) new_malloc(256 * sizeof(UWORD_32bits));
	bf_P = blowbox[bx].P;
	bf_S = blowbox[bx].S;
	blowbox[bx].keybytes = keybytes;
	strncpy(blowbox[bx].key, key, keybytes);
	blowbox[bx].lastuse = now;

	/* robey: reset blowfish boxes to initial state */
	/* (i guess normally it just keeps scrambling them, but here it's */
	/* important to get the same encrypted result each time) */
	for (i = 0; i < bf_N + 2; i++)
		bf_P[i] = initbf_P[i];
	for (i = 0; i < 4; i++)
		for (j = 0; j < 256; j++)
	bf_S[i][j] = initbf_S[i][j];

	j = 0;
	for (i = 0; i < bf_N + 2; ++i) 
		temp.word = 0;
		temp.w.byte0 = key[j];
		temp.w.byte1 = key[(j + 1) % keybytes];
		temp.w.byte2 = key[(j + 2) % keybytes];
		temp.w.byte3 = key[(j + 3) % keybytes];
		data = temp.word;
		bf_P[i] = bf_P[i] ^ data;
		j = (j + 4) % keybytes;

	datal = 0x00000000;
	datar = 0x00000000;

	for (i = 0; i < bf_N + 2; i += 2) 
		blowfish_encipher(&datal, &datar);
		bf_P[i] = datal;
		bf_P[i + 1] = datar;

	for (i = 0; i < 4; ++i) 
		for (j = 0; j < 256; j += 2) 
			blowfish_encipher(&datal, &datar);
			bf_S[i][j] = datal;
			bf_S[i][j + 1] = datar;

/* stuff below this line was written by robey for eggdrop use */

/* convert 64-bit encrypted password to text for userfile */
static char *base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

static int base64dec (char c)
	int i;
	for (i = 0; i < 64; i++)
		if (base64[i] == c)
			return i;
	return 0;

/* returned string must be freed when done with it! */
static char *encrypt_string (char * key, char * str)
	UWORD_32bits left, right;
	char *p, *s, *dest, *d;
	int i;
	dest = (char *) new_malloc((strlen(str) + 9) * 2);
	/* pad fake string with 8 bytes to make sure there's enough */
	s = (char *) new_malloc(strlen(str) + 9);
	strcpy(s, str);
	p = s;
	while (*p)
	for (i = 0; i < 8; i++)
		*p++ = 0;
	blowfish_init(key, strlen(key));
	p = s;
	d = dest;
	while (*p) 
		left = ((*p++) << 24);
		left += ((*p++) << 16);
		left += ((*p++) << 8);
		left += (*p++);
		right = ((*p++) << 24);
		right += ((*p++) << 16);
		right += ((*p++) << 8);
		right += (*p++);
		blowfish_encipher(&left, &right);
		for (i = 0; i < 6; i++) 
			*d++ = base64[right & 0x3f];
			right = (right >> 6);
		for (i = 0; i < 6; i++) 
			*d++ = base64[left & 0x3f];
			left = (left >> 6);
	*d = 0;
	return dest;

/* returned string must be freed when done with it! */
static char *decrypt_string (char * key, char * str)
	UWORD_32bits left, right;
	char *p, *s, *dest, *d;
	int i;
	dest = (char *) new_malloc(strlen(str) + 12);
	/* pad encoded string with 0 bits in case it's bogus */
	s = (char *) new_malloc(strlen(str) + 12);
	strcpy(s, str);
	p = s;
	while (*p)
	for (i = 0; i < 12; i++)
		*p++ = 0;
	blowfish_init(key, strlen(key));
	p = s;
	d = dest;
	while (*p) {
		right = 0L;
		left = 0L;
		for (i = 0; i < 6; i++)
			right |= (base64dec(*p++)) << (i * 6);
		for (i = 0; i < 6; i++)
			left |= (base64dec(*p++)) << (i * 6);
		blowfish_decipher(&left, &right);
		for (i = 0; i < 4; i++)
			*d++ = (left & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
		for (i = 0; i < 4; i++)
			*d++ = (right & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
	*d = 0;
	return dest;

#ifdef WANT_TCL
static int tcl_encrypt STDVAR
	char *p;
	BADARGS(3, 3, " key string");
	p = encrypt_string(argv[1], argv[2]);
	Tcl_AppendResult(irp, p, NULL);
	return TCL_OK;

static int tcl_decrypt STDVAR
	char *p;
	BADARGS(3, 3, " key string");
	p = decrypt_string(argv[1], argv[2]);
	Tcl_AppendResult(irp, p, NULL);
	return TCL_OK;

#endif /* WANT_TCL */

	char *p, *q, *r;
	if (!input) 
		return m_strdup("1");
	p = input;
	if ((q = strchr(input, ' '))) 
		*q++ = 0; 
		r = encrypt_string(p, q);
		return r;
	return m_strdup(empty_string);

	char *p, *q, *r;
	if (!input) 
		return m_strdup("1");
	p = input;
	if ((q = strchr(input, ' '))) 
		*q++ = 0; 
		r = decrypt_string(p, q);
		return r;
	return m_strdup(empty_string);

int Blowfish_Init(IrcCommandDll **intp, Function_ptr *global_table)
	int i;
	for (i = 0; i < BOXES; i++) {
		blowbox[i].P = NULL;
		blowbox[i].S = NULL;
		blowbox[i].key[0] = 0;
		blowbox[i].lastuse = 0L;
#ifdef WANT_TCL
	Tcl_CreateCommand(tcl_interp, "encrypt", tcl_encrypt, NULL, NULL);
	Tcl_CreateCommand(tcl_interp, "decrypt", tcl_decrypt, NULL, NULL);
	Tcl_SetVar(tcl_interp, "blowfish_version", blowfish_version, TCL_GLOBAL_ONLY);
	add_module_proc(ALIAS_PROC, "blowfish", "encrypt", "Blowfish Encryption", 0, 0, ircii_encrypt, NULL);
	add_module_proc(ALIAS_PROC, "blowfish", "decrypt", "Blowfish Decryption", 0, 0, ircii_decrypt, NULL);
  put_it("%s loaded.", blowfish_version);
  put_it("Adapted from eggdrop by By-Tor");
  return 0;

int Blowfish_Cleanup(IrcCommandDll **intp)
#ifdef WANT_TCL
	Tcl_DeleteCommand(tcl_interp, "encrypt");
	Tcl_DeleteCommand(tcl_interp, "decrypt");
	Tcl_UnsetVar(tcl_interp, "blowfish_version", TCL_GLOBAL_ONLY);
	return 1;

This is a hacked up blowfish encryption module for bitchx...
It is stolen from eggdrop. And no, im not going to include the entire
eggdrop source. If you want it, go get it. Otherwise, bleh!

--- NEW FILE: bot-crypt.tcl ---
global crypttimeout cryptlength
set crypttimeout 60
set cryptlength 50
#borrowed from alltools.tcl
proc randstring {count} {
  set rs ""
  for {set j 0} {$j < $count} {incr j} {
     set x [rand 62]
     append rs [string range "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" $x $x]
  unset x
  unset j
  return $rs

bind msg o crypt_op crypt_challenge
bind msg o crypt_reply crypt_response

proc crypt_challenge {n u h a} {
	global cryptlist crypttimeout crypt_string cryptlength
	set ln [string tolower $n]
	if {[llength [getuser $h XTRA crypt]] != 2} {
		putserv "notice $n :You have no crypt keys set."
		return 0
	if [info exists cryptlist($ln)] {
		putlog "Ignoring outstanding crypt-op request from $n."
		return 0
	} {
		set cryptlist($ln) [utimer $crypttimeout "unset cryptlist($ln)"]
		putserv "privmsg $ln :crypt_op [encrypt [lindex [getuser $h XTRA crypt] 0] [set crypt_string($ln) [randstring $cryptlength]]]"

proc crypt_response {n u h a} {
	global cryptlist crypt_string
	set ln [string tolower $n]
	if {![info exists cryptlist($ln)]} {
		putlog "Ignoring unrequested or late crypt response from $n."
		return 0
	if {![string compare $crypt_string($ln) [decrypt [lindex [getuser $h XTRA crypt] 1] $a]]} {
		killutimer $cryptlist($ln)
		unset cryptlist($ln)
		foreach	chan [channels] {
			if [onchan $n $chan] {
				pushmode $chan +o $n
		putlog "($n@$u) !$h! crypt-op"
	} {
		putlog "$n ($h) FAILED crypt authorization!"
	return 0

bind dcc o crypt crypt_set

proc crypt_set {h i a} {
	if {[llength $a] != 2} {
		putdcc $i "Usage: crypt <key1> <key2>"
		return 0
	putdcc $i "Key1: [lindex $a 0] key2: [lindex $a 1]"
	if {![string compare [lindex $a 0] [lindex $a 1]]} {
		putdcc $i "key1 and key2 MUST be different."
		return 0
	setuser $h XTRA crypt $a
	putdcc $i "Set crypt keys to \"[lindex $a 0]\" and \"[lindex $a 1]\""
	putlog "#$h# crypt ..."
	return 0
--- NEW FILE: blowfish.sh ---
# Make .def file:
export LIBPATH=/usr/local/cygwin-new/i586-pc-cygwin/lib
export LD=/usr/local/cygwin-new/bin/i586-pc-cygwin-ld
export NM=/usr/local/cygwin-new/bin/i586-pc-cygwin-nm
export DLLTOOL=/usr/local/cygwin-new/bin/i586-pc-cygwin-dlltool
export AS=/usr/local/cygwin-new/bin/i586-pc-cygwin-as
export GCC=/usr/local/cygwin-new/bin/i586-pc-cygwin-gcc

$GCC -I../../include -c blowfish.c

echo EXPORTS > blowfish.def
$NM blowfish.o ../init.o ../fixup.o | grep '^........ [T] _' | sed 's/[^_]*_//' >> blowfish.def

# Link DLL.
$LD --base-file blowfish.base --dll -o blowfish.dll blowfish.o ../init.o ../fixup.o\
 $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry at 12
$DLLTOOL --as=$AS --dllname blowfish.dll --def blowfish.def --base-file\
 blowfish.base --output-exp blowfish.exp
$LD --base-file blowfish.base blowfish.exp --dll -o blowfish.dll blowfish.o\
 ../init.o ../fixup.o $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry at 12
$DLLTOOL --as=$AS --dllname blowfish.dll --def blowfish.def --base-file\
 blowfish.base --output-exp blowfish.exp
$LD blowfish.exp --dll -o blowfish.dll blowfish.o ../init.o ../fixup.o\
 $LIBPATH/libcygwin.a $LIBPATH/libkernel32.a -e _dll_entry at 12

# Build the blowfishB.a lib to link to:
$DLLTOOL --as=$AS --dllname blowfish.dll --def blowfish.def --output-lib blowfish.a

$RM *.base *.exp *.def
$CP *.dll ..

--- NEW FILE: bf_tab.h ---
/* bf_tab.h: Blowfish P-box and S-box tables */
#ifndef _H_TAB_BF
#define _H_TAB_BF

static UWORD_32bits initbf_P[bf_N + 2] = {
  0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
  0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
  0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
  0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
  0x9216d5d9, 0x8979fb1b,
static UWORD_32bits initbf_S[4][256] = {
  0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
  0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
  0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
  0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
  0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
  0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
  0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
  0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
  0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
  0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
  0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
  0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
  0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
  0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
  0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
  0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
  0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
  0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
  0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
  0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
  0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
  0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
  0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
  0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
  0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
  0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
  0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
  0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
  0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
  0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
  0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
  0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
  0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
  0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
  0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
  0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
  0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
  0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
  0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
  0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
  0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
  0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
  0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
  0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
  0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
  0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
  0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
  0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
  0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
  0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
  0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
  0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
  0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
  0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
  0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
  0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
  0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
  0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
  0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
  0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
  0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
  0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
  0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
  0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a },
  0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
  0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
  0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
  0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
  0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
  0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
  0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
  0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
  0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
  0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
  0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
  0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
  0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
  0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
  0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
  0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
  0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
  0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
  0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
  0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
  0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
  0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
  0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
  0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
  0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
  0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
  0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
  0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
  0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
  0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
  0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
  0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
  0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
  0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
  0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
  0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
  0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
  0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
  0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
  0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
  0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
  0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
  0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
  0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
  0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
  0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
  0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
  0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
  0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
  0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
  0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
  0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
  0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
  0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
  0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
  0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
  0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
  0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
  0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
  0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
  0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
  0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
  0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
  0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 },
  0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
  0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
  0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
  0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
  0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
  0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
  0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
  0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
  0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
  0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
  0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
  0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
  0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
  0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
  0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
  0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
  0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
  0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
  0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
  0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
  0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
  0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
  0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
  0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
  0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
  0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
  0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
  0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
  0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
  0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
  0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
  0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
  0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
  0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
  0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
  0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
  0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
  0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
  0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
  0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
  0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
  0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
  0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
  0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
  0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
  0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
  0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
  0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
  0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
  0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
  0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
  0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
  0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
  0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
  0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
  0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
  0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
  0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
  0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
  0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
  0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
  0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
  0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
  0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 },
  0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
  0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
  0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
  0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
  0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
  0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
  0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
  0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
  0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
  0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
  0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
  0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
  0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
  0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
  0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
  0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
  0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
  0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
  0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
  0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
  0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
  0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
  0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
  0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
  0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
  0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
  0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
  0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
  0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
  0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
  0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
  0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
  0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
  0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
  0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
  0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
  0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
  0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
  0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
  0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
  0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
  0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
  0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
  0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
  0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
  0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
  0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
  0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
  0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
  0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
  0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
  0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
  0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
  0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
  0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
  0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
  0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
  0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
  0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
  0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
  0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
  0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
  0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
  0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 }


This is a total rip-off of the eggdrop blowfish implementation. Some
versions of tcl will have trouble encrypting strings with a ";" in them, so
use quotes...


More information about the dslinux-commit mailing list