From van-bc!vanbc.wimsey.com!cs.ubc.ca!uw-beaver!netnews.nwnet.net!usenet.coe.montana.edu!saimiri.primate.wisc.edu!sdd.hp.com!math.ohio-state.edu!usc!rand.org!jim Wed Jun  2 12:29:00 PDT 1993
Article: 10401 of sci.crypt
Path: sqwest!van-bc!vanbc.wimsey.com!cs.ubc.ca!uw-beaver!netnews.nwnet.net!usenet.coe.montana.edu!saimiri.primate.wisc.edu!sdd.hp.com!math.ohio-state.edu!usc!rand.org!jim
From: jim@rand.org (Jim Gillogly)
Newsgroups: sci.crypt
Subject: Re: Secure Hash Standard Approved - FIPS 180
Message-ID: <16826@rand.org>
Date: 2 Jun 93 16:44:43 GMT
References: <5438.204.uupcb@ssr.com> <1ugu0q$s08@msuinfo.cl.msu.edu> <HANCHE.93Jun2111344@ptolemy.ams.sunysb.edu>
Sender: news@rand.org
Organization: Banzai Institute
Lines: 621
Nntp-Posting-Host: mycroft.rand.org

hanche@ams.sunysb.edu (Harald Hanche-Olsen) writes:
> (Mark Riordan) writes:
>> Peter Gutmann's C implementation is available on ripem.msu.edu.
>
>Is it exportable?  The site maintainers on ripem seem to think not, as
>they have not made it accessible to all:

Peter Gutmann's is certainly exportable, since he's from New Zealand.  It's
exportable in any case, since SHA is non-cryptographic and doesn't hide
information by itself.  Note, though, that Phil Karn and others have shown
how hash algorithms may be used as the core of cryptosystems.

I'm <so> confident that it's exportable from the US that I'll include my
own implementation here.  :)  After un-sharing and compiling it with

	cc -O -o sha sha.c

or however you'd like, you can test it against the three NIST appendix
values by uudecoding the files app.a.uue, app.b.uue and app.c.Z.uue.  Test
them in turn with

	sha -v app.a app.b
	zcat app.c.Z | sha

For reference, here's what NIST says the three examples should yield:

     A Message digest =  0164b8a9 14cd2a5e 74c4f7ff 082c4d97 f1edf880
     B Message digest =  d2516ee1 acfa5baf 33dfc1c4 71e43844 9ef134c8
     C Message digest =  3232affa 48628a26 653b5aaa 44541fd9 0d690603

This package may be used either as a stand-alone program or as a library
routine to hash memory blocks.

	Jim Gillogly
	12 Forelithe S.R. 1993, 16:29

----------------------- clip here ----------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Readme app.a.uue app.b.uue app.c.Z.uue sha.1 sha.c
#   sha_file.3
# Wrapped by jim@mycroft on Wed Jun  2 09:23:24 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Readme' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Readme'\"
else
echo shar: Extracting \"'Readme'\" \(1679 characters\)
sed "s/^X//" >'Readme' <<'END_OF_FILE'
X/* Implementation of NIST's Secure Hash Algorithm (FIPS 180)
X * Lightly bummed for execution efficiency.
X *
X * Jim Gillogly 3 May 1993
X *
X * Compile: cc -O -o sha sha.c
X *
X * To remove the test wrapper and use just the nist_hash() routine,
X * compile with -DONT_WRAP
X *
X * Usage: sha [-vt] [filename ...]
X *
X *      -v switch: output the filename as well
X *      -t switch: suppress spaces between 32-bit blocks
X *
X *      If no input files are specified, process standard input.
X *
X * Output: 40-hex-digit digest of each file specified (160 bits)
X *
X * Synopsis of the function calls:
X *
X *   sha_file(char *filename, unsigned long *buffer)
X *      Filename is a file to be opened and processed.
X *      buffer is a user-supplied array of 5 or more longs.
X *      The 5-word buffer is filled with 160 bits of non-terminated hash.
X *      Returns 0 if successful, non-zero if bad file.
X *
X *   void sha_stream(FILE *stream, unsigned long *buffer)
X *      Input is from already-opened stream, not file.
X *
X *   void sha_memory(char *mem, long length, unsigned long *buffer)
X *      Input is a memory block "length" bytes long.
X *
X * Caveat:
X *      Not tested for case that requires the high word of the length,
X *      which would be files larger than 1/2 gig or so.
X *
X * Limitation:
X *      sha_memory (the memory block function) will deal with blocks no longer
X *      than 4 gigabytes; for longer samples, the stream version will
X *      probably be most convenient (e.g. perl moby_data.pl | sha).
X *
X * Bugs:
X *      The standard is defined for bit strings; I assume bytes.
X *
X * Copyright 1993, Dr. James J. Gillogly
X * This code may be freely used in any application.
X */
END_OF_FILE
if test 1679 -ne `wc -c <'Readme'`; then
    echo shar: \"'Readme'\" unpacked with wrong size!
fi
# end of 'Readme'
fi
if test -f 'app.a.uue' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.a.uue'\"
else
echo shar: Extracting \"'app.a.uue'\" \(28 characters\)
sed "s/^X//" >'app.a.uue' <<'END_OF_FILE'
Xbegin 664 app.a
X#86)C
X 
Xend
END_OF_FILE
if test 28 -ne `wc -c <'app.a.uue'`; then
    echo shar: \"'app.a.uue'\" unpacked with wrong size!
fi
# end of 'app.a.uue'
fi
if test -f 'app.b.uue' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.b.uue'\"
else
echo shar: Extracting \"'app.b.uue'\" \(102 characters\)
sed "s/^X//" >'app.b.uue' <<'END_OF_FILE'
Xbegin 664 app.b
XM86)C9&)C9&5C9&5F9&5F9V5F9VAF9VAI9VAI:FAI:FMI:FML:FML;6ML;6YL
X+;6YO;6YO<&YO<'%F
X 
Xend
END_OF_FILE
if test 102 -ne `wc -c <'app.b.uue'`; then
    echo shar: \"'app.b.uue'\" unpacked with wrong size!
fi
# end of 'app.b.uue'
fi
if test -f 'app.c.Z.uue' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'app.c.Z.uue'\"
else
echo shar: Extracting \"'app.c.Z.uue'\" \(2534 characters\)
sed "s/^X//" >'app.c.Z.uue' <<'END_OF_FILE'
Xbegin 664 app.c.Z
XM'YV080(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
XMI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
XMJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
XMKMV[>//JW<NWK]^_@ ,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
XML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
XMN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
XMO?OW\./+GT^_OOW[^//KW\^_O___  8HX( $%FC@@0@FJ.""##;HX(,01BCA
XMA!16:.&%&&:HX88<=NCAAR"&*.*())9HXHDHIJCBBBRVZ.*+,,8HXXPTUFCC
XMC3CFJ...//;HXX] !BGDD$06:>212":IY)),-NGDDU!&*>645%9IY9589JGE
XMEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG
XMGX &*NB@A!9JZ*&()JKHHHPVZNBCD$8JZ:245FKII9AFJNFFG';JZ:>@ABKJ
XMJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP 8K[+#$%FOL
XML<@FJ^RRS#;K[+/01BOMM-16:^VUV&:K[;;<=NOMM^"&*^ZXY)9K[KGHIJON
XMNNRVZ^Z[\,8K[[STUFOOO?CFJ^^^_/;K[[\ !RSPP 07;/#!"">L\,(,-^SP
XMPQ!'+/'$%%=L\<489ZSQQAQW[/''((<L\L@DEVSRR2BGK/+*++?L\LLPQRSS
XMS#37;//-..>L\\X\]^SSST '+?301!=M]-%()ZWTTDPW[?334$<M]=145VWU
XMU5AGK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
XMWGSW[???@ <N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
XMYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_ !R_\
XM\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
XM^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P ,H  '2, "&O" "$R@
XM A?(P 8Z\($0C* $)TC!"EKP@AC,H 8WR,$.>O"#( RA"$=(PA*:\(0H3*$*
XM5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(= #*(0ATC$(AKQB$A,HA*7
XMR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV ,HQC'2,8RFO&,:$RC&M?(
XMQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@ RD( =)R$(:\I"(3*0B%\G(
XM1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
XMNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\ ,IC"'2<QB&O.8R$RF,I?)S&8Z
XM\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X RG.,=)SG*:\YSH3*<ZU\G.=KKS
XMG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\ #:A !TK0@AKTH A-J$(7RM"&.O2A
XM$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR -J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
XMC:E,9TK3FMKTICC-J4YWRM.>^O2G0 VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
XMJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK
XM7.=*U[K:]:YXS:M>]\K7OOKUKX -K& '2]C"&O:PB$VL8A?+V,8Z]K&0C:QD
XM)TO9REKVLIC-K&8WR]G.>O:SH VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG
XM2]O:VO:VN,VM;G?+V][Z]K? #:YPATO<XAKWN,A-KG*7R]SF.O>YT(VN=*=+
XMW>I:][K8S:YVM\O=[GKWN^ -KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO?
XM^MKWOOC-KW[WR]_^^O>_  ZP@ =,X (;^, (3K""%\S@!COXP1".L(0G3.$*
XM6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK;
XM^,8XSK&.=\SC'OOXQT .LI"'3.0B&_G(2$ZRDI?,Y"8[^<E0CK*4ITSE*EOY
XMREC.LI:WS.4N>_G+8 ZSF,=,YC*;^<QH3K.:U\SF-KOYS7".LYSG3.<ZV_G.
X4>,ZSGO?,YS[[^<^ #K2@!TUH> *;
X 
Xend
END_OF_FILE
if test 2534 -ne `wc -c <'app.c.Z.uue'`; then
    echo shar: \"'app.c.Z.uue'\" unpacked with wrong size!
fi
# end of 'app.c.Z.uue'
fi
if test -f 'sha.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sha.1'\"
else
echo shar: Extracting \"'sha.1'\" \(1172 characters\)
sed "s/^X//" >'sha.1' <<'END_OF_FILE'
X.TH SHA 1 "30 Apr 1993"
X.SH NAME
Xsha \- Secure Hash Algorithm
X.SH SYNOPSIS
X.B "sha [-vt] [\fIfilename\fB]..."
X.SH DESCRIPTION
X.I Sha
Xcalculates the NIST Secure Hash Algorithm defined in FIPS 180.
XFor each file in the list it
Xproduces 160 bits of hash, formatted as 40 hex digits.  The "-v" flag
Xcauses
X.I sha
Xto print the filename as well as the hash.  The "-t" flag suppresses
Xthe spaces between 32-bit groups.  If no file is specified, it processes
Xthe standard input.
X.PP
XNIST suggests using the Secure Hash Algorithm as a message digesting function,
Xproducing a message-dependent fixed-size block that may be securely signed
Xwith a digital signature system such as NIST's DSS.  Quoting from the
Xdraft standard, "The SHA is designed to have the following properties:
Xit is computationally infeasible to recover a message corresponding to
Xa given message digest, or to find two different messages which produce
Xthe same message digest."
X.PP
XIt may also be used as an ordinary file checksum.
X
X.SH "SEE ALSO"
Xsum(1), sha_file(3), FIPS 180
X
X.SH BUGS
XNIST defines SHA for arbitrary bit strings.  This implementation operates
Xonly at the byte level.
X
X.SH AUTHOR
XJim Gillogly
END_OF_FILE
if test 1172 -ne `wc -c <'sha.1'`; then
    echo shar: \"'sha.1'\" unpacked with wrong size!
fi
# end of 'sha.1'
fi
if test -f 'sha.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sha.c'\"
else
echo shar: Extracting \"'sha.c'\" \(8143 characters\)
sed "s/^X//" >'sha.c' <<'END_OF_FILE'
X/* Implementation of NIST's Secure Hash Algorithm (FIPS 180)
X * Lightly bummed for execution efficiency.
X *
X * Jim Gillogly 3 May 1993
X *
X * Compile: cc -O -o sha sha.c
X *
X * To remove the test wrapper and use just the nist_hash() routine,
X * compile with -DONT_WRAP
X *
X * Usage: sha [-vt] [filename ...]
X *
X *      -v switch: output the filename as well
X *      -t switch: suppress spaces between 32-bit blocks
X *
X *      If no input files are specified, process standard input.
X *
X * Output: 40-hex-digit digest of each file specified (160 bits)
X *
X * Synopsis of the function calls:
X *
X *   sha_file(char *filename, unsigned long *buffer)
X *      Filename is a file to be opened and processed.
X *      buffer is a user-supplied array of 5 or more longs.
X *      The 5-word buffer is filled with 160 bits of non-terminated hash.
X *      Returns 0 if successful, non-zero if bad file.
X *
X *   void sha_stream(FILE *stream, unsigned long *buffer)
X *      Input is from already-opened stream, not file.
X *
X *   void sha_memory(char *mem, long length, unsigned long *buffer)
X *      Input is a memory block "length" bytes long.
X *
X * Caveat:
X *      Not tested for case that requires the high word of the length,
X *      which would be files larger than 1/2 gig or so.
X *
X * Limitation:
X *      sha_memory (the memory block function) will deal with blocks no longer
X *      than 4 gigabytes; for longer samples, the stream version will
X *      probably be most convenient (e.g. perl moby_data.pl | sha).
X *
X * Bugs:
X *      The standard is defined for bit strings; I assume bytes.
X *
X * Copyright 1993, Dr. James J. Gillogly
X * This code may be freely used in any application.
X */
X
X#include <stdio.h>
X#include <memory.h>
X
X#define TRUE  1
X#define FALSE 0
X
X#define SUCCESS 0
X#define FAILURE -1
X
Xint sha_file();                         /* External entries */
Xvoid sha_stream(), sha_memory();
X
Xstatic void nist_guts();
X
X#ifndef ONT_WRAP        /* Using just the hash routine itself */
X
X#define HASH_SIZE 5     /* Produces 160-bit digest of the message */
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X    unsigned long hbuf[HASH_SIZE];
X    char *s;
X    int file_args = FALSE;  /* If no files, take it from stdin */
X    int verbose = FALSE;
X    int terse = FALSE;
X
X#ifdef MEMTEST
X    sha_memory("abc", 3l, hbuf);         /* NIST test value from appendix A */
X    if (verbose) printf("Memory:");
X    if (terse) printf("%08x%08x%08x%08x%08x\n",
X	hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X    else printf("%08x %08x %08x %08x %08x\n",
X	hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X#endif
X
X    for (++argv; --argc; ++argv)           /* March down the arg list */
X    {
X	if (**argv == '-')                 /* Process one or more flags */
X	    for (s = &(*argv)[1]; *s; s++) /* Obfuscated C contest entry */
X		switch(*s)
X		{
X		    case 'v': case 'V':
X			verbose = TRUE;
X			break;
X		    case 't': case 'T':
X			terse = TRUE;
X			break;
X		    default:
X			fprintf(stderr, "Unrecognized flag: %c\n", *s);
X			return FALSE;
X		}
X	else                            /* Process a file */
X	{
X	    if (verbose) printf("%s:", *argv);
X	    file_args = TRUE;           /* Whether or not we could read it */
X
X	    if (sha_file(*argv, hbuf) == FAILURE)
X		printf("Can't open file %s.\n", *argv);
X	    else
X		if (terse) printf("%08x%08x%08x%08x%08x\n",
X		    hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X		else printf("%08x %08x %08x %08x %08x\n",
X		    hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X	}
X    }
X    if (! file_args)    /* No file specified */
X    {
X	if (verbose) printf("%s:", *argv);
X	sha_stream(stdin, hbuf);
X
X	if (terse) printf("%08x%08x%08x%08x%08x\n",
X	    hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X	else printf("%08x %08x %08x %08x %08x\n",
X	    hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
X    }
X    return TRUE;
X}
X
X#endif ONT_WRAP
X
Xunion longbyte
X{
X    unsigned long W[80];        /* Process 16 32-bit words at a time */
X    char B[320];                /* But read them as bytes for counting */
X};
X
Xsha_file(filename, buffer)      /* Hash a file */
Xchar *filename;
Xunsigned long *buffer;
X{
X    FILE *infile;
X
X    if ((infile = fopen(filename, "rb")) == NULL)
X    {
X	int i;
X
X	for (i = 0; i < 5; i++)
X	    buffer[i] = 0xdeadbeef;
X	return FAILURE;
X    }
X    (void) sha_stream(infile, buffer);
X    fclose(infile);
X    return SUCCESS;
X}
X
Xvoid sha_memory(mem, length, buffer)    /* Hash a memory block */
Xchar *mem;
Xunsigned long length;
Xunsigned long *buffer;
X{
X    nist_guts(FALSE, (FILE *) NULL, mem, length, buffer);
X}
X
Xvoid sha_stream(stream, buffer)
XFILE *stream;
Xunsigned long *buffer;
X{
X    nist_guts(TRUE, stream, (char *) NULL, 0l, buffer);
X}
X
X#define f0(x,y,z) (z ^ (x & (y ^ z)))           /* Magic functions */
X#define f1(x,y,z) (x ^ y ^ z)
X#define f2(x,y,z) ((x & y) | (z & (x | y)))
X#define f3(x,y,z) (x ^ y ^ z)
X
X#define K0 0x5a827999                           /* Magic constants */
X#define K1 0x6ed9eba1
X#define K2 0x8f1bbcdc
X#define K3 0xca62c1d6
X
X#define S(n, X) ((X << n) | (X >> (32 - n)))    /* Barrel roll */
X
X#define r0(f, K) \
X    temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
X    E = D;  \
X    D = C;  \
X    C = S(30, B); \
X    B = A;  \
X    A = temp
X
X#define r1(f, K) \
X    temp = S(5, A) + f(B, C, D) + E + \
X	   (*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
X    E = D;  \
X    D = C;  \
X    C = S(30, B); \
X    B = A;  \
X    A = temp
X
Xstatic void nist_guts(file_flag, stream, mem, length, buf)
Xint file_flag;                  /* Input from memory, or from stream? */
XFILE *stream;
Xchar *mem;
Xunsigned long length;
Xunsigned long *buf;
X{
X    int i, nread, nbits;
X    union longbyte d;
X    unsigned long hi_length, lo_length;
X    int padded;
X    char *s;
X
X    register unsigned long *p0, *p1, *p2, *p3, *p4;
X    unsigned long A, B, C, D, E, temp;
X
X    unsigned long h0, h1, h2, h3, h4;
X
X    h0 = 0x67452301;                            /* Accumulators */
X    h1 = 0xefcdab89;
X    h2 = 0x98badcfe;
X    h3 = 0x10325476;
X    h4 = 0xc3d2e1f0;
X
X    padded = FALSE;
X    s = mem;
X    for (hi_length = lo_length = 0; ;)  /* Process 16 longs at a time */
X    {
X	if (file_flag)
X	{
X		nread = fread(d.B, 1, 64, stream);  /* Read as 64 bytes */
X	}
X	else
X	{
X		if (length < 64) nread = length;
X		else             nread = 64;
X		length -= nread;
X		memcpy(d.B, s, nread);
X		s += nread;
X	}
X	if (nread < 64)   /* Partial block? */
X	{
X		nbits = nread << 3;               /* Length: bits */
X		if ((lo_length += nbits) < nbits)
X			hi_length++;              /* 64-bit integer */
X
X		if (nread < 64 && ! padded)  /* Append a single bit */
X		{
X			d.B[nread++] = 0x80; /* Using up next byte */
X			padded = TRUE;       /* Single bit once */
X		}
X		for (i = nread; i < 64; i++) /* Pad with nulls */
X			d.B[i] = 0;
X		if (nread <= 56)   /* Room for length in this block */
X		{
X			d.W[14] = hi_length;
X			d.W[15] = lo_length;
X		}
X	}
X	else    /* Full block -- get efficient */
X	{
X		if ((lo_length += 512) < 512)
X			hi_length++;    /* 64-bit integer */
X	}
X
X	p0 = d.W;
X	A = h0; B = h1; C = h2; D = h3; E = h4;
X
X	r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
X	r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
X	r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
X	r0(f0,K0);
X
X	p1 = &d.W[13]; p2 = &d.W[8]; p3 = &d.W[2]; p4 = &d.W[0];
X
X		   r1(f0,K0); r1(f0,K0); r1(f0,K0); r1(f0,K0);
X	r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
X	r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
X	r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
X	r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
X	r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
X	r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
X	r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
X	r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
X	r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
X	r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
X	r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
X	r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
X
X	h0 += A; h1 += B; h2 += C; h3 += D; h4 += E;
X
X	if (nread <= 56) break; /* If it's greater, length in next block */
X    }
X    buf[0] = h0; buf[1] = h1; buf[2] = h2; buf[3] = h3; buf[4] = h4;
X}
END_OF_FILE
if test 8143 -ne `wc -c <'sha.c'`; then
    echo shar: \"'sha.c'\" unpacked with wrong size!
fi
# end of 'sha.c'
fi
if test -f 'sha_file.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sha_file.3'\"
else
echo shar: Extracting \"'sha_file.3'\" \(1774 characters\)
sed "s/^X//" >'sha_file.3' <<'END_OF_FILE'
X.TH SHA_FILE 3 "30 Apr 1993"
X.SH NAME
Xsha_file, sha_stream, sha_memory \- Secure Hash Algorithm
X.SH SYNOPSIS
X.B "sha_file(char *filename, unsigned long *hash)"
X.br
X.B "void sha_stream(FILE *stream, unsigned long *hash)"
X.br
X.B "void sha_memory(char *mem, long length, unsigned long *hash)"
X.SH DESCRIPTION
XThese functions calculate
Xthe NIST Secure Hash Algorithm defined in FIPS 180.
XIn each function the
X.I hash
Xpointer identifies a user-allocated array of
Xfive longs for the hash output, for a total of 160 bits.  The first argument
Xin
X.I sha_file()
Xis the name of the file to process.
XIt returns 0 if successful,
Xnon-zero if the file could not be opened.
XThe first argument of
X.I sha_stream()
Xis a previously-opened stream (e.g. stdin).
X.I sha_memory()
Xexpects a pointer to the block of memory to be hashed, and the length in
Xbytes of the block to be hashed.
X.PP
XNIST suggests using the Secure Hash Algorithm as a message digesting function,
Xproducing a message-dependent fixed-size block that may be securely signed
Xwith a digital signature system such as NIST's DSS.  Quoting from the
Xdraft standard, "The SHA is designed to have the following properties:
Xit is computationally infeasible to recover a message corresponding to
Xa given message digest, or to find two different messages which produce
Xthe same message digest."
X.PP
XIt may also be used as an ordinary file checksum.
X
X.SH LIMITATIONS
XThe
X.I sha_memory()
Xcall processes blocks only up to 4 gigabytes.  For longer samples, the stream
Xversion of
X.I sha (1)
Xwill probably be most convenient, e.g.:
X.br
X.sp
X.ti +8
Xperl moby_data.pl | sha
X
X.SH BUGS
XNIST defines SHA for arbitrary bit strings.  This implementation operates
Xonly at the byte level.
X
X.SH "SEE ALSO"
Xsum(1), sha(1), FIPS 180
X
X.SH AUTHOR
XJim Gillogly
END_OF_FILE
if test 1774 -ne `wc -c <'sha_file.3'`; then
    echo shar: \"'sha_file.3'\" unpacked with wrong size!
fi
# end of 'sha_file.3'
fi
echo shar: End of shell archive.
exit 0
----------------------- clip here ----------------------
-- 
	Jim Gillogly
	12 Forelithe S.R. 1993, 16:44


