[BACK]Return to sha1.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / builtin

Annotation of OpenXM_contrib2/asir2000/builtin/sha1.c, Revision 1.1

1.1     ! noro        1: /* $OpenXM: OpenXM/src/asir99/builtin/sha1.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
        !             2: /* Implementation of NIST's Secure Hash Algorithm (FIPS 180)
        !             3: * Lightly bummed for execution efficiency.
        !             4: *
        !             5: * Jim Gillogly 3 May 1993
        !             6: *
        !             7: * 27 Aug 93: imported LITTLE_ENDIAN mods from Peter Gutmann's implementation
        !             8: * 5 Jul 94: Modified for NSA fix
        !             9: *
        !            10: * Compile: cc -O -o sha sha.c
        !            11: *
        !            12: * To remove the test wrapper and use just the nist_hash() routine,
        !            13: *      compile with -DONT_WRAP
        !            14: *
        !            15: * To reverse byte order for little-endian machines, use -DLITTLE_ENDIAN
        !            16: *
        !            17: * To get the original SHA definition before the 1994 fix, use -DVERSION_0
        !            18: *
        !            19: * Usage: sha [-vt] [filename ...]
        !            20: *
        !            21: *      -v switch: output the filename as well
        !            22: *      -t switch: suppress spaces between 32-bit blocks
        !            23: *
        !            24: *      If no input files are specified, process standard input.
        !            25: *
        !            26: * Output: 40-hex-digit digest of each file specified (160 bits)
        !            27: *
        !            28: * Synopsis of the function calls:
        !            29: *
        !            30: *   sha_file(char *filename, unsigned int *buffer)
        !            31: *      Filename is a file to be opened and processed.
        !            32: *      buffer is a user-supplied array of 5 or more ints.
        !            33: *      The 5-word buffer is filled with 160 bits of non-terminated hash.
        !            34: *      Returns 0 if successful, non-zero if bad file.
        !            35: *
        !            36: *   void sha_stream(FILE *stream, unsigned int *buffer)
        !            37: *      Input is from already-opened stream, not file.
        !            38: *
        !            39: *   void sha_memory(char *mem, int length, unsigned int *buffer)
        !            40: *      Input is a memory block "length" bytes int.
        !            41: *
        !            42: * Caveat:
        !            43: *      Not tested for case that requires the high word of the length,
        !            44: *      which would be files larger than 1/2 gig or so.
        !            45: *
        !            46: * Limitation:
        !            47: *      sha_memory (the memory block function) will deal with blocks no inter
        !            48: *      than 4 gigabytes; for inter samples, the stream version will
        !            49: *      probably be most convenient (e.g. perl moby_data.pl | sha).
        !            50: *
        !            51: * Bugs:
        !            52: *      The standard is defined for bit strings; I assume bytes.
        !            53: *
        !            54: * Copyright 1993, Dr. James J. Gillogly
        !            55: * This code may be freely used in any application.
        !            56: */
        !            57:
        !            58: #define ONT_WRAP    /* Using just the hash routine itself */
        !            59:
        !            60: /* #define VERSION_0 */  /* Define this to get the original SHA definition */
        !            61:
        !            62: #include <stdio.h>
        !            63: #include <memory.h>
        !            64:
        !            65: #define VERBOSE
        !            66:
        !            67: #define TRUE  1
        !            68: #define FALSE 0
        !            69:
        !            70: #define SUCCESS 0
        !            71: #define FAILURE -1
        !            72:
        !            73: int sha_file(char* filename, unsigned int *buffer);
        !            74: void sha_stream(FILE *stream, unsigned int *buffer);
        !            75: void sha_memory(char *mem, unsigned int length, unsigned int *buffer);
        !            76:
        !            77: static void nist_guts(int file_flag, /* Input from memory, or from stream? */
        !            78:             FILE *stream,
        !            79:             char *mem,
        !            80:             unsigned int length,
        !            81:             unsigned int *buf);
        !            82:
        !            83: #ifndef ONT_WRAP    /* Using just the hash routine itself */
        !            84:
        !            85: #define HASH_SIZE 5   /* Produces 160-bit digest of the message */
        !            86:
        !            87: int main(int argc, char **argv)
        !            88: {
        !            89:   unsigned int hbuf[HASH_SIZE];
        !            90:   char *s;
        !            91:   int file_args = FALSE;  /* If no files, take it from stdin */
        !            92:   int verbose = FALSE;
        !            93:   int terse = FALSE;
        !            94:
        !            95: #ifdef MEMTEST
        !            96:   sha_memory("abc", 3l, hbuf);     /* NIST test value from appendix A */
        !            97:   if (verbose) printf("Memory:");
        !            98:   if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
        !            99:     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           100:   else printf("%08lx %08lx %08lx %08lx %08lx\n",
        !           101:     hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           102: #endif
        !           103:
        !           104:   for (++argv; --argc; ++argv)       /* March down the arg list */
        !           105:     {
        !           106:       if (**argv == '-')         /* Process one or more flags */
        !           107:         for (s = &(*argv)[1]; *s; s++) /* Obfuscated C contest entry */
        !           108:           switch(*s)
        !           109:             {
        !           110:               case 'v': case 'V':
        !           111:                 verbose = TRUE;
        !           112:                 break;
        !           113:               case 't': case 'T':
        !           114:                 terse = TRUE;
        !           115:                 break;
        !           116:               default:
        !           117:                 fprintf(stderr, "Unrecognized flag: %c\n", *s);
        !           118:                 return FALSE;
        !           119:             }
        !           120:       else              /* Process a file */
        !           121:         {
        !           122:           if (verbose) printf("%s:", *argv);
        !           123:           file_args = TRUE;       /* Whether or not we could read it */
        !           124:
        !           125:           if (sha_file(*argv, hbuf) == FAILURE)
        !           126:             printf("Can't open file %s.\n", *argv);
        !           127:           else
        !           128:             if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
        !           129:               hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           130:             else printf("%08lx %08lx %08lx %08lx %08lx\n",
        !           131:               hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           132:         }
        !           133:     }
        !           134:   if (! file_args)  /* No file specified */
        !           135:     {
        !           136:       if (verbose) printf("%s:", *argv);
        !           137:       sha_stream(stdin, hbuf);
        !           138:
        !           139:       if (terse) printf("%08lx%08lx%08lx%08lx%08lx\n",
        !           140:         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           141:       else printf("%08lx %08lx %08lx %08lx %08lx\n",
        !           142:         hbuf[0], hbuf[1], hbuf[2], hbuf[3], hbuf[4]);
        !           143:     }
        !           144:   return TRUE;
        !           145: }
        !           146:
        !           147: #endif ONT_WRAP
        !           148:
        !           149: /* #ifdef LITTLE_ENDIAN */ /* Imported from Peter Gutmann's implementation */
        !           150:
        !           151: /* When run on a little-endian CPU we need to perform byte reversal on an
        !           152:   array of intwords.  It is possible to make the code endianness-
        !           153:   independant by fiddling around with data at the byte level, but this
        !           154:   makes for very slow code, so we rely on the user to sort out endianness
        !           155:   at compile time */
        !           156:
        !           157: static void byteReverse( unsigned int *buffer, int byteCount )
        !           158: {
        !           159:   unsigned int value;
        !           160:   int count;
        !           161:   extern int little_endian;
        !           162:
        !           163:   if ( !little_endian )
        !           164:        return;
        !           165:
        !           166:   byteCount /= sizeof( unsigned int );
        !           167:   for( count = 0; count < byteCount; count++ )
        !           168:     {
        !           169:       value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 );
        !           170:       buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
        !           171:     }
        !           172: }
        !           173: /* #endif */ /* LITTLE_ENDIAN */
        !           174:
        !           175: union intbyte
        !           176: {
        !           177:   unsigned int W[80];    /* Process 16 32-bit words at a time */
        !           178:   char B[320];        /* But read them as bytes for counting */
        !           179: };
        !           180:
        !           181: int sha_file(char* filename, unsigned int *buffer)    /* Hash a file */
        !           182: {
        !           183:   FILE *infile;
        !           184:
        !           185:   if ((infile = fopen(filename, "rb")) == NULL)
        !           186:     {
        !           187:       int i;
        !           188:
        !           189:       for (i = 0; i < 5; i++)
        !           190:         buffer[i] = 0xdeadbeef;
        !           191:       return FAILURE;
        !           192:     }
        !           193:   (void) sha_stream(infile, buffer);
        !           194:   fclose(infile);
        !           195:   return SUCCESS;
        !           196: }
        !           197:
        !           198: void sha_memory(char *mem, unsigned int length, unsigned int *buffer)
        !           199: {
        !           200:   nist_guts(FALSE, (FILE *) NULL, mem, length, buffer);
        !           201: }
        !           202:
        !           203: void sha_stream(FILE *stream, unsigned int *buffer)
        !           204: {
        !           205:   nist_guts(TRUE, stream, (char *) NULL, 0l, buffer);
        !           206: }
        !           207:
        !           208: #define f0(x,y,z) (z ^ (x & (y ^ z)))       /* Magic functions */
        !           209: #define f1(x,y,z) (x ^ y ^ z)
        !           210: #define f2(x,y,z) ((x & y) | (z & (x | y)))
        !           211: #define f3(x,y,z) (x ^ y ^ z)
        !           212:
        !           213: #define K0 0x5a827999               /* Magic constants */
        !           214: #define K1 0x6ed9eba1
        !           215: #define K2 0x8f1bbcdc
        !           216: #define K3 0xca62c1d6
        !           217:
        !           218: #define S(n, X) ((X << n) | (X >> (32 - n)))  /* Barrel roll */
        !           219:
        !           220: #define r0(f, K) \
        !           221:   temp = S(5, A) + f(B, C, D) + E + *p0++ + K; \
        !           222:   E = D;  \
        !           223:   D = C;  \
        !           224:   C = S(30, B); \
        !           225:   B = A;  \
        !           226:   A = temp
        !           227:
        !           228: #ifdef VERSION_0
        !           229: #define r1(f, K) \
        !           230:   temp = S(5, A) + f(B, C, D) + E + \
        !           231:       (*p0++ = *p1++ ^ *p2++ ^ *p3++ ^ *p4++) + K; \
        !           232:   E = D;  \
        !           233:   D = C;  \
        !           234:   C = S(30, B); \
        !           235:   B = A;  \
        !           236:   A = temp
        !           237: #else           /* Version 1: Summer '94 update */
        !           238: #define r1(f, K) \
        !           239:   temp = *p1++ ^ *p2++ ^ *p3++ ^ *p4++; \
        !           240:   temp = S(5, A) + f(B, C, D) + E + (*p0++ = S(1,temp)) + K; \
        !           241:   E = D;  \
        !           242:   D = C;  \
        !           243:   C = S(30, B); \
        !           244:   B = A;  \
        !           245:   A = temp
        !           246: #endif
        !           247:
        !           248: static void nist_guts(int file_flag, /* Input from memory, or from stream? */
        !           249:             FILE *stream,
        !           250:             char *mem,
        !           251:             unsigned int length,
        !           252:             unsigned int *buf)
        !           253: {
        !           254:   int i, nread, nbits;
        !           255:   union intbyte d;
        !           256:   unsigned int hi_length, lo_length;
        !           257:   int padded;
        !           258:   char *s;
        !           259:
        !           260:   register unsigned int *p0, *p1, *p2, *p3, *p4;
        !           261:   unsigned int A, B, C, D, E, temp;
        !           262:
        !           263:   unsigned int h0, h1, h2, h3, h4;
        !           264:
        !           265:   h0 = 0x67452301;              /* Accumulators */
        !           266:   h1 = 0xefcdab89;
        !           267:   h2 = 0x98badcfe;
        !           268:   h3 = 0x10325476;
        !           269:   h4 = 0xc3d2e1f0;
        !           270:
        !           271:   padded = FALSE;
        !           272:   s = mem;
        !           273:   for (hi_length = lo_length = 0; ;)  /* Process 16 ints at a time */
        !           274:     {
        !           275:       if (file_flag)
        !           276:         {
        !           277:           nread = fread(d.B, 1, 64, stream);  /* Read as 64 bytes */
        !           278:         }
        !           279:       else
        !           280:         {
        !           281:           if (length < 64) nread = length;
        !           282:           else       nread = 64;
        !           283:           length -= nread;
        !           284:           memcpy(d.B, s, nread);
        !           285:           s += nread;
        !           286:         }
        !           287:       if (nread < 64)   /* Partial block? */
        !           288:         {
        !           289:           nbits = nread << 3;         /* Length: bits */
        !           290:           if ((lo_length += nbits) < nbits)
        !           291:             hi_length++;        /* 64-bit integer */
        !           292:
        !           293:           if (nread < 64 && ! padded)  /* Append a single bit */
        !           294:             {
        !           295:               d.B[nread++] = 0x80; /* Using up next byte */
        !           296:               padded = TRUE;     /* Single bit once */
        !           297:             }
        !           298:           for (i = nread; i < 64; i++) /* Pad with nulls */
        !           299:             d.B[i] = 0;
        !           300:           if (nread <= 56)   /* Room for length in this block */
        !           301:             {
        !           302:               d.W[14] = hi_length;
        !           303:               d.W[15] = lo_length;
        !           304: /* #ifdef LITTLE_ENDIAN */
        !           305:               byteReverse(d.W, 56 );
        !           306: /* #endif */ /* LITTLE_ENDIAN */
        !           307:             }
        !           308: /* #ifdef LITTLE_ENDIAN */
        !           309:           else
        !           310:             byteReverse(d.W, 64 );
        !           311: /* #endif */ /* LITTLE_ENDIAN */
        !           312:         }
        !           313:       else  /* Full block -- get efficient */
        !           314:         {
        !           315:           if ((lo_length += 512) < 512)
        !           316:             hi_length++;  /* 64-bit integer */
        !           317: /* #ifdef LITTLE_ENDIAN */
        !           318:           byteReverse(d.W, 64 );
        !           319: /* #endif */ /* LITTLE_ENDIAN */
        !           320:         }
        !           321:
        !           322:       p0 = d.W;
        !           323:       A = h0; B = h1; C = h2; D = h3; E = h4;
        !           324:
        !           325:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
        !           326:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
        !           327:       r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0); r0(f0,K0);
        !           328:       r0(f0,K0);
        !           329:
        !           330:       p1 = &d.W[13]; p2 = &d.W[8]; p3 = &d.W[2]; p4 = &d.W[0];
        !           331:
        !           332:       r1(f0,K0); r1(f0,K0); r1(f0,K0); r1(f0,K0);
        !           333:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
        !           334:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
        !           335:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
        !           336:       r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1); r1(f1,K1);
        !           337:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
        !           338:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
        !           339:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
        !           340:       r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2); r1(f2,K2);
        !           341:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
        !           342:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
        !           343:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
        !           344:       r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3); r1(f3,K3);
        !           345:
        !           346:       h0 += A; h1 += B; h2 += C; h3 += D; h4 += E;
        !           347:
        !           348:       if (nread <= 56) break; /* If it's greater, length in next block */
        !           349:     }
        !           350:   buf[0] = h0; buf[1] = h1; buf[2] = h2; buf[3] = h3; buf[4] = h4;
        !           351: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>