hey emacs, show me an -*- mode: outline -*-

* ciphers to add

CAST6
SEED
MARS
Serpent
Camellia
...others?...

* add OpenPGP functions

This would involve writing some simple base64 encoding and decoding.
I'm not sure how to add this and achieve the right amount of generality
and functionality.  Just writing an OpenPGP parser is straightforward,
but determining what to do with the data is a little more complicated.

* add {EN,DE}CRYPTING-STREAM capabilities

Encrypts data written to it before writing the (now-encrypted) data to
an underlying stream.  Of course, the equivalent functionality is
available for decrypting.  This might finesse the current lack of
padding functionality in the library: when the stream is closed, the
appropriate amount and kind of padding is added.  Not sure that this is
necessarily the right idea, although when people are encrypting data,
they are generally doing so before writing said data someplace else.  I
don't encrypt data in memory just for the fun of it.

(These are partially written, see octet-stream.lisp.)

* make a condition hierarchy for the library

Throwing general ERRORs everywhere is not very helpful for understanding
what's going wrong.

Some conditions have been added as of 0.7, but there probably need to be
more, with helpful messages along the way.

* move generic function definitions to their own file

There's a lot of generic function definitions floating around as of
version 0.5 and there are likely to be many more as the library grows.
Perhaps the DEFGENERIC forms should be moved into their own file;
such a change would make the source tree cleaner and provide a good
starting point for people interested in examining the library's
functionality.

* add functional version of encryption and decryption

{ENCRYPT,DECRYPT}-MESSAGE would be perfect for this; although they were
originally conceived for public-key operations (and therefore they have
to return a fresh octet vector), they make perfect candidates for
providing functional interfaces to encryption and decryption as well.
Figuring out short block interfaces for this and padding issues,
however, will be a little tricky.

* remove generic function calls from inner loops

ENCRYPT-WITH-MODE, by virtue of calling <CIPHER>-ENCRYPT-BLOCK on
every iteration of the loop, requires <CIPHER>-ENCRYPT-BLOCK to
repeatedly extract the cipher-specific data from the provided cipher
context.  No idea if this is a bottleneck (probably not).

Doing this extraction on every iteration of the loop is overhead,
though--unnecessary overhead compared to a C implementation.  Pulling
the extraction out of the loop in a clean, cipher-independent manner is
probably pretty hairy, however.

* figure out interface for extra cipher creation parameters

RC5, for instance, is configurable in the number of rounds.  The number
of rounds must be fixed the way the current system works.  Configuring
the number of rounds for TEA and XTEA would be another example of where
this is useful.  Surely there are other reasons, too.

* add more cipher modes of operation

CBC with ciphertext stealing (CBC-CTS) (this would require some sort
of ENCRYPT-FINAL-BLOCK interface so we would know when to perform the
ciphertext stealing)
PCBC, for all those Lispers who want to implement Kerberos 4

* add padding primitives

This should be combined, somehow, with an ENCRYPT-FINAL-BLOCK generic
function.  This lets the caller do padding and encryption in one shot.

An alternative to ENCRYPT-FINAL-BLOCK is to provide a
:PROCESS-FINAL-BLOCK argument to {ENCRYPT,DECRYPT}, which seems cleaner
and easier to add.

* Lispy bigger variants of SHA

SHA-384 and SHA-512 require 64-bit arithmetic, which is a pain to
implement portably and efficiently.

* add other MACs

The NESSIE project has a boatload of MAC recommendations with test
vectors and everything.  Adding other MACs would help with cleaning up
the MAC interface (or lack thereof).

* add other digests

Whirlpool, for example, would be nice to have (more 64-bit issues,
though).

Are there any other reputable hash functions?

* figure out interface for stream ciphers

WiderWake 4+1
SEAL (intellectual property issues, although that doesn't seem to stop
  many other crypto libraries)

* add public-key crypto

DSA signing and verification routines have been added as of version
0.11.  RSA, Elgamal, elliptic-curve crypto, and others remain to be
added.  One issue that has yet to be resolved is how to handle the
myriad signature/encryption schemes for RSA.

* blue-sky ideas

** implementation-specific algorithm implementations

Ironclad is written with implementations that are capable of performing
32-bit unboxed arithmetic in mind.  However, there is no reason to leave
other implementations out in the cold.  I particularly have in mind
ABCL, whose clean Java integration could facilitate using Java's crypto
routines for many of the algorithms Ironclad provides.

** compilable encryption and decryption routines

One trick that's commonly used in high-performance crypto libraries is
unrolling inner loops of ciphers, which are generally Feistel networks
of some sort.  This transformation has many benefits: avoiding jumps and
compiling more efficient code for structure accesses, to name two.
Ironclad features unrolled loops in various places (e.g. the CAST5 and
Blowfish ciphers).  Unrolled loops can be particularly helpful in Common
Lisp because the compiler can often optimize away things like array
bounds checks.

Unfortunately, this tends to limit the libraries to only handling a
fixed number of rounds (or other configurable parameters of block
ciphers).  Accomodating variable numbers of rounds makes life easier for
the truly paranoid and is more in the spirit of the ciphers as
originally designed.

One way of getting around this limitation would be to use Common Lisp's
provision of the COMPILE function at create-the-cipher time.  One could
compile--on demand--specialized encryption/decryption routines that only
accomodated a fixed number of rounds (or other static configuration
parameters).  This facility would be particularly helpful for those
ciphers whose round keys are variable in the number of rounds chosen;
bounds checking for accesses to these keys could be done away with
entirely (except perhaps for a check to ensure the round key vector is
of the proper length and type).  Furthermore, the round keys could
actually be compiled directly into the code--as 32-bit constant
arguments on the x86, for example.  Such a change would necessarily make
the compiled routines key-specific, but perhaps that would be OK.

(When reading the specifications for Blowfish and Twofish, the authors
make much of this capability by citing screaming performance numbers for
this scenario while noting that modifying the code for each individual
key is difficult.  In Ironclad, providing three differing levels of
generality--general, n-rounds-specific, and key-specific--would be
relatively easy compared to the difficulty of doing it in C.)

Changes to MAKE-CIPHER--a keyword argument specifying the level of
specialization--would be necessary.  Extensive changes to the individual
block ciphers would also be necessary.  Perhaps this sort of facility
need not be added to all ciphers; the common ones could come first
(e.g. AES) and less-common ones would be converted as people contributed
patches or needs were found for them.

** use word-aligned loads when possible

The current code uses byte loads + shifts and ors to fetch
(UNSIGNED-BYTE 32) values out of a (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*)).
Some implementations (I have in mind particularly SBCL and CMUCL) could
use a more efficient mechanism if the offset of the (UNSIGNED-BYTE 32)
value was known to be four-byte aligned.  Once this was done for each
encryption/decryption function for a particular block cipher, the
high-level generic functions could call efficient versions if possible,
eliminating some overhead.

There is actually some (SBCL) support for this in cipher.lisp, in the
alternate definition for WITH-WORDS.  It doesn't make that much of a
difference--at least not in the case where WITH-WORDS needs to check for
alignment and safety.  It might be a win if there were several
different *-ENCRYPT-BLOCK functions and the high-level ones knew which
one to call, but...
