CRYPT-SHA1(2)                                       CRYPT-SHA1(2)

     NAME
          crypt: sha1, sha224, sha256, sha384, sha512, md4, md5,
          hmac_sha1, hmac_md5 - cryptographic digests

     SYNOPSIS
          include "ipints.m";
          ipints := load IPints IPints->PATH;
          IPint: import ipints;

          include "crypt.m";
          crypt := load Crypt Crypt->PATH;

          DigestState: adt
          {
              # hidden state
              copy:   fn(d: self ref DigestState): ref DigestState;
          };

          sha1:   fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          sha224: fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          sha256: fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          sha384: fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          sha512: fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          md4:    fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;
          md5:    fn(buf: array of byte, n: int, digest: array of byte,
                        state: ref DigestState): ref DigestState;

          SHA1dlen, SHA224dlen, SHA256dlen, SHA384dlen, SHA512dlen, MD4dlen, MD5dlen: con ...;

          hmac_sha1: fn(buf: array of byte, n: int, key: array of byte,
                            digest: array of byte,
                            state: ref DigestState): ref DigestState;
          hmac_md5:  fn(buf: array of byte, n: int, key: array of byte,
                            digest: array of byte,
                            state: ref DigestState): ref DigestState;

     DESCRIPTION
          Sha1, sha224, sha256, sha384, sha512, md4 and md5 are cryp-
          tographically secure hash functions that produce output
          called a message digest.  Each function computes a hash of n
          bytes of the data in buf, using the named algorithm, and
          updates the current state. They can be called iteratively to
          form a single digest for many data blocks.  The state is
          kept in the DigestState value referenced by state between

     Page 1                       Plan 9             (printed 4/20/24)

     CRYPT-SHA1(2)                                       CRYPT-SHA1(2)

          calls.  State should be nil on the first call, and a newly
          allocated DigestState will be returned for use in subsequent
          calls.  On a call in which digest is not nil, the hash is
          completed and copied into the digest array.  Sha1 produces a
          20-byte hash (SHA1dlen), sha224 a 28-byte hash (SHA224dlen),
          sha256 a 32-byte hash (SHA256dlen), sha384 a 48-byte hash
          (SHA384dlen), sha256 a 64-byte hash (SHA512dlen), md4 and
          md5 a 16-byte one (MD4len and MD5len).

          Hmac_sha1 and hmac_md5 are keyed versions of the hashing
          functions, following Internet RFC2104.  The key must be pro-
          vided in each call, but otherwise the calling conventions
          are those of sha1.  The key must currently be no more than
          64 bytes.

          DigestState hides the state of partially completed hash
          functions during processing.  Its copy operation returns a
          reference to a new copy of a given state.

     EXAMPLES
          A program to read a file and hash it using SHA might contain
          the following inner loop:

               state: ref DigestState = nil;
               while((n := sys->read(fd, buf, len buf)) > 0)
                       state = kr->sha1(buf, n, nil, state);
               digest := array[kr->SHA1dlen] of byte;
               kr->sha1(buf, 0, digest, state);

     SOURCE
          /libinterp/crypt.c
          /libsec/port/hmac.c
          /libsec/port/md4.c
          /libsec/port/md5.c
          /libsec/port/sha1.c

     BUGS
          The MD4 algorithm is included only to allow communication
          with software that might still use it; it should not other-
          wise be used now, because it is easily broken.

     Page 2                       Plan 9             (printed 4/20/24)