--- /dev/null
+Cryptographic hash functions
+
+
+ Hash functions are very useful cryptographic primitives.
+ Catacomb provides a few of the best-known cryptographic hashes.
+
+
+Hash function interface
+
+ Hash functions share a regular interface. I'll take Ron
+ Rivest's MD5 as an example.
+
+ Using a hash function is a three-stage process. You initialize
+ a context, you hash some data, and you get the result out of the
+ end. The data to be hashed need not be contiguous, and you
+ don't have to have it all before you start. Hash function
+ contexts don't use up lots of memory.
+
+ An MD5 context is called `md5_ctx'. You initialize it with
+ `md5_init'. You hash a block of data using `md5_hash' giving it
+ the context, the pointer to the data and its length. Finally,
+ you extract the data using `md5_done', giving it the address of
+ a buffer of MD5_HASHSZ bytes for it to write the result.
+
+ There are some other standard operations as well, but they're
+ not often used: see the header files for details.
+
+ The hash functions supported are:
+
+ MD4 By Ron Rivest -- returns a 128-bit hash. MD4 is
+ not collision-resistant, and may not even be
+ second-preimage-resistant. Don't depend on its
+ security. On the other hand, MD4 is *very*
+ fast.
+
+ MD5 Also by Rivest, also returns a 128-bit hash.
+ MD5 is slower than MD4, and more conservative,
+ but there are still grave doubts about its
+ security.
+
+ SHA1 Designed by the US National Security Agency.
+ Returns a 160-bit hash. Slower than MD5. Looks
+ strong. Fixes a problem in the earlier SHA.
+
+ RIPEMD-160 Designed by the people who broke MD4 and MD5.
+ Returns a 160-bit hash. Slower than SHA1. My
+ personal preference.
+
+
+HMAC interface
+
+ It's possible to construct a `keyed hash' or `message
+ authentication code' from a hash function. Most methods for
+ doing this are insecure. HMAC is a good method, with rigorously
+ proven security properties.
+
+ Each hash function above has an HMAC mode defined for it. This
+ works much the same way as block cipher modes.
+
+ Using HMAC is a two-step process. First, you initialize a MAC
+ key block `mackey' to contain the key you'll use, and then you
+ initialize MAC contexts `macctx' which to actually hash the
+ data. Hashing works just the same as the basic hash function,
+ except that you use `macinit', `machash' and `macdone' functions
+ rather than the plain `init', `hash' and `done'.
+
+
+Generic interfaces
+
+ Generic interfaces to hash functions and MACs are provided. See
+ README.cipher to get an idea for how a similar generic interface
+ works -- I'll only explain the differences here.
+
+ The generic hash object, `ghash' contains an `ops' member
+ referring to:
+
+ h->ops->b->name The name of the hash function.
+
+ h->ops->b->hashsz The output size of the hash function.
+
+ h->ops->hash(h, p, sz) Hash sz bytes of data starting at
+ address p.
+
+ h->ops->done(h, b) Stop hashing, write the result to buffer
+ b with size `hashsz'.
+
+ h->ops->destroy(h) Destroy the generic hash object.
+
+ The generic hash class, `gchash', contains a base which has the
+ same members as `ops->b' above, and an `init' function which
+ takes no arguments and returns a pointer to a `ghash'.
+
+ There's a generic MAC interface too. A MAC class, `gcmac'
+ contains a hash base (exactly the same, but with a different
+ name), and a function `key' which takes a pointer to some key
+ data and the key size, and returns a pointer to a `generic mac'
+ object, `gmac'.
+
+ A `gmac' contains an `ops' member:
+
+ m->ops->b->name, m->ops->b->hashsz
+ As above.
+
+ m->ops->init(m) Returns a generic *hash* object to
+ actually compute a MAC over some data.
+
+ m->ops->destroy(m) Destroys the generic MAC block.
+
+
+ That was quite complex. Here's an example of using a generic
+ MAC.
+
+ void compute_mac(gcmac *gcm, const void *k, size_t ksz,
+ const void *p, size_t sz,
+ void *hash)
+ {
+ gmac *m = gcm->init(k, ksz);
+ ghash *h = m->ops->init(m);
+ m->ops->destroy(m);
+ h->ops->hash(h, p, sz);
+ h->ops->done(h, hash);
+ h->ops->destroy(h);
+ }
+
+ Note that the hash doesn't depend on the MAC object continuing
+ to exist.
+
+--
+[mdw]
+
+\f
+Local variables:
+mode: text
+End: