summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/fluff.html158
-rw-r--r--doc/index.html182
-rw-r--r--doc/ironclad-doc.txt658
-rw-r--r--doc/ironclad.html182
-rw-r--r--doc/style.css77
5 files changed, 1257 insertions, 0 deletions
diff --git a/doc/fluff.html b/doc/fluff.html
new file mode 100644
index 0000000..7c80b16
--- /dev/null
+++ b/doc/fluff.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<HTML><HEAD><TITLE>Ironclad</TITLE><LINK TYPE="text/css" TITLE="default" REL="stylesheet" MEDIA="screen" HREF="style.css" /></HEAD><BODY><H1>Ironclad</H1><P>Ironclad is a cryptography library written entirely in
+Common Lisp. It includes support for several
+popular <A HREF="#ciphers">ciphers</A>, <A HREF="#digests">digests</A>, and <A HREF="#macs">MACs</A>. Rudimentary support for <A HREF="#public-key">public-key cryptography</A> is included. For several implementations that support Gray
+Streams, <A HREF="#gray-streams">support</A> is included for
+convenient stream wrappers.</P><H2>Installation</H2><P>Ironclad can be downloaded at <A HREF="http://www.method-combination.net/lisp/files/ironclad.tar.gz">http://www.method-combination.net/lisp/files/ironclad.tar.gz</A>.
+The latest version is 0.20.1.</P><P>It comes with an ASDF system definition, so <TT>(ASDF:OOS
+'ASDF:LOAD-OP :IRONCLAD)</TT> should be all that you need to get started.
+The testsuite can be run by substituting <TT>ASDF:TEST-OP</TT> for <TT>ASDF:LOAD-OP</TT> in the form above. All tests should pass successfully.
+If they do not, you have found a bug; please report it.</P><H2>License</H2><P>Ironclad is released under a MIT-like license; you can do pretty
+much anything you want to with the code except claim that you wrote
+it.</P><H2>Ciphers</H2><DIV CLASS="lisp-symbol"><A NAME="make-cipher"></A><TT><STRONG>make-cipher</STRONG> <EM>name</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM>mode</EM> <EM>initialization-vector</EM> <EM>padding</EM> =&gt; <EM>cipher</EM></TT><BR /></DIV><P>Return a cipher object suitable for use for both encryption and
+decryption.</P><P><EM>name</EM> denotes the encryption algorithm to use. <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A> will tell you the names of all supported ciphers;
+the short list of ones you are likely to be interested in is:</P><UL><LI>AES</LI><LI>DES</LI><LI>3DES</LI><LI>Blowfish</LI><LI>Twofish</LI><LI>RC5</LI><LI>RC6</LI><LI>Arcfour (RC4)</LI></UL><P><EM>name</EM> should be a symbol in the <TT>KEYWORD</TT> package; <TT>:AES</TT> for AES, <TT>:ARCFOUR</TT> for RC4, and so forth.</P><P><EM>mode</EM> describes the mode of operation for the cipher. Stream
+ciphers such as Arcfour can operate in only one mode, <TT>stream</TT>.
+Block ciphers such as AES and DES can operate in several different
+modes:</P><UL><LI>ECB</LI><LI>CBC</LI><LI>OFB</LI><LI>CFB (note that CFB mode is 'n'-bit CFB, where 'n' is the <A HREF="#block-length" STYLE="symbol">block-length</A> of the cipher)</LI><LI>CTR</LI></UL><P><EM>mode</EM> should be a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT>
+packages; <TT>:STREAM</TT>, <TT>IRONCLAD:OFB</TT>, and so forth. An error
+will be signaled if <EM>mode</EM> is not appropriate for the cipher <EM>name</EM>.</P><P><EM>initialization-vector</EM> (IV) should be supplied only if <EM>mode</EM>
+requires one. <EM>initialization-vector</EM> should be a <TT>(VECTOR
+(UNSIGNED-BYTE 8))</TT>. The supplied IV should be the same length as the
+<A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>name</EM>.</P><P><EM>key</EM> is, of course, the key for the cipher. <EM>key</EM> should be
+a <TT>(VECTOR (UNSIGNED-BYTE 8))</TT>.</P><P>If <EM>padding</EM> is supplied, the specified padding method will be
+used by <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> to handle short blocks when the <TT>:HANDLE-FINAL-BLOCK</TT> argument is supplied. Depending on the mode
+specified, <EM>padding</EM> may be ignored (e.g. OFB and CFB modes do not
+care about short blocks; neither do stream ciphers).</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>padding</EM> is currently ignored in all modes (and, by extension,
+so is <TT>:HANDLE-FINAL-BLOCK</TT>). This oversight is expected to be
+corrected in a future release.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="encrypt"></A><TT><STRONG>encrypt</STRONG> <EM>cipher</EM> <EM>plaintext</EM> <EM>ciphertext</EM> <EM><TT>&key</TT></EM> <EM>plaintext-start</EM> <EM>plaintext-end</EM> <EM>ciphertext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts data according to <EM>cipher</EM> from <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM> and continuing until <EM>plaintext-end</EM>. The encrypted data is placed in <EM>ciphertext</EM> starting at <EM>ciphertext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="decrypt"></A><TT><STRONG>decrypt</STRONG> <EM>cipher</EM> <EM>ciphertext</EM> <EM>plaintext</EM> <EM><TT>&key</TT></EM> <EM>ciphertext-start</EM> <EM>ciphertext-end</EM> <EM>plaintext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Decrypts data according to <EM>cipher</EM> from <EM>ciphertext</EM>
+starting at <EM>ciphertext-start</EM> and continuing until <EM>ciphertext-end</EM>. The decrypted data is placed in <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="encrypt-in-place"></A><TT><STRONG>encrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /><A NAME="decrypt-in-place"></A><TT><STRONG>decrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts or decrypts data in <EM>text</EM> between <EM>start</EM> and <EM>end</EM> "in-place" according to <EM>cipher</EM>. These functions are
+shorthand for:</P><PRE>(encrypt cipher text text :plaintext-start start :plaintext-end end :ciphertext-start start)
+(decrypt cipher text text :ciphertext-start start :ciphertext-end end :plaintext-start start)</PRE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> and <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A> do not support a <EM>handle-final-block</EM> parameter as <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> do.
+If you need the functionality that <EM>handle-final-block</EM> provides,
+then you need to use <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>n-bytes-consumed</EM> and <EM>n-bytes-produced</EM> may not always be
+equal to the length of the data specified in the call to <A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> or <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A>. This subtlely is also
+present in <A HREF="#encrypt" STYLE="symbol">encrypt</A> or <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-ciphers"></A><TT><STRONG>list-all-ciphers</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list of cipher-names that may be validly passed to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P><DIV CLASS="lisp-symbol"><A NAME="cipher-supported-p"></A><TT><STRONG>cipher-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="key-lengths"></A><TT><STRONG>key-lengths</STRONG> <EM>cipher</EM> =&gt; <EM>list</EM></TT><BR /></DIV><P>Return a list of valid key lengths for <EM>cipher</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="block-length"></A><TT><STRONG>block-length</STRONG> <EM>cipher</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Return the number of octets <EM>cipher</EM> processes at a time. This
+function always returns 1 for stream ciphers.</P><H2>Digests</H2><P>Digest functions, also known as hash functions, produce
+fixed-length output (a <EM>digest</EM> or <EM>hash</EM>) from a
+variable-length message. The simplest example of a digest function is
+one that adds up all the bytes in the message modulo 256. This digest
+function fails one test of a cryptographically secure hash function: it
+must be difficult to find a message with a given digest. It also fails
+the other test: it must be difficult to find two messages with the same
+digest.</P><P>Ironclad provides several cryptographically secure digest functions
+and several non-cryptographically secure digest functions.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">In the functions below, messages or parts thereof are provided
+as octet vectors; Ironclad has no facilities for producing digests of
+strings. If you need to obtain the digest of a string, then you need to
+figure out how to convert it to an octet vector first. This is a
+deliberate design decision. Characters are not equivalent to bytes.
+See your local Unicode guru for more details.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="make-digest"></A><TT><STRONG>make-digest</STRONG> <EM>digest-name</EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Returns a digest object. <EM>digest-name</EM> is a keyword naming the
+algorithm you wish <EM>digester</EM> to use. The algorithms you are likely
+to want to use are:</P><UL><LI>MD4</LI><LI>MD5</LI><LI>SHA1</LI><LI>SHA256</LI><LI>Tiger</LI><LI>Adler32</LI><LI>CRC32</LI></UL><P>Other legitimate digest names can be found by calling <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>. Like <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>, <EM>digest-name</EM> should be
+a symbol in the <TT>KEYWORD</TT> package.</P><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>thing</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>(values)</EM></TT><BR /></DIV><P>Updates the internal state of <EM>digester</EM> with the contents of <EM>thing</EM>. The exact method is determined by the type of THING.</P><P>There are several methods defined on this generic function that
+take a particular digester and a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT> as well as the usual <EM>start</EM> and <EM>end</EM> keyword
+arguments. These methods update the state of <EM>digester</EM> with the
+subsequence of the array denoted by <EM>start</EM> and <EM>end</EM>. They are
+note listed here because there's one method for every type of digest
+that Ironclad provides, and listing them would get very tedious
+for no benefit. An example should suffice.</P><PRE>(let ((digester (ironclad:make-digest :sha1))
+ (array (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)))
+ ;; Update with 16 zeroes.
+ (ironclad:update-digest digester array)
+ ;; Update with 8 ones.
+ (fill array 1 :start 2 :end 10)
+ (ironclad:update-digest digester array :start 2 :end 10))</PRE><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>(stream stream)</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Update the internal state of <EM>digester</EM> with the contents of <EM>stream</EM>, which must respond to <TT>READ-BYTE</TT> or <TT>READ-SEQUENCE</TT>
+with a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT> and return <EM>digester</EM>. This method is implemented on top of the previous method
+for sequences It differs from <A HREF="#digest-stream" STYLE="symbol">digest-stream</A>, below, in that you
+may need to digest data before or after the contents of <EM>stream</EM>
+(this happens, for instance, when signing the contents of some file).</P><DIV CLASS="lisp-symbol"><A NAME="produce-digest"></A><TT><STRONG>produce-digest</STRONG> <EM>digester</EM> <EM><TT>&key</TT></EM> <EM>digest-start</EM> <EM>digest</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Return the digest of the data processed by <EM>digester</EM> so far.
+The internal state of <EM>digester</EM> is not modified; this feature makes
+it possible to compute a "rolling digest" of a document.</P><P>If <EM>digest</EM> is provided, the computed digest will be placed
+into <EM>digest</EM> starting at <EM>digest-start</EM>. <EM>digest</EM> must be
+a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
+insufficient space in <EM>digest</EM>.</P><H3>High-level convenience functions</H3><P>Several high-level convenience functions that encapsulate common
+sequences of <A HREF="#make-digest" STYLE="symbol">make-digest</A>, <A HREF="#update-digest" STYLE="symbol">update-digest</A> and <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> are provided by Ironclad as well.</P><DIV CLASS="lisp-symbol"><A NAME="digest-sequence"></A><TT><STRONG>digest-sequence</STRONG> <EM>digest-name</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the subsequence of <EM>sequence</EM> bounded by
+<EM>start</EM> and <EM>end</EM>, according to <EM>digest-name</EM>. <EM>sequence</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-stream"></A><TT><STRONG>digest-stream</STRONG> <EM>digest-name</EM> <EM>stream</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the stream specified by <EM>stream</EM>. <TT>READ-BYTE</TT> must be a legal operation on <EM>stream</EM>
+and return an <TT>(UNSIGNED-BYTE 8)</TT>. In a similar fashion, <TT>READ-SEQUENCE</TT> on <EM>stream</EM> must support reading into a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-file"></A><TT><STRONG>digest-file</STRONG> <EM>digest-name</EM> <EM>pathname</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the file named by <EM>pathname</EM>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-digests"></A><TT><STRONG>list-all-digests</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list whose elements may be validly passed to <A HREF="#make-digest" STYLE="symbol">make-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-supported-p"></A><TT><STRONG>digest-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="digest-length"></A><TT><STRONG>digest-length</STRONG> <EM>digest</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Returns the length of the digest computed by <EM>digest</EM>, which
+may be a digest-name or a digest instance.</P><H2>Message authentication codes</H2><P>A message authentication code is a cryptographic function of some
+data and a user-specified key. Only a person knowing the key can
+recompute the MAC for the given message. A MAC is useful where
+maintaining data integrity is required, but the secrecy of the data is
+not paramount.</P><P>Ironclad provides two different kinds of MACs: HMACs, specified in
+<A HREF="http://www.ietf.org/rfc/rfc2109.txt">RFC 2104</A>, and CMACs,
+specified in <A HREF="http://www.ietf.org/rfc/rfc4493.txt">RFC 4493</A>
+and NIST document 800-38B.</P><H3>HMACs</H3><P>Instances of HMACs are constructed by specifying a secret key and a
+digest-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-hmac"></A><TT><STRONG>make-hmac</STRONG> <EM>key</EM> <EM>digest-name</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Return an HMAC instance based on the hash function <EM>digest-name</EM> with secret key <EM>key</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-hmac"></A><TT><STRONG>update-hmac</STRONG> <EM>hmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>hmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="hmac-digest"></A><TT><STRONG>hmac-digest</STRONG> <EM>hmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>hmac</EM> thus far.
+The internal state of <EM>hmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#digest-length" STYLE="symbol">digest-length</A> of <EM>digest-name</EM>
+passed to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A> when <EM>hmac</EM> was constructed.</P><H3>CMACs</H3><P>Instances of CMACs are constructed by specifying a secret key and a
+cipher-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-cmac"></A><TT><STRONG>make-cmac</STRONG> <EM>key</EM> <EM>cipher-name</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Return a CMAC instance based on the cipher <EM>cipher-name</EM> with
+secret key <EM>key</EM>. <EM>cipher-name</EM> must have a <A HREF="#block-length" STYLE="symbol">block-length</A>
+of either 8 or 16; this restriction is satisfied by most ciphers in
+Ironclad with the notable exception of stream ciphers. <EM>key</EM> must
+be an acceptable key for <EM>cipher-name</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-cmac"></A><TT><STRONG>update-cmac</STRONG> <EM>cmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>cmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="cmac-digest"></A><TT><STRONG>cmac-digest</STRONG> <EM>cmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>cmac</EM> thus far.
+The internal state of <EM>cmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>cipher-name</EM>
+passed to <A HREF="#make-cmac" STYLE="symbol">make-cmac</A> when <EM>cmac</EM> was constructed.</P><H2>Public-key Operations</H2><P>Ironclad includes support for DSA signing and verification.
+Support for RSA encryption and decryption is provided as well, but it is
+"raw"--the various formatting schemes (e.g. PKCS-1) must be implemented
+by the user at this time.</P><H3>Key construction</H3><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>public-key</EM></TT><BR /></DIV><P>Return a public key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA public key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, and <EM>y</EM>
+are the usual parameters for DSA keys discussed in the literature.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a private key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM>x</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA private key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, <EM>y</EM>, and
+<EM>x</EM> are the usual parameters for DSA keys discussed in the
+literature.</P><H3>Digital signatures</H3><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Return a signature of <EM>message</EM> between <EM>start</EM> and <EM>end</EM> signed with <EM>key</EM>; the class of <EM>key</EM> determines the class of
+<EM>signature</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>(key dsa-private-key)</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>This method places an additional constraint on the size of <EM>message</EM> specified by <EM>start</EM> and <EM>end</EM>: it must be exactly
+20 bytes long (the length of a SHA-1 digest). <EM>signature</EM> is a <A HREF="#dsa-signature" STYLE="symbol">dsa-signature</A> object.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>key</EM> <EM>message</EM> <EM>signature</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Verify whether <EM>signature</EM> is the signature of <EM>message</EM>
+between <EM>start</EM> and <EM>end</EM> using <EM>key</EM>. Return T or NIL
+depending on the result of verification.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>(key dsa-public-key)</EM> <EM>message</EM> <EM>(signature dsa-signature)</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><H4>Signature objects</H4><P>There is no one "right" way to format signatures into octet
+vectors; different applications may have different requirements. <A HREF="#sign-message" STYLE="symbol">sign-message</A> therefore returns objects and lets the user determine
+how to best format the values contained therein.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature"></A><TT><STRONG>dsa-signature</STRONG></TT><BR /></DIV><P>A DSA signature object.</P><DIV CLASS="lisp-symbol"><A NAME="make-dsa-signature"></A><TT><STRONG>make-dsa-signature</STRONG> <EM>r</EM> <EM>s</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Returns a DSA signature with the provided <EM>r</EM> and <EM>s</EM>
+values. <EM>r</EM> and <EM>s</EM> may be either integers or they may be
+20-byte octet vectors.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-r"></A><TT><STRONG>dsa-signature-r</STRONG> <EM>dsa-signature</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>r</EM> value of the provided DSA signature.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-s"></A><TT><STRONG>dsa-signature-s</STRONG> <EM>dsa-signature</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>s</EM> value of the provided DSA signature.</P><H3>Encryption and decryption</H3><DIV CLASS="lisp-symbol"><A NAME="encrypt-message"></A><TT><STRONG>encrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>encrypted-message</EM></TT><BR /></DIV><DIV CLASS="lisp-symbol"><A NAME="decrypt-message"></A><TT><STRONG>decrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>decrypted-message</EM></TT><BR /></DIV><H2>Gray Streams</H2><P>Ironclad includes support for several convenient stream
+abstractions based on Gray streams. Gray streams support in Ironclad is
+included for SBCL, CMUCL, OpenMCL, and Allegro.</P><H3>Octet streams</H3><P>Octet streams are very similar to Common Lisp's <A HREF="#string-stream" STYLE="symbol">string-stream</A>,
+except they deal in octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-input-stream"></A><TT><STRONG>make-octet-input-stream</STRONG> <EM>buffer</EM> <EM><TT>&optional</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>octet-input-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-input-stream" STYLE="symbol">make-string-input-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-output-stream"></A><TT><STRONG>make-octet-output-stream</STRONG> =&gt; <EM>octet-output-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-output-stream" STYLE="symbol">make-string-output-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="get-output-stream-octets"></A><TT><STRONG>get-output-stream-octets</STRONG> <EM>stream</EM> =&gt; <EM>octet-vector</EM></TT><BR /></DIV><P>As <A HREF="#get-output-stream-string" STYLE="symbol">get-output-stream-string</A>, only with an octet output-steam
+instead of a string output-stream.</P><H3>Digest streams</H3><P>Digest streams compute a digest of the data written to them
+according to a specific digest algorithm.</P><P>Example:</P><PRE>(defun frobbing-function (stream)
+ ;; We want to compute a digest of the data being written to STREAM
+ ;; without involving our callees in the process.
+ (let* ((digesting-stream (crypto:make-digesting-stream :sha1))
+ (stream (make-broadcast-stream stream digesting-stream)))
+ ;; Feed data to STREAM.
+ (frob-guts stream)
+ ;; Do something with the digest computed.
+ (... (crypto:produce-digest digesting-stream) ...)
+ ...))</PRE><DIV CLASS="lisp-symbol"><A NAME="make-digesting-stream"></A><TT><STRONG>make-digesting-stream</STRONG> <EM>digest</EM> =&gt; <EM>stream</EM></TT><BR /></DIV><P>Make a stream that computes a digest of the data written to it
+according to the algorithm <EM>digest-name</EM>. <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> may
+be used to obtain a digest of all the data written to the stream.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">Calling <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> on a digest stream does not alter
+the internal state of the digest.</TD></TR></TABLE><H2>Utility Functions</H2><DIV CLASS="lisp-symbol"><A NAME="ub16ref/le"></A><TT><STRONG>ub16ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/le"></A><TT><STRONG>ub32ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/le"></A><TT><STRONG>ub64ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>This family of functions accesses an unsigned 16-bit, 32-bit or
+64-bit value stored in little-endian order starting at <EM>index</EM> in <EM>array</EM>. <EM>array</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT>. These functions are SETFable.</P><DIV CLASS="lisp-symbol"><A NAME="ub16ref/be"></A><TT><STRONG>ub16ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/be"></A><TT><STRONG>ub32ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/be"></A><TT><STRONG>ub64ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>As the above, only the value is stored in big-endian order.</P><DIV CLASS="lisp-symbol"><A NAME="byte-array-to-hex-string"></A><TT><STRONG>byte-array-to-hex-string</STRONG> <EM>vector</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>element-type</EM> =&gt; <EM>string</EM></TT><BR /><A NAME="ascii-string-to-byte-array"></A><TT><STRONG>ascii-string-to-byte-array</STRONG> <EM>string</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>byte-array-to-hex-string</TT> converts the bytes of <EM>vector</EM>
+between <EM>start</EM> and <EM>end</EM> into a hexadecimal string. It is
+useful for converting digests to a more readable form. <EM>element-type</EM> indicates the element-type of the returned string.</P><P><TT>ascii-string-to-byte-array</TT> is provided as a quick and dirty way
+to convert a string to a byte array suitable for feeding to <A HREF="#update-digest" STYLE="symbol">update-digest</A> or <A HREF="#encrypt" STYLE="symbol">encrypt</A>. Care should be taken to ensure that
+the provided string is actually an ASCII string. <EM>start</EM> and <EM>end</EM> have their usual interpretations.</P><DIV CLASS="lisp-symbol"><A NAME="octets-to-integer"></A><TT><STRONG>octets-to-integer</STRONG> <EM>octet-vec</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>big-endian</EM> <EM>n-bits</EM> =&gt; <EM>number</EM></TT><BR /><A NAME="integer-to-octets"></A><TT><STRONG>integer-to-octets</STRONG> <EM>bignum</EM> <EM><TT>&key</TT></EM> <EM>n-bits</EM> <EM>big-endian</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>octets-to-integer</TT> converts the bytes of <EM>octet-vec</EM> between
+<EM>start</EM> and <EM>end</EM> to an integer as though the bytes denoted a
+number in base 256. <EM>big-endian</EM> is a boolean indicating whether
+the bytes are to be read in big-endian or little-endian order. <EM>n-bits</EM> specifies how many bits should be considered as significant
+in the resulting number.</P><P><TT>integer-to-octets</TT> is the reverse operation.</P><DIV CLASS="lisp-symbol"><A NAME="expt-mod"></A><TT><STRONG>expt-mod</STRONG> <EM>n</EM> <EM>exponent</EM> <EM>modulus</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Raises <EM>n</EM> to the <EM>exponent</EM> power modulo <EM>modulus</EM> in
+a more efficient fashion than <TT>(MOD (EXPT N EXPONENT) MODULUS)</TT>.</P><H2>Conditions</H2><DIV CLASS="lisp-symbol"><A NAME="ironclad-error"></A><TT><STRONG>ironclad-error</STRONG></TT><BR /></DIV><P>All errors signaled by Ironclad are of this type. This type is a
+direct subtype of <TT>SIMPLE-ERROR</TT> without any extra slots or
+options.</P><DIV CLASS="lisp-symbol"><A NAME="initialization-vector-not-supplied"></A><TT><STRONG>initialization-vector-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled by <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> when an initialization
+vector is not provided and the requested mode requires an initialization
+vector.</P><DIV CLASS="lisp-symbol"><A NAME="invalid-initialization-vector"></A><TT><STRONG>invalid-initialization-vector</STRONG></TT><BR /></DIV><P>This error is signaled when an invalid initialization vector is
+supplied to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> (e.g. when the length of the initialization
+vector does not match the block length of the cipher).</P><DIV CLASS="lisp-symbol"><A NAME="invalid-key-length"></A><TT><STRONG>invalid-key-length</STRONG></TT><BR /></DIV><P>This error is signaled when the key provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is
+not of an acceptable length for the requested cipher.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-cipher"></A><TT><STRONG>unsupported-cipher</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>cipher-name</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#cipher-supported-p" STYLE="symbol">cipher-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-mode"></A><TT><STRONG>unsupported-mode</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>mode</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#mode-supported-p" STYLE="symbol">mode-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-digest"></A><TT><STRONG>unsupported-digest</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>digest-name</EM> provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A> is not <A HREF="#digest-supported-p" STYLE="symbol">digest-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="insufficient-buffer-space"></A><TT><STRONG>insufficient-buffer-space</STRONG></TT><BR /></DIV><P>This error is signaled when Ironclad needs to stuff some data into a
+buffer (e.g. when the user provides <EM>digest</EM> to <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>) and
+there is insufficient space.</P><DIV CLASS="lisp-symbol"><A NAME="key-not-supplied"></A><TT><STRONG>key-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled when a <TT>:KEY</TT> argument is not provided
+to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P></BODY></HTML> \ No newline at end of file
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..807db3d
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<HTML><HEAD><TITLE>Ironclad</TITLE><LINK TYPE="text/css" TITLE="default" REL="stylesheet" MEDIA="screen" HREF="style.css" /></HEAD><BODY><H1>Ironclad</H1><P>Ironclad is a cryptography library written entirely in Common
+Lisp. It includes support for several popular <A HREF="#ciphers">ciphers</A>, <A HREF="#digests">digests</A>, and <A HREF="#macs">MACs</A>. Rudimentary support for <A HREF="#public-key">public-key
+cryptography</A> is included. For several implementations that support
+Gray Streams, <A HREF="#gray-streams">support</A> is included for
+convenient stream wrappers.</P><P>Ironclad was written primarily by Nathan Froyd (froydnj@gmail.com).</P><H2>Installation</H2><P>Ironclad can be downloaded at <A HREF="http://www.method-combination.net/lisp/files/ironclad.tar.gz">http://www.method-combination.net/lisp/files/ironclad.tar.gz</A>.
+The latest version is 0.27.</P><P>It comes with an ASDF system definition, so <TT>(ASDF:OOS
+'ASDF:LOAD-OP :IRONCLAD)</TT> should be all that you need to get started.
+The testsuite can be run by substituting <TT>ASDF:TEST-OP</TT> for <TT>ASDF:LOAD-OP</TT> in the form above.</P><P>Ironclad has been tested in the following implementations:</P><UL><LI>SBCL x86/linux (primary development platform)</LI><LI>SBCL x86-64/solaris</LI><LI>CMUCL x86/linux</LI><LI>ABCL with Sun's 1.5.0 JVM</LI><LI>Lispworks 5.0.1 x86/linux</LI><LI>Allegro 8.0 x86/linux</LI><LI>Allegro 8.1 x86/linux</LI><LI>Allegro 8.1 x86-64/linux</LI><LI>Allegro 8.1 sparc/solaris</LI><LI>CLISP 2.41 x86/linux</LI><LI>CLISP 2.44 x86/cygwin</LI><LI>Clozure Common Lisp 1.2 x86-64/Linux</LI></UL><P>All included tests should pass successfully. If you use a platform
+not listed above, please send your platform information to the author so
+that he can add it to the above list. If the tests do not all pass, you
+have found a bug; please report it.</P><H2>License</H2><P>Ironclad is released under a MIT-like license; you can do pretty
+much anything you want to with the code except claim that you wrote
+it.</P><H2 ID="ciphers">Ciphers</H2><DIV CLASS="lisp-symbol"><A NAME="make-cipher"></A><TT><STRONG>make-cipher</STRONG> <EM>name</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM>mode</EM> <EM>initialization-vector</EM> <EM>padding</EM> =&gt; <EM>cipher</EM></TT><BR /></DIV><P>Return a cipher object suitable for use for both encryption and
+decryption.</P><P><EM>name</EM> denotes the encryption algorithm to use. <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A> will tell you the names of all supported ciphers;
+the short list of ones you are likely to be interested in is:</P><UL><LI>AES</LI><LI>DES</LI><LI>3DES</LI><LI>Blowfish</LI><LI>Twofish</LI><LI>RC5</LI><LI>RC6</LI><LI>Arcfour (RC4)</LI></UL><P><EM>name</EM> can be a symbol in the <TT>KEYWORD</TT> package or the <TT>IRONCLAD</TT> package; <TT>:AES</TT> for AES, <TT>IRONCLAD:ARCFOUR</TT> for
+RC4, and so forth.</P><P><EM>mode</EM> describes the mode of operation for the cipher. Stream
+ciphers such as Arcfour can operate in only one mode, <TT>stream</TT>.
+Block ciphers such as AES and DES can operate in several different
+modes:</P><UL><LI>ECB</LI><LI>CBC</LI><LI>OFB</LI><LI>CFB (note that Ironclad's CFB mode is 'n'-bit CFB, where 'n' is
+the <A HREF="#block-length" STYLE="symbol">block-length</A> of the cipher)</LI><LI>CFB8 (this seems to be the mode other crypto packages call
+'CFB')</LI><LI>CTR</LI></UL><P><EM>mode</EM> should be a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT>
+packages; <TT>:STREAM</TT>, <TT>IRONCLAD:OFB</TT>, and so forth. An error
+will be signaled if <EM>mode</EM> is not appropriate for the cipher <EM>name</EM>.</P><P><EM>initialization-vector</EM> (IV) should be supplied only if <EM>mode</EM>
+requires one. <EM>initialization-vector</EM> should be a <TT>(VECTOR
+(UNSIGNED-BYTE 8))</TT>. The supplied IV should be the same length as the
+<A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>name</EM>.</P><P><EM>key</EM> is, of course, the key for the cipher. <EM>key</EM> should be
+a <TT>(VECTOR (UNSIGNED-BYTE 8))</TT>.</P><P>If <EM>padding</EM> is supplied, the specified padding method will be
+used by <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> to handle short blocks when the <TT>:HANDLE-FINAL-BLOCK</TT> argument is supplied. Depending on the mode
+specified, <EM>padding</EM> may be ignored (e.g. OFB and CFB modes do not
+care about short blocks; neither do stream ciphers).</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>padding</EM> is currently ignored in all modes (and, by extension,
+so is <TT>:HANDLE-FINAL-BLOCK</TT>). This oversight is expected to be
+corrected in a future release.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="encrypt"></A><TT><STRONG>encrypt</STRONG> <EM>cipher</EM> <EM>plaintext</EM> <EM>ciphertext</EM> <EM><TT>&key</TT></EM> <EM>plaintext-start</EM> <EM>plaintext-end</EM> <EM>ciphertext-start</EM> <EM>plaintext-start</EM> <EM>ciphertext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts data according to <EM>cipher</EM> from <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM> and continuing until <EM>plaintext-end</EM>. The encrypted data is placed in <EM>ciphertext</EM> starting at <EM>ciphertext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="decrypt"></A><TT><STRONG>decrypt</STRONG> <EM>cipher</EM> <EM>ciphertext</EM> <EM>plaintext</EM> <EM><TT>&key</TT></EM> <EM>ciphertext-start</EM> <EM>ciphertext-end</EM> <EM>plaintext-start</EM> <EM>ciphertext-start</EM> <EM>plaintext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Decrypts data according to <EM>cipher</EM> from <EM>ciphertext</EM>
+starting at <EM>ciphertext-start</EM> and continuing until <EM>ciphertext-end</EM>. The decrypted data is placed in <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="encrypt-in-place"></A><TT><STRONG>encrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /><A NAME="decrypt-in-place"></A><TT><STRONG>decrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts or decrypts data in <EM>text</EM> between <EM>start</EM> and <EM>end</EM> "in-place" according to <EM>cipher</EM>. These functions are
+shorthand for:</P><PRE>(encrypt cipher text text :plaintext-start start :plaintext-end end :ciphertext-start start)
+(decrypt cipher text text :ciphertext-start start :ciphertext-end end :plaintext-start start)</PRE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> and <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A> do not support a <EM>handle-final-block</EM> parameter as <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> do.
+If you need the functionality that <EM>handle-final-block</EM> provides,
+then you need to use <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>n-bytes-consumed</EM> and <EM>n-bytes-produced</EM> may not always be
+equal to the length of the data specified in the call to <A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> or <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A>. This subtlely is also
+present in <A HREF="#encrypt" STYLE="symbol">encrypt</A> or <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-ciphers"></A><TT><STRONG>list-all-ciphers</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list of cipher-names that may be validly passed to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P><DIV CLASS="lisp-symbol"><A NAME="cipher-supported-p"></A><TT><STRONG>cipher-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="key-lengths"></A><TT><STRONG>key-lengths</STRONG> <EM>cipher</EM> =&gt; <EM>list</EM></TT><BR /></DIV><P>Return a list of valid key lengths for <EM>cipher</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="block-length"></A><TT><STRONG>block-length</STRONG> <EM>cipher</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Return the number of octets <EM>cipher</EM> processes at a time. This
+function always returns 1 for stream ciphers.</P><H2 ID="digests">Digests</H2><P>Digest functions, also known as hash functions, produce
+fixed-length output (a <EM>digest</EM> or <EM>hash</EM>) from a
+variable-length message. The simplest example of a digest function is
+one that adds up all the bytes in the message modulo 256. This digest
+function fails one test of a cryptographically secure hash function: it
+must be difficult to find a message with a given digest. It also fails
+the other test: it must be difficult to find two messages with the same
+digest.</P><P>Ironclad provides several cryptographically secure digest functions
+and several non-cryptographically secure digest functions.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">In the functions below, messages or parts thereof are provided
+as octet vectors; Ironclad has no facilities for producing digests of
+strings. If you need to obtain the digest of a string, then you need to
+figure out how to convert it to an octet vector first. This is a
+deliberate design decision. Characters are not equivalent to bytes.
+See your local Unicode guru for more details.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="make-digest"></A><TT><STRONG>make-digest</STRONG> <EM>digest-name</EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Returns a digest object. <EM>digest-name</EM> is a keyword naming the
+algorithm you wish <EM>digester</EM> to use. The algorithms you are likely
+to want to use are:</P><UL><LI>MD4</LI><LI>MD5</LI><LI>SHA1</LI><LI>SHA256</LI><LI>Tiger</LI><LI>Adler32</LI><LI>CRC32</LI></UL><P>Other legitimate digest names can be found by calling <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>. Like <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>, <EM>digest-name</EM> should be
+a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT> packages.</P><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>thing</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>(values)</EM></TT><BR /></DIV><P>Updates the internal state of <EM>digester</EM> with the contents of <EM>thing</EM>. The exact method is determined by the type of THING.</P><P>There are several methods defined on this generic function that
+take a particular digester and a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT> as well as the usual <EM>start</EM> and <EM>end</EM> keyword
+arguments. These methods update the state of <EM>digester</EM> with the
+subsequence of the array denoted by <EM>start</EM> and <EM>end</EM>. They are
+not listed here because there's one method for every type of digest
+that Ironclad provides, and listing them would get very tedious
+for no benefit. An example should suffice.</P><PRE>(let ((digester (ironclad:make-digest :sha1))
+ (array (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)))
+ ;; Update with 16 zeroes.
+ (ironclad:update-digest digester array)
+ ;; Update with 8 ones.
+ (fill array 1 :start 2 :end 10)
+ (ironclad:update-digest digester array :start 2 :end 10))</PRE><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>(stream stream)</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>(start 0)</EM> <EM>end</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Update the internal state of <EM>digester</EM> with the contents of <EM>stream</EM>, which must respond to <TT>READ-BYTE</TT> or <TT>READ-SEQUENCE</TT>
+with a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT> and return <EM>digester</EM>. It differs from <A HREF="#digest-stream" STYLE="symbol">digest-stream</A>, below, in that you
+may need to digest data before or after the contents of <EM>stream</EM>
+(this happens, for instance, when signing the contents of some file).</P><DIV CLASS="lisp-symbol"><A NAME="produce-digest"></A><TT><STRONG>produce-digest</STRONG> <EM>digester</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Return the digest of the data processed by <EM>digester</EM> so far.
+The internal state of <EM>digester</EM> is modified; if you wish to retain
+a copy of the digest, you must call <A HREF="#copy-digest" STYLE="symbol">copy-digest</A>.</P><P>If <EM>digest</EM> is provided, the computed digest will be placed
+into <EM>digest</EM> starting at <EM>digest-start</EM>. <EM>digest</EM> must be
+a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
+insufficient space in <EM>digest</EM>.</P><H3>High-level convenience functions</H3><P>Several high-level convenience functions that encapsulate common
+sequences of <A HREF="#make-digest" STYLE="symbol">make-digest</A>, <A HREF="#update-digest" STYLE="symbol">update-digest</A> and <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> are provided by Ironclad as well. They come in two flavors: the first
+takes a digest name as would be provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A>. The
+second way to call these functions is to provide an actual digest object
+as the first argument. So one can say:</P><PRE>(ironclad:digest-sequence :md5 *buffer*)</PRE><P>or, equivalently:</P><PRE>(let ((digester (make-digest :md5)))
+ (ironclad:digest-sequence digester *buffer*))</PRE><P>The second form comes in handy if you plan on <A HREF="#digest-tips">reusing the digest object</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-sequence"></A><TT><STRONG>digest-sequence</STRONG> <EM>digest-spec</EM> <EM>sequence</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the subsequence of <EM>sequence</EM> bounded by
+<EM>start</EM> and <EM>end</EM>, according to <EM>digest-name</EM>. <EM>sequence</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-stream"></A><TT><STRONG>digest-stream</STRONG> <EM>digest-spec</EM> <EM>stream</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the stream specified by <EM>stream</EM>. <TT>READ-BYTE</TT> must be a legal operation on <EM>stream</EM>
+and return an <TT>(UNSIGNED-BYTE 8)</TT>. In a similar fashion, <TT>READ-SEQUENCE</TT> on <EM>stream</EM> must support reading into a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><P>If <EM>buffer</EM> is provided, it must be a <TT>(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))</TT>; the portion of <EM>buffer</EM> between <EM>start</EM> and <EM>end</EM> will be used to read the data from the stream.</P><DIV CLASS="lisp-symbol"><A NAME="digest-file"></A><TT><STRONG>digest-file</STRONG> <EM>digest-spec</EM> <EM>pathname</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the file named by <EM>pathname</EM>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><P>If <EM>buffer</EM> is provided, it must be a <TT>(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))</TT>; the portion of <EM>buffer</EM> between <EM>start</EM> and <EM>end</EM> will be used to read the data from the stream.</P><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-digests"></A><TT><STRONG>list-all-digests</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list whose elements may be validly passed to <A HREF="#make-digest" STYLE="symbol">make-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-supported-p"></A><TT><STRONG>digest-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="digest-length"></A><TT><STRONG>digest-length</STRONG> <EM>digest</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Returns the length of the digest computed by <EM>digest</EM>, which
+may be a digest-name or a digest instance.</P><H3 ID="digest-tips">Miscellaneous</H3><P>Ironclad digests are CLOS objects; the interesting thing about this
+for most purposes is that functions like <TT>REINITIALIZE-INSTANCE</TT> are
+supported. This means one can write a fairly efficient clone of the <TT>md5sum</TT> program like so:</P><PRE>(defun digest-sum-files (digest &rest files)
+ (unless files
+ (error "no files given to digest"))
+ (loop with buffer = (make-array 8192 :element-type '(unsigned-byte 8))
+ with digest = (make-array (ironclad:digest-length digest)
+ :element-type '(unsigned-byte 8))
+ for file in files
+ for digester = (ironclad:make-digest digest)
+ then (reinitialize-instance digester)
+ do (ironclad:digest-file digester file :buffer buffer :digest digest)
+ (format t "~A ~A~%" (file-namestring file)
+ (ironclad:byte-array-to-hex-string digest))))</PRE><H2 ID="macs">Message authentication codes</H2><P>A message authentication code is a cryptographic function of some
+data and a user-specified key. Only a person knowing the key can
+recompute the MAC for the given message. A MAC is useful where
+maintaining data integrity is required, but the secrecy of the data is
+not paramount.</P><P>Ironclad provides two different kinds of MACs: HMACs, specified in
+<A HREF="http://www.ietf.org/rfc/rfc2109.txt">RFC 2104</A>, and CMACs,
+specified in <A HREF="http://www.ietf.org/rfc/rfc4493.txt">RFC 4493</A>
+and NIST document 800-38B.</P><H3>HMACs</H3><P>Instances of HMACs are constructed by specifying a secret key and a
+digest-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-hmac"></A><TT><STRONG>make-hmac</STRONG> <EM>key</EM> <EM>digest-name</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Return an HMAC instance based on the hash function <EM>digest-name</EM> with secret key <EM>key</EM>.</P><P>The returned object supports <TT>REINITIALIZE-INSTANCE</TT>:</P><DIV CLASS="lisp-symbol"><A NAME="reinitialize-instance"></A><TT><STRONG>reinitialize-instance</STRONG> <EM>(mac hmac)</EM> <EM><TT>&rest</TT></EM> <EM>initargs</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>The <TT>:KEY</TT> argument is the secret key, as provided to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A>.</P><DIV CLASS="lisp-symbol"><A NAME="update-hmac"></A><TT><STRONG>update-hmac</STRONG> <EM>hmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>hmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="hmac-digest"></A><TT><STRONG>hmac-digest</STRONG> <EM>hmac</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>buffer-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>hmac</EM> thus far.
+The internal state of <EM>hmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#digest-length" STYLE="symbol">digest-length</A> of <EM>digest-name</EM>
+passed to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A> when <EM>hmac</EM> was constructed.</P><P>If <EM>buffer</EM> is provided, the computed MAC will be placed into <EM>buffer</EM> starting at <EM>buffer-start</EM>. <EM>buffer</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
+insufficient space in <EM>buffer</EM>.</P><H3>CMACs</H3><P>Instances of CMACs are constructed by specifying a secret key and a
+cipher-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-cmac"></A><TT><STRONG>make-cmac</STRONG> <EM>key</EM> <EM>cipher-name</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Return a CMAC instance based on the cipher <EM>cipher-name</EM> with
+secret key <EM>key</EM>. <EM>cipher-name</EM> must have a <A HREF="#block-length" STYLE="symbol">block-length</A>
+of either 8 or 16; this restriction is satisfied by most ciphers in
+Ironclad with the notable exception of stream ciphers. <EM>key</EM> must
+be an acceptable key for <EM>cipher-name</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-cmac"></A><TT><STRONG>update-cmac</STRONG> <EM>cmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>cmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="cmac-digest"></A><TT><STRONG>cmac-digest</STRONG> <EM>cmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>cmac</EM> thus far.
+The internal state of <EM>cmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>cipher-name</EM>
+passed to <A HREF="#make-cmac" STYLE="symbol">make-cmac</A> when <EM>cmac</EM> was constructed.</P><H2 ID="public-key">Public-key Operations</H2><P>Ironclad includes support for DSA signing and verification.
+Support for RSA encryption and decryption is provided as well, but it is
+"raw"--the various formatting schemes (e.g. PKCS-1) must be implemented
+by the user at this time.</P><H3>Key construction</H3><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>public-key</EM></TT><BR /></DIV><P>Return a public key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA public key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, and <EM>y</EM>
+are the usual parameters for DSA keys discussed in the literature.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a private key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM>x</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA private key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, <EM>y</EM>, and
+<EM>x</EM> are the usual parameters for DSA keys discussed in the
+literature.</P><H3>Digital signatures</H3><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Return a signature of <EM>message</EM> between <EM>start</EM> and <EM>end</EM> signed with <EM>key</EM>; the class of <EM>key</EM> determines the class of
+<EM>signature</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>(key dsa-private-key)</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>This method places an additional constraint on the size of <EM>message</EM> specified by <EM>start</EM> and <EM>end</EM>: it must be exactly
+20 bytes long (the length of a SHA-1 digest). <EM>signature</EM> is a <A HREF="#dsa-signature" STYLE="symbol">dsa-signature</A> object.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>key</EM> <EM>message</EM> <EM>signature</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Verify whether <EM>signature</EM> is the signature of <EM>message</EM>
+between <EM>start</EM> and <EM>end</EM> using <EM>key</EM>. Return T or NIL
+depending on the result of verification.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>(key dsa-public-key)</EM> <EM>message</EM> <EM>(signature dsa-signature)</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><H4>Signature objects</H4><P>There is no one "right" way to format signatures into octet
+vectors; different applications may have different requirements. <A HREF="#sign-message" STYLE="symbol">sign-message</A> therefore returns objects and lets the user determine
+how to best format the values contained therein.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature"></A><TT><STRONG>dsa-signature</STRONG></TT><BR /></DIV><P>A DSA signature object.</P><DIV CLASS="lisp-symbol"><A NAME="make-dsa-signature"></A><TT><STRONG>make-dsa-signature</STRONG> <EM>r</EM> <EM>s</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Returns a DSA signature with the provided <EM>r</EM> and <EM>s</EM>
+values. <EM>r</EM> and <EM>s</EM> may be either integers or they may be
+20-byte octet vectors.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-r"></A><TT><STRONG>dsa-signature-r</STRONG> <EM>object</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>r</EM> value of the provided DSA signature.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-s"></A><TT><STRONG>dsa-signature-s</STRONG> <EM>object</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>s</EM> value of the provided DSA signature.</P><H3>Encryption and decryption</H3><DIV CLASS="lisp-symbol"><A NAME="encrypt-message"></A><TT><STRONG>encrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>end</EM> <EM>start</EM> =&gt; <EM>encrypted-message</EM></TT><BR /></DIV><DIV CLASS="lisp-symbol"><A NAME="decrypt-message"></A><TT><STRONG>decrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>start</EM> =&gt; <EM>decrypted-message</EM></TT><BR /></DIV><H2 ID="gray-streams">Gray Streams</H2><P>Ironclad includes support for several convenient stream
+abstractions based on Gray streams. Gray streams support in Ironclad is
+included for SBCL, CMUCL, OpenMCL, Lispworks, and Allegro.</P><H3>Octet streams</H3><P>Octet streams are very similar to Common Lisp's <A HREF="#string-stream" STYLE="symbol">string-stream</A>,
+except they deal in octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-input-stream"></A><TT><STRONG>make-octet-input-stream</STRONG> <EM>buffer</EM> <EM><TT>&optional</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>octet-input-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-input-stream" STYLE="symbol">make-string-input-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-output-stream"></A><TT><STRONG>make-octet-output-stream</STRONG> =&gt; <EM>octet-output-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-output-stream" STYLE="symbol">make-string-output-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="get-output-stream-octets"></A><TT><STRONG>get-output-stream-octets</STRONG> <EM>stream</EM> =&gt; <EM>octet-vector</EM></TT><BR /></DIV><P>As <A HREF="#get-output-stream-string" STYLE="symbol">get-output-stream-string</A>, only with an octet output-steam
+instead of a string output-stream.</P><H3>Digest streams</H3><P>Digest streams compute a digest of the data written to them
+according to a specific digest algorithm.</P><P>Example:</P><PRE>(defun frobbing-function (stream)
+ ;; We want to compute a digest of the data being written to STREAM
+ ;; without involving our callees in the process.
+ (let* ((digesting-stream (crypto:make-digesting-stream :sha1))
+ (stream (make-broadcast-stream stream digesting-stream)))
+ ;; Feed data to STREAM.
+ (frob-guts stream)
+ ;; Do something with the digest computed.
+ (... (crypto:produce-digest digesting-stream) ...)
+ ...))</PRE><DIV CLASS="lisp-symbol"><A NAME="make-digesting-stream"></A><TT><STRONG>make-digesting-stream</STRONG> <EM>digest</EM> =&gt; <EM>stream</EM></TT><BR /></DIV><P>Make a stream that computes a digest of the data written to it
+according to the algorithm <EM>digest-name</EM>. <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> may
+be used to obtain a digest of all the data written to the stream.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">Calling <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> on a digest stream does not alter
+the internal state of the digest.</TD></TR></TABLE><H2>Utility Functions</H2><DIV CLASS="lisp-symbol"><A NAME="ub16ref/le"></A><TT><STRONG>ub16ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/le"></A><TT><STRONG>ub32ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/le"></A><TT><STRONG>ub64ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>This family of functions accesses an unsigned 16-bit, 32-bit or
+64-bit value stored in little-endian order starting at <EM>index</EM> in <EM>array</EM>. <EM>array</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT>. These functions are SETFable.</P><DIV CLASS="lisp-symbol"><A NAME="ub16ref/be"></A><TT><STRONG>ub16ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/be"></A><TT><STRONG>ub32ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/be"></A><TT><STRONG>ub64ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>As the above, only the value is stored in big-endian order.</P><DIV CLASS="lisp-symbol"><A NAME="byte-array-to-hex-string"></A><TT><STRONG>byte-array-to-hex-string</STRONG> <EM>vector</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>element-type</EM> =&gt; <EM>string</EM></TT><BR /><A NAME="ascii-string-to-byte-array"></A><TT><STRONG>ascii-string-to-byte-array</STRONG> <EM>string</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>byte-array-to-hex-string</TT> converts the bytes of <EM>vector</EM>
+between <EM>start</EM> and <EM>end</EM> into a hexadecimal string. It is
+useful for converting digests to a more readable form. <EM>element-type</EM> indicates the element-type of the returned string.</P><P><TT>ascii-string-to-byte-array</TT> is provided as a quick and dirty way
+to convert a string to a byte array suitable for feeding to <A HREF="#update-digest" STYLE="symbol">update-digest</A> or <A HREF="#encrypt" STYLE="symbol">encrypt</A>. Care should be taken to ensure that
+the provided string is actually an ASCII string. <EM>start</EM> and <EM>end</EM> have their usual interpretations.</P><DIV CLASS="lisp-symbol"><A NAME="octets-to-integer"></A><TT><STRONG>octets-to-integer</STRONG> <EM>octet-vec</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>big-endian</EM> <EM>n-bits</EM> =&gt; <EM>number</EM></TT><BR /><A NAME="integer-to-octets"></A><TT><STRONG>integer-to-octets</STRONG> <EM>bignum</EM> <EM><TT>&key</TT></EM> <EM>n-bits</EM> <EM>big-endian</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>octets-to-integer</TT> converts the bytes of <EM>octet-vec</EM> between
+<EM>start</EM> and <EM>end</EM> to an integer as though the bytes denoted a
+number in base 256. <EM>big-endian</EM> is a boolean indicating whether
+the bytes are to be read in big-endian or little-endian order. <EM>n-bits</EM> specifies how many bits should be considered as significant
+in the resulting number.</P><P><TT>integer-to-octets</TT> is the reverse operation.</P><DIV CLASS="lisp-symbol"><A NAME="expt-mod"></A><TT><STRONG>expt-mod</STRONG> =&gt; <EM>number</EM></TT><BR /></DIV><P>Raises <EM>n</EM> to the <EM>exponent</EM> power modulo <EM>modulus</EM> in
+a more efficient fashion than <TT>(MOD (EXPT N EXPONENT) MODULUS)</TT>.</P><H2>Conditions</H2><DIV CLASS="lisp-symbol"><A NAME="ironclad-error"></A><TT><STRONG>ironclad-error</STRONG></TT><BR /></DIV><P>All errors signaled by Ironclad are of this type. This type is a
+direct subtype of <TT>SIMPLE-ERROR</TT> without any extra slots or
+options.</P><DIV CLASS="lisp-symbol"><A NAME="initialization-vector-not-supplied"></A><TT><STRONG>initialization-vector-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled by <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> when an initialization
+vector is not provided and the requested mode requires an initialization
+vector.</P><DIV CLASS="lisp-symbol"><A NAME="invalid-initialization-vector"></A><TT><STRONG>invalid-initialization-vector</STRONG></TT><BR /></DIV><P>This error is signaled when an invalid initialization vector is
+supplied to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> (e.g. when the length of the initialization
+vector does not match the block length of the cipher).</P><DIV CLASS="lisp-symbol"><A NAME="invalid-key-length"></A><TT><STRONG>invalid-key-length</STRONG></TT><BR /></DIV><P>This error is signaled when the key provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is
+not of an acceptable length for the requested cipher.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-cipher"></A><TT><STRONG>unsupported-cipher</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>cipher-name</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#cipher-supported-p" STYLE="symbol">cipher-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-mode"></A><TT><STRONG>unsupported-mode</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>mode</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#mode-supported-p" STYLE="symbol">mode-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-digest"></A><TT><STRONG>unsupported-digest</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>digest-name</EM> provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A> is not <A HREF="#digest-supported-p" STYLE="symbol">digest-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="insufficient-buffer-space"></A><TT><STRONG>insufficient-buffer-space</STRONG></TT><BR /></DIV><P>This error is signaled when Ironclad needs to stuff some data into a
+buffer (e.g. when the user provides <EM>digest</EM> to <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>) and
+there is insufficient space.</P><DIV CLASS="lisp-symbol"><A NAME="key-not-supplied"></A><TT><STRONG>key-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled when a <TT>:KEY</TT> argument is not provided
+to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P></BODY></HTML> \ No newline at end of file
diff --git a/doc/ironclad-doc.txt b/doc/ironclad-doc.txt
new file mode 100644
index 0000000..cac2062
--- /dev/null
+++ b/doc/ironclad-doc.txt
@@ -0,0 +1,658 @@
+(:author "Nathan Froyd"
+ :email "froydnj@gmail.com"
+ :package "Ironclad"
+ :cl-package "IRONCLAD"
+ :version #.(asdf:component-version (asdf:find-system :ironclad))
+ :homepage "http://www.method-combination.net/lisp/ironclad/"
+ :download "http://www.method-combination.net/lisp/files/ironclad.tar.gz")
+
+(:h1 ${package})
+
+(:p ${package} " is a cryptography library written entirely in Common
+Lisp. It includes support for several popular " (:xref "ciphers"
+"ciphers") ", " (:xref "digests" "digests") ", and " (:xref "macs"
+"MACs") ". Rudimentary support for " (:xref "public-key" "public-key
+cryptography") " is included. For several implementations that support
+Gray Streams, " (:xref "gray-streams" "support") " is included for
+convenient stream wrappers.")
+
+(:p ${package} " was written primarily by " ${author} " (" ${email} ").")
+
+(:h2 "Installation")
+
+(:p ${package} " can be downloaded at " (:url ${download} ${download}) ".
+The latest version is " ${version} ".")
+
+(:p "It comes with an ASDF system definition, so " `(ASDF:OOS
+'ASDF:LOAD-OP :IRONCLAD)` " should be all that you need to get started.
+The testsuite can be run by substituting " `ASDF:TEST-OP` " for "
+`ASDF:LOAD-OP` " in the form above.")
+
+(:p ${package} " has been tested in the following implementations:")
+
+(:ul
+(:li "SBCL x86/linux (primary development platform)")
+(:li "SBCL x86-64/solaris")
+(:li "CMUCL x86/linux")
+(:li "ABCL with Sun's 1.5.0 JVM")
+(:li "Lispworks 5.0.1 x86/linux")
+(:li "Allegro 8.0 x86/linux")
+(:li "Allegro 8.1 x86/linux")
+(:li "Allegro 8.1 x86-64/linux")
+(:li "Allegro 8.1 sparc/solaris")
+(:li "CLISP 2.41 x86/linux")
+(:li "CLISP 2.44 x86/cygwin")
+(:li "Clozure Common Lisp 1.2 x86-64/Linux"))
+
+(:p "All included tests should pass successfully. If you use a platform
+not listed above, please send your platform information to the author so
+that he can add it to the above list. If the tests do not all pass, you
+have found a bug; please report it.")
+
+(:h2 "License")
+
+(:p ${package} " is released under a MIT-like license; you can do pretty
+much anything you want to with the code except claim that you wrote
+it.")
+
+((:h2 id "ciphers") "Ciphers")
+
+(:describe :function (ironclad:make-cipher cipher))
+
+(:p "Return a cipher object suitable for use for both encryption and
+decryption.")
+
+(:p 'name' " denotes the encryption algorithm to use. "
+@list-all-ciphers " will tell you the names of all supported ciphers;
+the short list of ones you are likely to be interested in is:")
+
+(:ul
+(:li "AES")
+(:li "DES")
+(:li "3DES")
+(:li "Blowfish")
+(:li "Twofish")
+(:li "RC5")
+(:li "RC6")
+(:li "Arcfour (RC4)"))
+
+(:p 'name' " can be a symbol in the " `KEYWORD` " package or the "
+`IRONCLAD` " package; " `:AES` " for AES, " `IRONCLAD:ARCFOUR` " for
+RC4, and so forth.")
+
+(:p 'mode' " describes the mode of operation for the cipher. Stream
+ciphers such as Arcfour can operate in only one mode, " `stream` ".
+Block ciphers such as AES and DES can operate in several different
+modes:")
+
+(:ul
+(:li "ECB")
+(:li "CBC")
+(:li "OFB")
+(:li "CFB (note that Ironclad's CFB mode is 'n'-bit CFB, where 'n' is
+the " @block-length " of the cipher)")
+(:li "CFB8 (this seems to be the mode other crypto packages call
+'CFB')")
+(:li "CTR"))
+
+(:p 'mode' " should be a symbol in the " `KEYWORD` " or " `IRONCLAD` "
+packages; " `:STREAM` ", " `IRONCLAD:OFB` ", and so forth. An error
+will be signaled if " 'mode' " is not appropriate for the cipher "
+'name' ".")
+
+(:p 'initialization-vector' " (IV) should be supplied only if " 'mode' "
+requires one. " 'initialization-vector' " should be a " `(VECTOR
+(UNSIGNED-BYTE 8))` ". The supplied IV should be the same length as the
+" @block-length " of " 'name' ".")
+
+(:p 'key' " is, of course, the key for the cipher. " 'key' " should be
+a " `(VECTOR (UNSIGNED-BYTE 8))` ".")
+
+(:p "If " 'padding' " is supplied, the specified padding method will be
+used by " @encrypt " and " @decrypt " to handle short blocks when the "
+`:HANDLE-FINAL-BLOCK` " argument is supplied. Depending on the mode
+specified, " 'padding' " may be ignored (e.g. OFB and CFB modes do not
+care about short blocks; neither do stream ciphers).")
+
+(:note 'padding' " is currently ignored in all modes (and, by extension,
+so is " `:HANDLE-FINAL-BLOCK` "). This oversight is expected to be
+corrected in a future release.")
+
+(:describe :function (ironclad:encrypt (values n-bytes-consumed n-bytes-produced)))
+
+(:p "Encrypts data according to " 'cipher' " from " 'plaintext' "
+starting at " 'plaintext-start' " and continuing until "
+'plaintext-end' ". The encrypted data is placed in "
+'ciphertext' " starting at " 'ciphertext-start' ".")
+
+(:describe :function (ironclad:decrypt (values n-bytes-consumed n-bytes-produced)))
+
+(:p "Decrypts data according to " 'cipher' " from " 'ciphertext' "
+starting at " 'ciphertext-start' " and continuing until "
+'ciphertext-end' ". The decrypted data is placed in " 'plaintext' "
+starting at " 'plaintext-start' ".")
+
+(:describe :function (ironclad:encrypt-in-place (values n-bytes-consumed n-bytes-produced))
+ (ironclad:decrypt-in-place (values n-bytes-consumed n-bytes-produced)))
+
+(:p "Encrypts or decrypts data in " 'text' " between " 'start' " and "
+'end' " \"in-place\" according to " 'cipher' ". These functions are
+shorthand for:")
+
+(:pre "(encrypt cipher text text :plaintext-start start :plaintext-end end :ciphertext-start start)
+(decrypt cipher text text :ciphertext-start start :ciphertext-end end :plaintext-start start)")
+
+(:note @encrypt-in-place " and " @decrypt-in-place " do not support a "
+'handle-final-block' " parameter as " @encrypt " and " @decrypt " do.
+If you need the functionality that " 'handle-final-block' " provides,
+then you need to use " @encrypt " and " @decrypt ".")
+
+(:note 'n-bytes-consumed' " and " 'n-bytes-produced' " may not always be
+equal to the length of the data specified in the call to "
+@encrypt-in-place " or " @decrypt-in-place ". This subtlely is also
+present in " @encrypt " or " @decrypt ".")
+
+(:h3 "Inquiry functions")
+
+(:describe :function (ironclad:list-all-ciphers list))
+
+(:p "Returns a list of cipher-names that may be validly passed to "
+@make-cipher ".")
+
+(:describe :function (ironclad:cipher-supported-p boolean))
+
+(:p "Returns T if " 'name' " would be in the list returned by "
+@list-all-ciphers ", NIL otherwise.")
+
+(:describe :function (ironclad:key-lengths list))
+
+(:p "Return a list of valid key lengths for " 'cipher' ".")
+
+(:describe :function (ironclad:block-length number))
+
+(:p "Return the number of octets " 'cipher' " processes at a time. This
+function always returns 1 for stream ciphers.")
+
+((:h2 id "digests") "Digests")
+
+(:p "Digest functions, also known as hash functions, produce
+fixed-length output (a " 'digest' " or " 'hash' ") from a
+variable-length message. The simplest example of a digest function is
+one that adds up all the bytes in the message modulo 256. This digest
+function fails one test of a cryptographically secure hash function: it
+must be difficult to find a message with a given digest. It also fails
+the other test: it must be difficult to find two messages with the same
+digest.")
+
+(:p "Ironclad provides several cryptographically secure digest functions
+and several non-cryptographically secure digest functions.")
+
+(:note "In the functions below, messages or parts thereof are provided
+as octet vectors; Ironclad has no facilities for producing digests of
+strings. If you need to obtain the digest of a string, then you need to
+figure out how to convert it to an octet vector first. This is a
+deliberate design decision. Characters are not equivalent to bytes.
+See your local Unicode guru for more details.")
+
+(:describe :function (ironclad:make-digest digester))
+
+(:p "Returns a digest object. " 'digest-name' " is a keyword naming the
+algorithm you wish " 'digester' " to use. The algorithms you are likely
+to want to use are:")
+
+(:ul
+(:li "MD4")
+(:li "MD5")
+(:li "SHA1")
+(:li "SHA256")
+(:li "Tiger")
+(:li "Adler32")
+(:li "CRC32"))
+
+(:p "Other legitimate digest names can be found by calling "
+@list-all-digests ". Like " @make-cipher ", " 'digest-name' " should be
+a symbol in the " `KEYWORD` " or " `IRONCLAD` " packages.")
+
+(:describe :generic-function (ironclad:update-digest (values)))
+
+(:p "Updates the internal state of " 'digester' " with the contents of "
+'thing' ". The exact method is determined by the type of THING.")
+
+(:p "There are several methods defined on this generic function that
+take a particular digester and a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))` " as well as the usual " 'start' " and " 'end' " keyword
+arguments. These methods update the state of " 'digester' " with the
+subsequence of the array denoted by " 'start' " and " 'end' ". They are
+not listed here because there's one method for every type of digest
+that " ${package} " provides, and listing them would get very tedious
+for no benefit. An example should suffice.")
+
+(:pre
+"(let ((digester (ironclad:make-digest :sha1))
+ (array (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)))
+ ;; Update with 16 zeroes.
+ (ironclad:update-digest digester array)
+ ;; Update with 8 ones.
+ (fill array 1 :start 2 :end 10)
+ (ironclad:update-digest digester array :start 2 :end 10))")
+
+(:describe :method (ironclad:update-digest (t stream) digester))
+
+(:p "Update the internal state of " 'digester' " with the contents of "
+'stream' ", which must respond to " `READ-BYTE` " or " `READ-SEQUENCE` "
+with a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))` " and return "
+'digester' ". It differs from " @digest-stream ", below, in that you
+may need to digest data before or after the contents of " 'stream' "
+(this happens, for instance, when signing the contents of some file).")
+
+(:describe :generic-function (ironclad:produce-digest digest))
+
+(:p "Return the digest of the data processed by " 'digester' " so far.
+The internal state of " 'digester' " is modified; if you wish to retain
+a copy of the digest, you must call " @copy-digest ".")
+
+(:p "If " 'digest' " is provided, the computed digest will be placed
+into " 'digest' " starting at " 'digest-start' ". " 'digest' " must be
+a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))` ". An "
+@insufficient-buffer-space " error will be signaled if there is
+insufficient space in " 'digest' ".")
+
+(:h3 "High-level convenience functions")
+
+(:p "Several high-level convenience functions that encapsulate common
+sequences of " @make-digest ", " @update-digest " and " @produce-digest
+" are provided by Ironclad as well. They come in two flavors: the first
+takes a digest name as would be provided to " @make-digest ". The
+second way to call these functions is to provide an actual digest object
+as the first argument. So one can say:")
+
+(:pre "(ironclad:digest-sequence :md5 *buffer*)")
+
+(:p "or, equivalently:")
+
+(:pre
+"(let ((digester (make-digest :md5)))
+ (ironclad:digest-sequence digester *buffer*))")
+
+(:p "The second form comes in handy if you plan on " (:xref
+"digest-tips" "reusing the digest object") ".")
+
+(:describe :generic-function (ironclad:digest-sequence digest))
+
+(:p "Returns the digest of the subsequence of " 'sequence' " bounded by
+" 'start' " and " 'end' ", according to " 'digest-name' ". " 'sequence'
+" must be a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8))` ". " 'digest' " and "
+'digest-start' " are as in " @produce-digest ".")
+
+(:describe :generic-function (ironclad:digest-stream digest))
+
+(:p "Returns the digest of the contents of the stream specified by "
+'stream' ". " `READ-BYTE` " must be a legal operation on " 'stream' "
+and return an " `(UNSIGNED-BYTE 8)` ". In a similar fashion, "
+`READ-SEQUENCE` " on " 'stream' " must support reading into a "
+`(SIMPLE-ARRAY (UNSIGNED-BYTE 8))` ". " 'digest' " and " 'digest-start'
+" are as in " @produce-digest ".")
+
+(:p "If " 'buffer' " is provided, it must be a " `(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))` "; the portion of " 'buffer' " between " 'start'
+" and " 'end' " will be used to read the data from the stream.")
+
+(:describe :generic-function (ironclad:digest-file digest))
+
+(:p "Returns the digest of the contents of the file named by "
+'pathname' ". " 'digest' " and " 'digest-start' " are as in "
+@produce-digest ".")
+
+(:p "If " 'buffer' " is provided, it must be a " `(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))` "; the portion of " 'buffer' " between " 'start'
+" and " 'end' " will be used to read the data from the stream.")
+
+(:h3 "Inquiry functions")
+
+(:describe :function (ironclad:list-all-digests list))
+
+(:p "Returns a list whose elements may be validly passed to " @make-digest ".")
+
+(:describe :function (ironclad:digest-supported-p boolean))
+
+(:p "Returns T if " 'name' " would be in the list returned by "
+@list-all-digests ", NIL otherwise.")
+
+(:describe :function (ironclad:digest-length number))
+
+(:p "Returns the length of the digest computed by " 'digest' ", which
+may be a digest-name or a digest instance.")
+
+((:h3 id "digest-tips") "Miscellaneous")
+
+(:p "Ironclad digests are CLOS objects; the interesting thing about this
+for most purposes is that functions like " `REINITIALIZE-INSTANCE` " are
+supported. This means one can write a fairly efficient clone of the "
+`md5sum` " program like so:")
+
+(:pre
+"(defun digest-sum-files (digest &rest files)
+ (unless files
+ (error \"no files given to digest\"))
+ (loop with buffer = (make-array 8192 :element-type '(unsigned-byte 8))
+ with digest = (make-array (ironclad:digest-length digest)
+ :element-type '(unsigned-byte 8))
+ for file in files
+ for digester = (ironclad:make-digest digest)
+ then (reinitialize-instance digester)
+ do (ironclad:digest-file digester file :buffer buffer :digest digest)
+ (format t \"~A ~A~%\" (file-namestring file)
+ (ironclad:byte-array-to-hex-string digest))))")
+
+((:h2 id "macs") "Message authentication codes")
+
+(:p "A message authentication code is a cryptographic function of some
+data and a user-specified key. Only a person knowing the key can
+recompute the MAC for the given message. A MAC is useful where
+maintaining data integrity is required, but the secrecy of the data is
+not paramount.")
+
+(:p "Ironclad provides two different kinds of MACs: HMACs, specified in
+" (:url "http://www.ietf.org/rfc/rfc2109.txt" "RFC 2104") ", and CMACs,
+specified in " (:url "http://www.ietf.org/rfc/rfc4493.txt" "RFC 4493") "
+and NIST document 800-38B.")
+
+(:h3 "HMACs")
+
+(:p "Instances of HMACs are constructed by specifying a secret key and a
+digest-name.")
+
+(:describe :function (ironclad:make-hmac hmac))
+
+(:p "Return an HMAC instance based on the hash function " 'digest-name'
+" with secret key " 'key' ".")
+
+(:p "The returned object supports " `REINITIALIZE-INSTANCE` ":")
+
+(:describe :method (cl:reinitialize-instance (ironclad::hmac) hmac))
+
+(:p "The " `:KEY` " argument is the secret key, as provided to "
+@make-hmac ".")
+
+(:describe :function (ironclad:update-hmac hmac))
+
+(:p "Update the internal state of " 'hmac' " with the data in "
+'sequence' " bounded by " 'start' " and " 'end' ". " 'sequence' " must
+be a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))` ".")
+
+(:describe :function (ironclad:hmac-digest digest))
+
+(:p "Returns the MAC (" 'digest' ") computed by " 'hmac' " thus far.
+The internal state of " 'hmac' " is not modified; this feature makes it
+possible to compute a \"rolling MAC\" of a document. The length of "
+'digest' " is determined by the " @digest-length " of " 'digest-name' "
+passed to " @make-hmac " when " 'hmac' " was constructed.")
+
+(:p "If " 'buffer' " is provided, the computed MAC will be placed into "
+'buffer' " starting at " 'buffer-start' ". " 'buffer' " must be a "
+`(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))` ". An "
+@insufficient-buffer-space " error will be signaled if there is
+insufficient space in " 'buffer' ".")
+
+(:h3 "CMACs")
+
+(:p "Instances of CMACs are constructed by specifying a secret key and a
+cipher-name.")
+
+(:describe :function (ironclad:make-cmac cmac))
+
+(:p "Return a CMAC instance based on the cipher " 'cipher-name' " with
+secret key " 'key' ". " 'cipher-name' " must have a " @block-length "
+of either 8 or 16; this restriction is satisfied by most ciphers in
+Ironclad with the notable exception of stream ciphers. " 'key' " must
+be an acceptable key for " 'cipher-name' ".")
+
+(:describe :function (ironclad:update-cmac cmac))
+
+(:p "Update the internal state of " 'cmac' " with the data in "
+'sequence' " bounded by " 'start' " and " 'end' ". " 'sequence' " must
+be a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))` ".")
+
+(:describe :function (ironclad:cmac-digest digest))
+
+(:p "Returns the MAC (" 'digest' ") computed by " 'cmac' " thus far.
+The internal state of " 'cmac' " is not modified; this feature makes it
+possible to compute a \"rolling MAC\" of a document. The length of "
+'digest' " is determined by the " @block-length " of " 'cipher-name' "
+passed to " @make-cmac " when " 'cmac' " was constructed.")
+
+((:h2 id "public-key") "Public-key Operations")
+
+(:p "Ironclad includes support for DSA signing and verification.
+Support for RSA encryption and decryption is provided as well, but it is
+\"raw\"--the various formatting schemes (e.g. PKCS-1) must be implemented
+by the user at this time.")
+
+(:h3 "Key construction")
+
+(:describe :generic-function (ironclad:make-public-key public-key))
+
+(:p "Return a public key according to " 'kind' ". The " '&key' "
+arguments vary according to " 'kind' ". The interesting bits are in the
+methods that specialize on " 'kind' ", below.")
+
+(:describe :method (ironclad:make-public-key ((eql :dsa)) private-key))
+
+(:p "Return a DSA public key. " 'p' ", " 'q' ", " 'g' ", and " 'y' "
+are the usual parameters for DSA keys discussed in the literature.")
+
+(:describe :generic-function (ironclad:make-private-key private-key))
+
+(:p "Return a private key according to " 'kind' ". The " '&key' "
+arguments vary according to " 'kind' ". The interesting bits are in the
+methods that specialize on " 'kind' ", below.")
+
+(:describe :method (ironclad:make-private-key ((eql :dsa)) private-key))
+
+(:p "Return a DSA private key. " 'p' ", " 'q' ", " 'g' ", " 'y' ", and
+" 'x' " are the usual parameters for DSA keys discussed in the
+literature.")
+
+(:h3 "Digital signatures")
+
+(:describe :generic-function (ironclad:sign-message signature))
+
+(:p "Return a signature of " 'message' " between " 'start' " and " 'end'
+" signed with " 'key' "; the class of " 'key' " determines the class of
+" 'signature' ".")
+
+(:describe :method (ironclad:sign-message (ironclad::dsa-private-key t) signature))
+
+(:p "This method places an additional constraint on the size of "
+'message' " specified by " 'start' " and " 'end' ": it must be exactly
+20 bytes long (the length of a SHA-1 digest). " 'signature' " is a "
+@dsa-signature " object.")
+
+(:describe :generic-function (ironclad:verify-signature boolean))
+
+(:p "Verify whether " 'signature' " is the signature of " 'message' "
+between " 'start' " and " 'end' " using " 'key' ". Return T or NIL
+depending on the result of verification.")
+
+(:describe :method (ironclad:verify-signature (ironclad::dsa-public-key t ironclad::dsa-signature) boolean))
+
+(:h4 "Signature objects")
+
+(:p "There is no one \"right\" way to format signatures into octet
+vectors; different applications may have different requirements. "
+@sign-message " therefore returns objects and lets the user determine
+how to best format the values contained therein.")
+
+(:describe :class dsa-signature)
+
+(:p "A DSA signature object.")
+
+(:describe :function (ironclad:make-dsa-signature signature))
+
+(:p "Returns a DSA signature with the provided " 'r' " and " 's' "
+values. " 'r' " and " 's' " may be either integers or they may be
+20-byte octet vectors.")
+
+(:describe :function (ironclad:dsa-signature-r integer))
+
+(:p "Returns the " 'r' " value of the provided DSA signature.")
+
+(:describe :function (ironclad:dsa-signature-s integer))
+
+(:p "Returns the " 's' " value of the provided DSA signature.")
+
+(:h3 "Encryption and decryption")
+
+(:describe :function (ironclad:encrypt-message encrypted-message))
+
+(:describe :function (ironclad:decrypt-message decrypted-message))
+
+((:h2 id "gray-streams") "Gray Streams")
+
+(:p "Ironclad includes support for several convenient stream
+abstractions based on Gray streams. Gray streams support in Ironclad is
+included for SBCL, CMUCL, OpenMCL, Lispworks, and Allegro.")
+
+(:h3 "Octet streams")
+
+(:p "Octet streams are very similar to Common Lisp's " @string-stream ",
+except they deal in octets instead of characters.")
+
+(:describe :function (ironclad:make-octet-input-stream octet-input-stream))
+
+(:p "As " @make-string-input-stream ", only with octets instead of characters.")
+
+(:describe :function (ironclad:make-octet-output-stream octet-output-stream))
+
+(:p "As " @make-string-output-stream ", only with octets instead of characters.")
+
+(:describe :function (ironclad:get-output-stream-octets octet-vector))
+
+(:p "As " @get-output-stream-string ", only with an octet output-steam
+instead of a string output-stream.")
+
+(:h3 "Digest streams")
+
+(:p "Digest streams compute a digest of the data written to them
+according to a specific digest algorithm.")
+
+(:p "Example:")
+
+(:pre "(defun frobbing-function (stream)
+ ;; We want to compute a digest of the data being written to STREAM
+ ;; without involving our callees in the process.
+ (let* ((digesting-stream (crypto:make-digesting-stream :sha1))
+ (stream (make-broadcast-stream stream digesting-stream)))
+ ;; Feed data to STREAM.
+ (frob-guts stream)
+ ;; Do something with the digest computed.
+ (... (crypto:produce-digest digesting-stream) ...)
+ ...))")
+
+(:describe :function (ironclad:make-digesting-stream stream))
+
+(:p "Make a stream that computes a digest of the data written to it
+according to the algorithm " 'digest-name' ". " @produce-digest " may
+be used to obtain a digest of all the data written to the stream.")
+
+(:note "Calling " @produce-digest " on a digest stream does not alter
+the internal state of the digest.")
+
+(:h2 "Utility Functions")
+
+(:describe :accessor (ironclad:ub16ref/le value)
+ (ironclad:ub32ref/le value)
+ (ironclad:ub64ref/le value))
+
+(:p "This family of functions accesses an unsigned 16-bit, 32-bit or
+64-bit value stored in little-endian order starting at " 'index' " in "
+'array' ". " 'array' " must be a " `(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))` ". These functions are SETFable.")
+
+(:describe :accessor (ironclad:ub16ref/be value)
+ (ironclad:ub32ref/be value)
+ (ironclad:ub64ref/be value))
+
+(:p "As the above, only the value is stored in big-endian order.")
+
+(:describe :function (ironclad:byte-array-to-hex-string string)
+ (ironclad:ascii-string-to-byte-array vector))
+
+(:p `byte-array-to-hex-string` " converts the bytes of " 'vector' "
+between " 'start' " and " 'end' " into a hexadecimal string. It is
+useful for converting digests to a more readable form. " 'element-type'
+" indicates the element-type of the returned string.")
+
+(:p `ascii-string-to-byte-array` " is provided as a quick and dirty way
+to convert a string to a byte array suitable for feeding to "
+@update-digest " or " @encrypt ". Care should be taken to ensure that
+the provided string is actually an ASCII string. " 'start' " and "
+'end' " have their usual interpretations.")
+
+(:describe :function (ironclad:octets-to-integer number)
+ (ironclad:integer-to-octets vector))
+
+(:p `octets-to-integer` " converts the bytes of " 'octet-vec' " between
+" 'start' " and " 'end' " to an integer as though the bytes denoted a
+number in base 256. " 'big-endian' " is a boolean indicating whether
+the bytes are to be read in big-endian or little-endian order. "
+'n-bits' " specifies how many bits should be considered as significant
+in the resulting number.")
+
+(:p `integer-to-octets` " is the reverse operation.")
+
+(:describe :function (ironclad:expt-mod number))
+
+(:p "Raises " 'n' " to the " 'exponent' " power modulo " 'modulus' " in
+a more efficient fashion than " `(MOD (EXPT N EXPONENT) MODULUS)` ".")
+
+(:h2 "Conditions")
+
+(:describe :condition ironclad-error)
+
+(:p "All errors signaled by Ironclad are of this type. This type is a
+direct subtype of " `SIMPLE-ERROR` " without any extra slots or
+options.")
+
+(:describe :condition initialization-vector-not-supplied)
+
+(:p "This error is signaled by " @make-cipher " when an initialization
+vector is not provided and the requested mode requires an initialization
+vector.")
+
+(:describe :condition invalid-initialization-vector)
+
+(:p "This error is signaled when an invalid initialization vector is
+supplied to " @make-cipher " (e.g. when the length of the initialization
+vector does not match the block length of the cipher).")
+
+(:describe :condition invalid-key-length)
+
+(:p "This error is signaled when the key provided to " @make-cipher " is
+not of an acceptable length for the requested cipher.")
+
+(:describe :condition unsupported-cipher)
+
+(:p "This error is signaled when the " 'cipher-name' " provided to "
+@make-cipher " is not " @cipher-supported-p ".")
+
+(:describe :condition unsupported-mode)
+
+(:p "This error is signaled when the " 'mode' " provided to "
+@make-cipher " is not " @mode-supported-p ".")
+
+(:describe :condition unsupported-digest)
+
+(:p "This error is signaled when the " 'digest-name' " provided to "
+@make-digest " is not " @digest-supported-p ".")
+
+(:describe :condition insufficient-buffer-space)
+
+(:p "This error is signaled when Ironclad needs to stuff some data into a
+buffer (e.g. when the user provides " 'digest' " to " @produce-digest ") and
+there is insufficient space.")
+
+(:describe :condition key-not-supplied)
+
+(:p "This error is signaled when a " `:KEY` " argument is not provided
+to " @make-cipher ".")
diff --git a/doc/ironclad.html b/doc/ironclad.html
new file mode 100644
index 0000000..807db3d
--- /dev/null
+++ b/doc/ironclad.html
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<HTML><HEAD><TITLE>Ironclad</TITLE><LINK TYPE="text/css" TITLE="default" REL="stylesheet" MEDIA="screen" HREF="style.css" /></HEAD><BODY><H1>Ironclad</H1><P>Ironclad is a cryptography library written entirely in Common
+Lisp. It includes support for several popular <A HREF="#ciphers">ciphers</A>, <A HREF="#digests">digests</A>, and <A HREF="#macs">MACs</A>. Rudimentary support for <A HREF="#public-key">public-key
+cryptography</A> is included. For several implementations that support
+Gray Streams, <A HREF="#gray-streams">support</A> is included for
+convenient stream wrappers.</P><P>Ironclad was written primarily by Nathan Froyd (froydnj@gmail.com).</P><H2>Installation</H2><P>Ironclad can be downloaded at <A HREF="http://www.method-combination.net/lisp/files/ironclad.tar.gz">http://www.method-combination.net/lisp/files/ironclad.tar.gz</A>.
+The latest version is 0.27.</P><P>It comes with an ASDF system definition, so <TT>(ASDF:OOS
+'ASDF:LOAD-OP :IRONCLAD)</TT> should be all that you need to get started.
+The testsuite can be run by substituting <TT>ASDF:TEST-OP</TT> for <TT>ASDF:LOAD-OP</TT> in the form above.</P><P>Ironclad has been tested in the following implementations:</P><UL><LI>SBCL x86/linux (primary development platform)</LI><LI>SBCL x86-64/solaris</LI><LI>CMUCL x86/linux</LI><LI>ABCL with Sun's 1.5.0 JVM</LI><LI>Lispworks 5.0.1 x86/linux</LI><LI>Allegro 8.0 x86/linux</LI><LI>Allegro 8.1 x86/linux</LI><LI>Allegro 8.1 x86-64/linux</LI><LI>Allegro 8.1 sparc/solaris</LI><LI>CLISP 2.41 x86/linux</LI><LI>CLISP 2.44 x86/cygwin</LI><LI>Clozure Common Lisp 1.2 x86-64/Linux</LI></UL><P>All included tests should pass successfully. If you use a platform
+not listed above, please send your platform information to the author so
+that he can add it to the above list. If the tests do not all pass, you
+have found a bug; please report it.</P><H2>License</H2><P>Ironclad is released under a MIT-like license; you can do pretty
+much anything you want to with the code except claim that you wrote
+it.</P><H2 ID="ciphers">Ciphers</H2><DIV CLASS="lisp-symbol"><A NAME="make-cipher"></A><TT><STRONG>make-cipher</STRONG> <EM>name</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM>mode</EM> <EM>initialization-vector</EM> <EM>padding</EM> =&gt; <EM>cipher</EM></TT><BR /></DIV><P>Return a cipher object suitable for use for both encryption and
+decryption.</P><P><EM>name</EM> denotes the encryption algorithm to use. <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A> will tell you the names of all supported ciphers;
+the short list of ones you are likely to be interested in is:</P><UL><LI>AES</LI><LI>DES</LI><LI>3DES</LI><LI>Blowfish</LI><LI>Twofish</LI><LI>RC5</LI><LI>RC6</LI><LI>Arcfour (RC4)</LI></UL><P><EM>name</EM> can be a symbol in the <TT>KEYWORD</TT> package or the <TT>IRONCLAD</TT> package; <TT>:AES</TT> for AES, <TT>IRONCLAD:ARCFOUR</TT> for
+RC4, and so forth.</P><P><EM>mode</EM> describes the mode of operation for the cipher. Stream
+ciphers such as Arcfour can operate in only one mode, <TT>stream</TT>.
+Block ciphers such as AES and DES can operate in several different
+modes:</P><UL><LI>ECB</LI><LI>CBC</LI><LI>OFB</LI><LI>CFB (note that Ironclad's CFB mode is 'n'-bit CFB, where 'n' is
+the <A HREF="#block-length" STYLE="symbol">block-length</A> of the cipher)</LI><LI>CFB8 (this seems to be the mode other crypto packages call
+'CFB')</LI><LI>CTR</LI></UL><P><EM>mode</EM> should be a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT>
+packages; <TT>:STREAM</TT>, <TT>IRONCLAD:OFB</TT>, and so forth. An error
+will be signaled if <EM>mode</EM> is not appropriate for the cipher <EM>name</EM>.</P><P><EM>initialization-vector</EM> (IV) should be supplied only if <EM>mode</EM>
+requires one. <EM>initialization-vector</EM> should be a <TT>(VECTOR
+(UNSIGNED-BYTE 8))</TT>. The supplied IV should be the same length as the
+<A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>name</EM>.</P><P><EM>key</EM> is, of course, the key for the cipher. <EM>key</EM> should be
+a <TT>(VECTOR (UNSIGNED-BYTE 8))</TT>.</P><P>If <EM>padding</EM> is supplied, the specified padding method will be
+used by <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> to handle short blocks when the <TT>:HANDLE-FINAL-BLOCK</TT> argument is supplied. Depending on the mode
+specified, <EM>padding</EM> may be ignored (e.g. OFB and CFB modes do not
+care about short blocks; neither do stream ciphers).</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>padding</EM> is currently ignored in all modes (and, by extension,
+so is <TT>:HANDLE-FINAL-BLOCK</TT>). This oversight is expected to be
+corrected in a future release.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="encrypt"></A><TT><STRONG>encrypt</STRONG> <EM>cipher</EM> <EM>plaintext</EM> <EM>ciphertext</EM> <EM><TT>&key</TT></EM> <EM>plaintext-start</EM> <EM>plaintext-end</EM> <EM>ciphertext-start</EM> <EM>plaintext-start</EM> <EM>ciphertext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts data according to <EM>cipher</EM> from <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM> and continuing until <EM>plaintext-end</EM>. The encrypted data is placed in <EM>ciphertext</EM> starting at <EM>ciphertext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="decrypt"></A><TT><STRONG>decrypt</STRONG> <EM>cipher</EM> <EM>ciphertext</EM> <EM>plaintext</EM> <EM><TT>&key</TT></EM> <EM>ciphertext-start</EM> <EM>ciphertext-end</EM> <EM>plaintext-start</EM> <EM>ciphertext-start</EM> <EM>plaintext-start</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Decrypts data according to <EM>cipher</EM> from <EM>ciphertext</EM>
+starting at <EM>ciphertext-start</EM> and continuing until <EM>ciphertext-end</EM>. The decrypted data is placed in <EM>plaintext</EM>
+starting at <EM>plaintext-start</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="encrypt-in-place"></A><TT><STRONG>encrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /><A NAME="decrypt-in-place"></A><TT><STRONG>decrypt-in-place</STRONG> <EM>cipher</EM> <EM>text</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>n-bytes-consumed</EM>, <EM>n-bytes-produced</EM></TT><BR /></DIV><P>Encrypts or decrypts data in <EM>text</EM> between <EM>start</EM> and <EM>end</EM> "in-place" according to <EM>cipher</EM>. These functions are
+shorthand for:</P><PRE>(encrypt cipher text text :plaintext-start start :plaintext-end end :ciphertext-start start)
+(decrypt cipher text text :ciphertext-start start :ciphertext-end end :plaintext-start start)</PRE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> and <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A> do not support a <EM>handle-final-block</EM> parameter as <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A> do.
+If you need the functionality that <EM>handle-final-block</EM> provides,
+then you need to use <A HREF="#encrypt" STYLE="symbol">encrypt</A> and <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content"><EM>n-bytes-consumed</EM> and <EM>n-bytes-produced</EM> may not always be
+equal to the length of the data specified in the call to <A HREF="#encrypt-in-place" STYLE="symbol">encrypt-in-place</A> or <A HREF="#decrypt-in-place" STYLE="symbol">decrypt-in-place</A>. This subtlely is also
+present in <A HREF="#encrypt" STYLE="symbol">encrypt</A> or <A HREF="#decrypt" STYLE="symbol">decrypt</A>.</TD></TR></TABLE><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-ciphers"></A><TT><STRONG>list-all-ciphers</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list of cipher-names that may be validly passed to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P><DIV CLASS="lisp-symbol"><A NAME="cipher-supported-p"></A><TT><STRONG>cipher-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-ciphers" STYLE="symbol">list-all-ciphers</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="key-lengths"></A><TT><STRONG>key-lengths</STRONG> <EM>cipher</EM> =&gt; <EM>list</EM></TT><BR /></DIV><P>Return a list of valid key lengths for <EM>cipher</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="block-length"></A><TT><STRONG>block-length</STRONG> <EM>cipher</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Return the number of octets <EM>cipher</EM> processes at a time. This
+function always returns 1 for stream ciphers.</P><H2 ID="digests">Digests</H2><P>Digest functions, also known as hash functions, produce
+fixed-length output (a <EM>digest</EM> or <EM>hash</EM>) from a
+variable-length message. The simplest example of a digest function is
+one that adds up all the bytes in the message modulo 256. This digest
+function fails one test of a cryptographically secure hash function: it
+must be difficult to find a message with a given digest. It also fails
+the other test: it must be difficult to find two messages with the same
+digest.</P><P>Ironclad provides several cryptographically secure digest functions
+and several non-cryptographically secure digest functions.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">In the functions below, messages or parts thereof are provided
+as octet vectors; Ironclad has no facilities for producing digests of
+strings. If you need to obtain the digest of a string, then you need to
+figure out how to convert it to an octet vector first. This is a
+deliberate design decision. Characters are not equivalent to bytes.
+See your local Unicode guru for more details.</TD></TR></TABLE><DIV CLASS="lisp-symbol"><A NAME="make-digest"></A><TT><STRONG>make-digest</STRONG> <EM>digest-name</EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Returns a digest object. <EM>digest-name</EM> is a keyword naming the
+algorithm you wish <EM>digester</EM> to use. The algorithms you are likely
+to want to use are:</P><UL><LI>MD4</LI><LI>MD5</LI><LI>SHA1</LI><LI>SHA256</LI><LI>Tiger</LI><LI>Adler32</LI><LI>CRC32</LI></UL><P>Other legitimate digest names can be found by calling <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>. Like <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>, <EM>digest-name</EM> should be
+a symbol in the <TT>KEYWORD</TT> or <TT>IRONCLAD</TT> packages.</P><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>thing</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>(values)</EM></TT><BR /></DIV><P>Updates the internal state of <EM>digester</EM> with the contents of <EM>thing</EM>. The exact method is determined by the type of THING.</P><P>There are several methods defined on this generic function that
+take a particular digester and a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT> as well as the usual <EM>start</EM> and <EM>end</EM> keyword
+arguments. These methods update the state of <EM>digester</EM> with the
+subsequence of the array denoted by <EM>start</EM> and <EM>end</EM>. They are
+not listed here because there's one method for every type of digest
+that Ironclad provides, and listing them would get very tedious
+for no benefit. An example should suffice.</P><PRE>(let ((digester (ironclad:make-digest :sha1))
+ (array (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0)))
+ ;; Update with 16 zeroes.
+ (ironclad:update-digest digester array)
+ ;; Update with 8 ones.
+ (fill array 1 :start 2 :end 10)
+ (ironclad:update-digest digester array :start 2 :end 10))</PRE><DIV CLASS="lisp-symbol"><A NAME="update-digest"></A><TT><STRONG>update-digest</STRONG> <EM>digester</EM> <EM>(stream stream)</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>(start 0)</EM> <EM>end</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>digester</EM></TT><BR /></DIV><P>Update the internal state of <EM>digester</EM> with the contents of <EM>stream</EM>, which must respond to <TT>READ-BYTE</TT> or <TT>READ-SEQUENCE</TT>
+with a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT> and return <EM>digester</EM>. It differs from <A HREF="#digest-stream" STYLE="symbol">digest-stream</A>, below, in that you
+may need to digest data before or after the contents of <EM>stream</EM>
+(this happens, for instance, when signing the contents of some file).</P><DIV CLASS="lisp-symbol"><A NAME="produce-digest"></A><TT><STRONG>produce-digest</STRONG> <EM>digester</EM> <EM><TT>&key</TT></EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Return the digest of the data processed by <EM>digester</EM> so far.
+The internal state of <EM>digester</EM> is modified; if you wish to retain
+a copy of the digest, you must call <A HREF="#copy-digest" STYLE="symbol">copy-digest</A>.</P><P>If <EM>digest</EM> is provided, the computed digest will be placed
+into <EM>digest</EM> starting at <EM>digest-start</EM>. <EM>digest</EM> must be
+a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
+insufficient space in <EM>digest</EM>.</P><H3>High-level convenience functions</H3><P>Several high-level convenience functions that encapsulate common
+sequences of <A HREF="#make-digest" STYLE="symbol">make-digest</A>, <A HREF="#update-digest" STYLE="symbol">update-digest</A> and <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> are provided by Ironclad as well. They come in two flavors: the first
+takes a digest name as would be provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A>. The
+second way to call these functions is to provide an actual digest object
+as the first argument. So one can say:</P><PRE>(ironclad:digest-sequence :md5 *buffer*)</PRE><P>or, equivalently:</P><PRE>(let ((digester (make-digest :md5)))
+ (ironclad:digest-sequence digester *buffer*))</PRE><P>The second form comes in handy if you plan on <A HREF="#digest-tips">reusing the digest object</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-sequence"></A><TT><STRONG>digest-sequence</STRONG> <EM>digest-spec</EM> <EM>sequence</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the subsequence of <EM>sequence</EM> bounded by
+<EM>start</EM> and <EM>end</EM>, according to <EM>digest-name</EM>. <EM>sequence</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-stream"></A><TT><STRONG>digest-stream</STRONG> <EM>digest-spec</EM> <EM>stream</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the stream specified by <EM>stream</EM>. <TT>READ-BYTE</TT> must be a legal operation on <EM>stream</EM>
+and return an <TT>(UNSIGNED-BYTE 8)</TT>. In a similar fashion, <TT>READ-SEQUENCE</TT> on <EM>stream</EM> must support reading into a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8))</TT>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><P>If <EM>buffer</EM> is provided, it must be a <TT>(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))</TT>; the portion of <EM>buffer</EM> between <EM>start</EM> and <EM>end</EM> will be used to read the data from the stream.</P><DIV CLASS="lisp-symbol"><A NAME="digest-file"></A><TT><STRONG>digest-file</STRONG> <EM>digest-spec</EM> <EM>pathname</EM> <EM><TT>&rest</TT></EM> <EM>args</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>start</EM> <EM>end</EM> <EM>digest</EM> <EM>digest-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the digest of the contents of the file named by <EM>pathname</EM>. <EM>digest</EM> and <EM>digest-start</EM> are as in <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>.</P><P>If <EM>buffer</EM> is provided, it must be a <TT>(SIMPLE-ARRAY
+(UNSIGNED-BYTE 8) (*))</TT>; the portion of <EM>buffer</EM> between <EM>start</EM> and <EM>end</EM> will be used to read the data from the stream.</P><H3>Inquiry functions</H3><DIV CLASS="lisp-symbol"><A NAME="list-all-digests"></A><TT><STRONG>list-all-digests</STRONG> =&gt; <EM>list</EM></TT><BR /></DIV><P>Returns a list whose elements may be validly passed to <A HREF="#make-digest" STYLE="symbol">make-digest</A>.</P><DIV CLASS="lisp-symbol"><A NAME="digest-supported-p"></A><TT><STRONG>digest-supported-p</STRONG> <EM>name</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Returns T if <EM>name</EM> would be in the list returned by <A HREF="#list-all-digests" STYLE="symbol">list-all-digests</A>, NIL otherwise.</P><DIV CLASS="lisp-symbol"><A NAME="digest-length"></A><TT><STRONG>digest-length</STRONG> <EM>digest</EM> =&gt; <EM>number</EM></TT><BR /></DIV><P>Returns the length of the digest computed by <EM>digest</EM>, which
+may be a digest-name or a digest instance.</P><H3 ID="digest-tips">Miscellaneous</H3><P>Ironclad digests are CLOS objects; the interesting thing about this
+for most purposes is that functions like <TT>REINITIALIZE-INSTANCE</TT> are
+supported. This means one can write a fairly efficient clone of the <TT>md5sum</TT> program like so:</P><PRE>(defun digest-sum-files (digest &rest files)
+ (unless files
+ (error "no files given to digest"))
+ (loop with buffer = (make-array 8192 :element-type '(unsigned-byte 8))
+ with digest = (make-array (ironclad:digest-length digest)
+ :element-type '(unsigned-byte 8))
+ for file in files
+ for digester = (ironclad:make-digest digest)
+ then (reinitialize-instance digester)
+ do (ironclad:digest-file digester file :buffer buffer :digest digest)
+ (format t "~A ~A~%" (file-namestring file)
+ (ironclad:byte-array-to-hex-string digest))))</PRE><H2 ID="macs">Message authentication codes</H2><P>A message authentication code is a cryptographic function of some
+data and a user-specified key. Only a person knowing the key can
+recompute the MAC for the given message. A MAC is useful where
+maintaining data integrity is required, but the secrecy of the data is
+not paramount.</P><P>Ironclad provides two different kinds of MACs: HMACs, specified in
+<A HREF="http://www.ietf.org/rfc/rfc2109.txt">RFC 2104</A>, and CMACs,
+specified in <A HREF="http://www.ietf.org/rfc/rfc4493.txt">RFC 4493</A>
+and NIST document 800-38B.</P><H3>HMACs</H3><P>Instances of HMACs are constructed by specifying a secret key and a
+digest-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-hmac"></A><TT><STRONG>make-hmac</STRONG> <EM>key</EM> <EM>digest-name</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Return an HMAC instance based on the hash function <EM>digest-name</EM> with secret key <EM>key</EM>.</P><P>The returned object supports <TT>REINITIALIZE-INSTANCE</TT>:</P><DIV CLASS="lisp-symbol"><A NAME="reinitialize-instance"></A><TT><STRONG>reinitialize-instance</STRONG> <EM>(mac hmac)</EM> <EM><TT>&rest</TT></EM> <EM>initargs</EM> <EM><TT>&key</TT></EM> <EM>key</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>The <TT>:KEY</TT> argument is the secret key, as provided to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A>.</P><DIV CLASS="lisp-symbol"><A NAME="update-hmac"></A><TT><STRONG>update-hmac</STRONG> <EM>hmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>hmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>hmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="hmac-digest"></A><TT><STRONG>hmac-digest</STRONG> <EM>hmac</EM> <EM><TT>&key</TT></EM> <EM>buffer</EM> <EM>buffer-start</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>hmac</EM> thus far.
+The internal state of <EM>hmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#digest-length" STYLE="symbol">digest-length</A> of <EM>digest-name</EM>
+passed to <A HREF="#make-hmac" STYLE="symbol">make-hmac</A> when <EM>hmac</EM> was constructed.</P><P>If <EM>buffer</EM> is provided, the computed MAC will be placed into <EM>buffer</EM> starting at <EM>buffer-start</EM>. <EM>buffer</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>. An <A HREF="#insufficient-buffer-space" STYLE="symbol">insufficient-buffer-space</A> error will be signaled if there is
+insufficient space in <EM>buffer</EM>.</P><H3>CMACs</H3><P>Instances of CMACs are constructed by specifying a secret key and a
+cipher-name.</P><DIV CLASS="lisp-symbol"><A NAME="make-cmac"></A><TT><STRONG>make-cmac</STRONG> <EM>key</EM> <EM>cipher-name</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Return a CMAC instance based on the cipher <EM>cipher-name</EM> with
+secret key <EM>key</EM>. <EM>cipher-name</EM> must have a <A HREF="#block-length" STYLE="symbol">block-length</A>
+of either 8 or 16; this restriction is satisfied by most ciphers in
+Ironclad with the notable exception of stream ciphers. <EM>key</EM> must
+be an acceptable key for <EM>cipher-name</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="update-cmac"></A><TT><STRONG>update-cmac</STRONG> <EM>cmac</EM> <EM>sequence</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>cmac</EM></TT><BR /></DIV><P>Update the internal state of <EM>cmac</EM> with the data in <EM>sequence</EM> bounded by <EM>start</EM> and <EM>end</EM>. <EM>sequence</EM> must
+be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*))</TT>.</P><DIV CLASS="lisp-symbol"><A NAME="cmac-digest"></A><TT><STRONG>cmac-digest</STRONG> <EM>cmac</EM> =&gt; <EM>digest</EM></TT><BR /></DIV><P>Returns the MAC (<EM>digest</EM>) computed by <EM>cmac</EM> thus far.
+The internal state of <EM>cmac</EM> is not modified; this feature makes it
+possible to compute a "rolling MAC" of a document. The length of <EM>digest</EM> is determined by the <A HREF="#block-length" STYLE="symbol">block-length</A> of <EM>cipher-name</EM>
+passed to <A HREF="#make-cmac" STYLE="symbol">make-cmac</A> when <EM>cmac</EM> was constructed.</P><H2 ID="public-key">Public-key Operations</H2><P>Ironclad includes support for DSA signing and verification.
+Support for RSA encryption and decryption is provided as well, but it is
+"raw"--the various formatting schemes (e.g. PKCS-1) must be implemented
+by the user at this time.</P><H3>Key construction</H3><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>public-key</EM></TT><BR /></DIV><P>Return a public key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-public-key"></A><TT><STRONG>make-public-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA public key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, and <EM>y</EM>
+are the usual parameters for DSA keys discussed in the literature.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>kind</EM> <EM><TT>&key</TT></EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a private key according to <EM>kind</EM>. The <EM>&key</EM>
+arguments vary according to <EM>kind</EM>. The interesting bits are in the
+methods that specialize on <EM>kind</EM>, below.</P><DIV CLASS="lisp-symbol"><A NAME="make-private-key"></A><TT><STRONG>make-private-key</STRONG> <EM>(kind (eql :dsa))</EM> <EM><TT>&key</TT></EM> <EM>p</EM> <EM>q</EM> <EM>g</EM> <EM>y</EM> <EM>x</EM> <EM><TT>&allow-other-keys</TT></EM> =&gt; <EM>private-key</EM></TT><BR /></DIV><P>Return a DSA private key. <EM>p</EM>, <EM>q</EM>, <EM>g</EM>, <EM>y</EM>, and
+<EM>x</EM> are the usual parameters for DSA keys discussed in the
+literature.</P><H3>Digital signatures</H3><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Return a signature of <EM>message</EM> between <EM>start</EM> and <EM>end</EM> signed with <EM>key</EM>; the class of <EM>key</EM> determines the class of
+<EM>signature</EM>.</P><DIV CLASS="lisp-symbol"><A NAME="sign-message"></A><TT><STRONG>sign-message</STRONG> <EM>(key dsa-private-key)</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>This method places an additional constraint on the size of <EM>message</EM> specified by <EM>start</EM> and <EM>end</EM>: it must be exactly
+20 bytes long (the length of a SHA-1 digest). <EM>signature</EM> is a <A HREF="#dsa-signature" STYLE="symbol">dsa-signature</A> object.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>key</EM> <EM>message</EM> <EM>signature</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><P>Verify whether <EM>signature</EM> is the signature of <EM>message</EM>
+between <EM>start</EM> and <EM>end</EM> using <EM>key</EM>. Return T or NIL
+depending on the result of verification.</P><DIV CLASS="lisp-symbol"><A NAME="verify-signature"></A><TT><STRONG>verify-signature</STRONG> <EM>(key dsa-public-key)</EM> <EM>message</EM> <EM>(signature dsa-signature)</EM> <EM><TT>&key</TT></EM> <EM>(start 0)</EM> <EM>end</EM> =&gt; <EM>boolean</EM></TT><BR /></DIV><H4>Signature objects</H4><P>There is no one "right" way to format signatures into octet
+vectors; different applications may have different requirements. <A HREF="#sign-message" STYLE="symbol">sign-message</A> therefore returns objects and lets the user determine
+how to best format the values contained therein.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature"></A><TT><STRONG>dsa-signature</STRONG></TT><BR /></DIV><P>A DSA signature object.</P><DIV CLASS="lisp-symbol"><A NAME="make-dsa-signature"></A><TT><STRONG>make-dsa-signature</STRONG> <EM>r</EM> <EM>s</EM> =&gt; <EM>signature</EM></TT><BR /></DIV><P>Returns a DSA signature with the provided <EM>r</EM> and <EM>s</EM>
+values. <EM>r</EM> and <EM>s</EM> may be either integers or they may be
+20-byte octet vectors.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-r"></A><TT><STRONG>dsa-signature-r</STRONG> <EM>object</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>r</EM> value of the provided DSA signature.</P><DIV CLASS="lisp-symbol"><A NAME="dsa-signature-s"></A><TT><STRONG>dsa-signature-s</STRONG> <EM>object</EM> =&gt; <EM>integer</EM></TT><BR /></DIV><P>Returns the <EM>s</EM> value of the provided DSA signature.</P><H3>Encryption and decryption</H3><DIV CLASS="lisp-symbol"><A NAME="encrypt-message"></A><TT><STRONG>encrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>end</EM> <EM>start</EM> =&gt; <EM>encrypted-message</EM></TT><BR /></DIV><DIV CLASS="lisp-symbol"><A NAME="decrypt-message"></A><TT><STRONG>decrypt-message</STRONG> <EM>key</EM> <EM>message</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>start</EM> =&gt; <EM>decrypted-message</EM></TT><BR /></DIV><H2 ID="gray-streams">Gray Streams</H2><P>Ironclad includes support for several convenient stream
+abstractions based on Gray streams. Gray streams support in Ironclad is
+included for SBCL, CMUCL, OpenMCL, Lispworks, and Allegro.</P><H3>Octet streams</H3><P>Octet streams are very similar to Common Lisp's <A HREF="#string-stream" STYLE="symbol">string-stream</A>,
+except they deal in octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-input-stream"></A><TT><STRONG>make-octet-input-stream</STRONG> <EM>buffer</EM> <EM><TT>&optional</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>octet-input-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-input-stream" STYLE="symbol">make-string-input-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="make-octet-output-stream"></A><TT><STRONG>make-octet-output-stream</STRONG> =&gt; <EM>octet-output-stream</EM></TT><BR /></DIV><P>As <A HREF="#make-string-output-stream" STYLE="symbol">make-string-output-stream</A>, only with octets instead of characters.</P><DIV CLASS="lisp-symbol"><A NAME="get-output-stream-octets"></A><TT><STRONG>get-output-stream-octets</STRONG> <EM>stream</EM> =&gt; <EM>octet-vector</EM></TT><BR /></DIV><P>As <A HREF="#get-output-stream-string" STYLE="symbol">get-output-stream-string</A>, only with an octet output-steam
+instead of a string output-stream.</P><H3>Digest streams</H3><P>Digest streams compute a digest of the data written to them
+according to a specific digest algorithm.</P><P>Example:</P><PRE>(defun frobbing-function (stream)
+ ;; We want to compute a digest of the data being written to STREAM
+ ;; without involving our callees in the process.
+ (let* ((digesting-stream (crypto:make-digesting-stream :sha1))
+ (stream (make-broadcast-stream stream digesting-stream)))
+ ;; Feed data to STREAM.
+ (frob-guts stream)
+ ;; Do something with the digest computed.
+ (... (crypto:produce-digest digesting-stream) ...)
+ ...))</PRE><DIV CLASS="lisp-symbol"><A NAME="make-digesting-stream"></A><TT><STRONG>make-digesting-stream</STRONG> <EM>digest</EM> =&gt; <EM>stream</EM></TT><BR /></DIV><P>Make a stream that computes a digest of the data written to it
+according to the algorithm <EM>digest-name</EM>. <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> may
+be used to obtain a digest of all the data written to the stream.</P><TABLE CLASS="note"><TR><TD CLASS="title">Note</TD><TD CLASS="content">Calling <A HREF="#produce-digest" STYLE="symbol">produce-digest</A> on a digest stream does not alter
+the internal state of the digest.</TD></TR></TABLE><H2>Utility Functions</H2><DIV CLASS="lisp-symbol"><A NAME="ub16ref/le"></A><TT><STRONG>ub16ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/le"></A><TT><STRONG>ub32ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/le"></A><TT><STRONG>ub64ref/le</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>This family of functions accesses an unsigned 16-bit, 32-bit or
+64-bit value stored in little-endian order starting at <EM>index</EM> in <EM>array</EM>. <EM>array</EM> must be a <TT>(SIMPLE-ARRAY (UNSIGNED-BYTE 8)
+(*))</TT>. These functions are SETFable.</P><DIV CLASS="lisp-symbol"><A NAME="ub16ref/be"></A><TT><STRONG>ub16ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub32ref/be"></A><TT><STRONG>ub32ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /><A NAME="ub64ref/be"></A><TT><STRONG>ub64ref/be</STRONG> <EM>buffer</EM> <EM>index</EM> =&gt; <EM>value</EM></TT><BR /></DIV><P>As the above, only the value is stored in big-endian order.</P><DIV CLASS="lisp-symbol"><A NAME="byte-array-to-hex-string"></A><TT><STRONG>byte-array-to-hex-string</STRONG> <EM>vector</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>element-type</EM> =&gt; <EM>string</EM></TT><BR /><A NAME="ascii-string-to-byte-array"></A><TT><STRONG>ascii-string-to-byte-array</STRONG> <EM>string</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>byte-array-to-hex-string</TT> converts the bytes of <EM>vector</EM>
+between <EM>start</EM> and <EM>end</EM> into a hexadecimal string. It is
+useful for converting digests to a more readable form. <EM>element-type</EM> indicates the element-type of the returned string.</P><P><TT>ascii-string-to-byte-array</TT> is provided as a quick and dirty way
+to convert a string to a byte array suitable for feeding to <A HREF="#update-digest" STYLE="symbol">update-digest</A> or <A HREF="#encrypt" STYLE="symbol">encrypt</A>. Care should be taken to ensure that
+the provided string is actually an ASCII string. <EM>start</EM> and <EM>end</EM> have their usual interpretations.</P><DIV CLASS="lisp-symbol"><A NAME="octets-to-integer"></A><TT><STRONG>octets-to-integer</STRONG> <EM>octet-vec</EM> <EM><TT>&key</TT></EM> <EM>start</EM> <EM>end</EM> <EM>big-endian</EM> <EM>n-bits</EM> =&gt; <EM>number</EM></TT><BR /><A NAME="integer-to-octets"></A><TT><STRONG>integer-to-octets</STRONG> <EM>bignum</EM> <EM><TT>&key</TT></EM> <EM>n-bits</EM> <EM>big-endian</EM> =&gt; <EM>vector</EM></TT><BR /></DIV><P><TT>octets-to-integer</TT> converts the bytes of <EM>octet-vec</EM> between
+<EM>start</EM> and <EM>end</EM> to an integer as though the bytes denoted a
+number in base 256. <EM>big-endian</EM> is a boolean indicating whether
+the bytes are to be read in big-endian or little-endian order. <EM>n-bits</EM> specifies how many bits should be considered as significant
+in the resulting number.</P><P><TT>integer-to-octets</TT> is the reverse operation.</P><DIV CLASS="lisp-symbol"><A NAME="expt-mod"></A><TT><STRONG>expt-mod</STRONG> =&gt; <EM>number</EM></TT><BR /></DIV><P>Raises <EM>n</EM> to the <EM>exponent</EM> power modulo <EM>modulus</EM> in
+a more efficient fashion than <TT>(MOD (EXPT N EXPONENT) MODULUS)</TT>.</P><H2>Conditions</H2><DIV CLASS="lisp-symbol"><A NAME="ironclad-error"></A><TT><STRONG>ironclad-error</STRONG></TT><BR /></DIV><P>All errors signaled by Ironclad are of this type. This type is a
+direct subtype of <TT>SIMPLE-ERROR</TT> without any extra slots or
+options.</P><DIV CLASS="lisp-symbol"><A NAME="initialization-vector-not-supplied"></A><TT><STRONG>initialization-vector-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled by <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> when an initialization
+vector is not provided and the requested mode requires an initialization
+vector.</P><DIV CLASS="lisp-symbol"><A NAME="invalid-initialization-vector"></A><TT><STRONG>invalid-initialization-vector</STRONG></TT><BR /></DIV><P>This error is signaled when an invalid initialization vector is
+supplied to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> (e.g. when the length of the initialization
+vector does not match the block length of the cipher).</P><DIV CLASS="lisp-symbol"><A NAME="invalid-key-length"></A><TT><STRONG>invalid-key-length</STRONG></TT><BR /></DIV><P>This error is signaled when the key provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is
+not of an acceptable length for the requested cipher.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-cipher"></A><TT><STRONG>unsupported-cipher</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>cipher-name</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#cipher-supported-p" STYLE="symbol">cipher-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-mode"></A><TT><STRONG>unsupported-mode</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>mode</EM> provided to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A> is not <A HREF="#mode-supported-p" STYLE="symbol">mode-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="unsupported-digest"></A><TT><STRONG>unsupported-digest</STRONG></TT><BR /></DIV><P>This error is signaled when the <EM>digest-name</EM> provided to <A HREF="#make-digest" STYLE="symbol">make-digest</A> is not <A HREF="#digest-supported-p" STYLE="symbol">digest-supported-p</A>.</P><DIV CLASS="lisp-symbol"><A NAME="insufficient-buffer-space"></A><TT><STRONG>insufficient-buffer-space</STRONG></TT><BR /></DIV><P>This error is signaled when Ironclad needs to stuff some data into a
+buffer (e.g. when the user provides <EM>digest</EM> to <A HREF="#produce-digest" STYLE="symbol">produce-digest</A>) and
+there is insufficient space.</P><DIV CLASS="lisp-symbol"><A NAME="key-not-supplied"></A><TT><STRONG>key-not-supplied</STRONG></TT><BR /></DIV><P>This error is signaled when a <TT>:KEY</TT> argument is not provided
+to <A HREF="#make-cipher" STYLE="symbol">make-cipher</A>.</P></BODY></HTML> \ No newline at end of file
diff --git a/doc/style.css b/doc/style.css
new file mode 100644
index 0000000..df9513d
--- /dev/null
+++ b/doc/style.css
@@ -0,0 +1,77 @@
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+pre {
+ padding: 0;
+ margin: 0;
+}
+
+h1, h2 {
+ border-bottom: 2px solid #449977;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: sans-serif;
+ line-height: 1.3;
+}
+
+a:link {
+ color: #449977;
+}
+
+a:visited {
+ color: purple;
+}
+
+a {
+ text-decoration: none;
+ padding: 1px 2px;
+}
+
+a:hover {
+ text-decoration: none;
+ padding: 1px;
+ border: 1px solid #000000;
+}
+
+.lisp-symbol {
+ margin-right: 10%;
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+ border: 1px solid #449977;
+ background: #eeeeee;
+ padding: 0.5em;
+}
+
+.note {
+ margin-right: 10%;
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+
+td.content {
+ padding: 0;
+}
+
+td.title {
+ font-family: sans-serif;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-align: left;
+ vertical-align: top;
+ text-decoration: underline;
+ padding-right: 0.5em;
+ margin-top: 0.0em;
+ margin-bottom: 0.5em;
+}
+
+.note td.content {
+ padding-left: 0.5em;
+ border-left: 2px solid #449977;
+}