Annotation of pgp/src/md4.c, revision 1.1.1.1

1.1       root        1: /*
                      2: ** **************************************************************************
                      3: ** md4.c -- Implementation of MD4 Message Digest Algorithm                 **
                      4: ** Updated: 2/16/90 by Ronald L. Rivest                                    **
                      5: ** (C) 1990 RSA Data Security, Inc.                                        **
                      6: ** Adapted for short-word machines on 90.08.02 by Peter Pearson            **
                      7: ** **************************************************************************
                      8: */
                      9: 
                     10: /*
                     11: License to copy and use this software is granted provided it is 
                     12: identified as the "RSA Data Security, Inc. MD4 Message Digest 
                     13: Algorithm" in all materials mentioning or referencing this software, 
                     14: function, or document.
                     15: 
                     16: License is also granted to make derivative works provided that such
                     17: works are identified as "derived from the RSA Data Security, Inc. MD4
                     18: Message Digest Algorithm" in all material mentioning or referencing
                     19: the derived work.
                     20: 
                     21: RSA Data Security, Inc. makes no representations concerning the
                     22: merchantability of this algorithm or software or their suitability
                     23: for any specific purpose.  It is provided "as is" without express or
                     24: implied warranty of any kind.
                     25: 
                     26: These notices must be retained in any copies of any part of this
                     27: documentation and/or software.
                     28: */
                     29: 
                     30: /* 
                     31: ** To use MD4:
                     32: **   -- Include md4.h in your program
                     33: **   -- Declare an MDstruct MD to hold the state of the digest computation.
                     34: **   -- Initialize MD using MDbegin(&MD)
                     35: **   -- For each full block (64 bytes) X you wish to process, call
                     36: **          MDupdate(&MD,X,512)
                     37: **      (512 is the number of bits in a full block.)
                     38: **   -- For the last block (less than 64 bytes) you wish to process,
                     39: **          MDupdate(&MD,X,n)
                     40: **      where n is the number of bits in the partial block. A partial
                     41: **      block terminates the computation, so every MD computation should
                     42: **      terminate by processing a partial block, even if it has n = 0.
                     43: **   -- The message digest is available in MD.buffer[0] ... MD.buffer[3].
                     44: **      (Least-significant byte of each word should be output first.)
                     45: **   -- You can print out the digest using MDprint(&MD)
                     46: */
                     47: 
                     48: /* Implementation notes:
                     49: ** If the machine stores the least-significant byte of an int in the
                     50: ** least-addressed byte (eg., VAX and 8086), then LOWBYTEFIRST should be
                     51: ** set to TRUE.  Otherwise (eg., SUNS), LOWBYTEFIRST should be set to
                     52: ** FALSE.  Note that on machines with LOWBYTEFIRST FALSE the routine
                     53: ** MDupdate modifies has a side-effect on its input array (the order of bytes
                     54: ** in each word are reversed).  If this is undesired a call to MDreverse(X) can
                     55: ** reverse the bytes of X back into order after each call to MDupdate.
                     56: */
                     57: #define TRUE  1
                     58: #define FALSE 0
                     59: #define LOWBYTEFIRST TRUE
                     60: 
                     61: /* Compile-time includes 
                     62: */
                     63: #include <stdio.h>
                     64: #include "md4.h"
                     65: 
                     66: /* Compile-time declarations of MD4 ``magic constants''.
                     67: */
                     68: #define I0  0x67452301L       /* Initial values for MD buffer */
                     69: #define I1  0xefcdab89L
                     70: #define I2  0x98badcfeL
                     71: #define I3  0x10325476L
                     72: #define C2  013240474631L     /* round 2 constant = sqrt(2) in octal */
                     73: #define C3  015666365641L     /* round 3 constant = sqrt(3) in octal */
                     74: /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
                     75: ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
                     76: ** Table 2, page 660.
                     77: */
                     78: #define fs1  3               /* round 1 shift amounts */
                     79: #define fs2  7   
                     80: #define fs3 11  
                     81: #define fs4 19  
                     82: #define gs1  3               /* round 2 shift amounts */
                     83: #define gs2  5   
                     84: #define gs3  9   
                     85: #define gs4 13  
                     86: #define hs1  3               /* round 3 shift amounts */
                     87: #define hs2  9 
                     88: #define hs3 11 
                     89: #define hs4 15
                     90: 
                     91: 
                     92: /* Compile-time macro declarations for MD4.
                     93: ** Note: The ``rot'' operator uses the variable ``tmp''.
                     94: ** It assumes tmp is declared as unsigned int, so that the >>
                     95: ** operator will shift in zeros rather than extending the sign bit.
                     96: */
                     97: #define        f(X,Y,Z)             ((X&Y) | ((~X)&Z))
                     98: #define        g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
                     99: #define h(X,Y,Z)             (X^Y^Z)
                    100: #define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
                    101: #define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
                    102: #define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
                    103: #define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
                    104: 
                    105: /* MDprint(MDp)
                    106: ** Print message digest buffer MDp as 32 hexadecimal digits.
                    107: ** Order is from low-order byte of buffer[0] to high-order byte of buffer[3].
                    108: ** Each byte is printed with high-order hexadecimal digit first.
                    109: ** This is a user-callable routine.
                    110: */
                    111: void MDprint(MDptr MDp)
                    112: { int i,j;
                    113:   for (i=0;i<4;i++)
                    114:     for (j=0;j<32;j=j+8)
                    115:       printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
                    116: }
                    117: 
                    118: /* MDbegin(MDp)
                    119: ** Initialize message digest buffer MDp. 
                    120: ** This is a user-callable routine.
                    121: */
                    122: void MDbegin(MDptr MDp)
                    123: { int i;
                    124:   MDp->buffer[0] = I0;  
                    125:   MDp->buffer[1] = I1;  
                    126:   MDp->buffer[2] = I2;  
                    127:   MDp->buffer[3] = I3; 
                    128:   for (i=0;i<8;i++) MDp->count[i] = 0;
                    129:   MDp->done = 0;
                    130: }
                    131: 
                    132: /* MDreverse(X)
                    133: ** Reverse the byte-ordering of every int in X.
                    134: ** Assumes X is an array of 16 ints.
                    135: ** The macro revx reverses the byte-ordering of the next word of X.
                    136: */
                    137: #define revx { t = (*X << 16) | (*X >> 16); \
                    138:               *X++ = ((t & 0xFF00FF00L) >> 8) | ((t & 0x00FF00FFL) << 8); }
                    139: void MDreverse(Word32Type *X)
                    140: { register Word32Type t;
                    141:   revx; revx; revx; revx; revx; revx; revx; revx;
                    142:   revx; revx; revx; revx; revx; revx; revx; revx;
                    143: }
                    144: 
                    145: /* MDblock(MDp,X)
                    146: ** Update message digest buffer MDp->buffer using 16-word data block X.
                    147: ** Assumes all 16 words of X are full of data.
                    148: ** Does not update MDp->count.
                    149: ** This routine is not user-callable. 
                    150: */
                    151: static void MDblock(MDptr MDp, Word32Type *X)
                    152: { 
                    153:   register Word32Type tmp, A, B, C, D;
                    154: #if LOWBYTEFIRST == FALSE
                    155:   MDreverse(X);
                    156: #endif
                    157:   A = MDp->buffer[0];
                    158:   B = MDp->buffer[1];
                    159:   C = MDp->buffer[2];
                    160:   D = MDp->buffer[3];
                    161:   /* Update the message digest buffer */
                    162:   ff(A , B , C , D ,  0 , fs1); /* Round 1 */
                    163:   ff(D , A , B , C ,  1 , fs2); 
                    164:   ff(C , D , A , B ,  2 , fs3); 
                    165:   ff(B , C , D , A ,  3 , fs4); 
                    166:   ff(A , B , C , D ,  4 , fs1); 
                    167:   ff(D , A , B , C ,  5 , fs2); 
                    168:   ff(C , D , A , B ,  6 , fs3); 
                    169:   ff(B , C , D , A ,  7 , fs4); 
                    170:   ff(A , B , C , D ,  8 , fs1); 
                    171:   ff(D , A , B , C ,  9 , fs2); 
                    172:   ff(C , D , A , B , 10 , fs3); 
                    173:   ff(B , C , D , A , 11 , fs4); 
                    174:   ff(A , B , C , D , 12 , fs1); 
                    175:   ff(D , A , B , C , 13 , fs2); 
                    176:   ff(C , D , A , B , 14 , fs3); 
                    177:   ff(B , C , D , A , 15 , fs4); 
                    178:   gg(A , B , C , D ,  0 , gs1); /* Round 2 */
                    179:   gg(D , A , B , C ,  4 , gs2); 
                    180:   gg(C , D , A , B ,  8 , gs3); 
                    181:   gg(B , C , D , A , 12 , gs4); 
                    182:   gg(A , B , C , D ,  1 , gs1); 
                    183:   gg(D , A , B , C ,  5 , gs2); 
                    184:   gg(C , D , A , B ,  9 , gs3); 
                    185:   gg(B , C , D , A , 13 , gs4); 
                    186:   gg(A , B , C , D ,  2 , gs1); 
                    187:   gg(D , A , B , C ,  6 , gs2); 
                    188:   gg(C , D , A , B , 10 , gs3); 
                    189:   gg(B , C , D , A , 14 , gs4); 
                    190:   gg(A , B , C , D ,  3 , gs1); 
                    191:   gg(D , A , B , C ,  7 , gs2); 
                    192:   gg(C , D , A , B , 11 , gs3); 
                    193:   gg(B , C , D , A , 15 , gs4);  
                    194:   hh(A , B , C , D ,  0 , hs1); /* Round 3 */
                    195:   hh(D , A , B , C ,  8 , hs2); 
                    196:   hh(C , D , A , B ,  4 , hs3); 
                    197:   hh(B , C , D , A , 12 , hs4); 
                    198:   hh(A , B , C , D ,  2 , hs1); 
                    199:   hh(D , A , B , C , 10 , hs2); 
                    200:   hh(C , D , A , B ,  6 , hs3); 
                    201:   hh(B , C , D , A , 14 , hs4); 
                    202:   hh(A , B , C , D ,  1 , hs1); 
                    203:   hh(D , A , B , C ,  9 , hs2); 
                    204:   hh(C , D , A , B ,  5 , hs3); 
                    205:   hh(B , C , D , A , 13 , hs4); 
                    206:   hh(A , B , C , D ,  3 , hs1); 
                    207:   hh(D , A , B , C , 11 , hs2); 
                    208:   hh(C , D , A , B ,  7 , hs3); 
                    209:   hh(B , C , D , A , 15 , hs4);
                    210:   MDp->buffer[0] += A; 
                    211:   MDp->buffer[1] += B;
                    212:   MDp->buffer[2] += C;
                    213:   MDp->buffer[3] += D; 
                    214: }
                    215: 
                    216: /* MDupdate(MDp,X,count)
                    217: ** Input: MDp -- an MDptr
                    218: **        X -- a pointer to an array of unsigned characters.
                    219: **        count -- the number of bits of X to use.
                    220: **                 (if not a multiple of 8, uses high bits of last byte.)
                    221: ** Update MDp using the number of bits of X given by count.
                    222: ** This is the basic input routine for an MD4 user.
                    223: ** The routine completes the MD computation when count < 512, so
                    224: ** every MD computation should end with one call to MDupdate with a
                    225: ** count less than 512.  A call with count 0 will be ignored if the
                    226: ** MD has already been terminated (done != 0), so an extra call with count
                    227: ** 0 can be given as a ``courtesy close'' to force termination if desired.
                    228: */
                    229: void MDupdate(MDptr MDp, unsigned char *X, Word32Type count)
                    230: { int i, byte ;
                    231:   Word32Type tmp, bit, mask;
                    232:   unsigned char XX[64];
                    233:   unsigned char *p;
                    234:   /* return with no error if this is a courtesy close with count
                    235:   ** zero and MDp->done is true.
                    236:   */
                    237:   if (count == 0 && MDp->done) return;
                    238:   /* check to see if MD is already done and report error */
                    239:   if (MDp->done) { printf("\nError: MDupdate MD already done."); return; }
                    240:   /* Add count to MDp->count */
                    241:   tmp = count;
                    242:   p = MDp->count;
                    243:   while (tmp)
                    244:     { tmp += *p;
                    245:       *p++ = tmp;
                    246:       tmp = tmp >> 8;
                    247:     }
                    248:   /* Process data */
                    249:   if (count == 512) 
                    250:     { /* Full block of data to handle */
                    251:       MDblock(MDp,(Word32Type *)X);
                    252:     }
                    253:   else if (count > 512) /* Check for count too large */
                    254:     { printf("\nError: MDupdate called with illegal count value %d.",count);
                    255:       return;
                    256:     }
                    257:   else /* partial block -- must be last block so finish up */
                    258:     { /* Find out how many bytes and residual bits there are */
                    259:       byte = (int) count >> 3;
                    260:       bit =  count & 7;
                    261:       /* Copy X into XX since we need to modify it */
                    262:       for (i=0;i<=byte;i++)   XX[i] = X[i];
                    263:       for (i=byte+1;i<64;i++) XX[i] = 0;
                    264:       /* Add padding '1' bit and low-order zeros in last byte */
                    265:       mask = 1 << (7 - bit);
                    266:       XX[byte] = (XX[byte] | mask) & ~( mask - 1);
                    267:       /* If room for bit count, finish up with this block */
                    268:       if (byte <= 55)
                    269:        { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
                    270:          MDblock(MDp,(Word32Type *)XX);
                    271:        }
                    272:       else /* need to do two blocks to finish up */
                    273:        { MDblock(MDp,(Word32Type *)XX);
                    274:          for (i=0;i<56;i++) XX[i] = 0;
                    275:          for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
                    276:          MDblock(MDp,(Word32Type *)XX);
                    277:        }
                    278:       /* Set flag saying we're done with MD computation */
                    279:       MDp->done = 1;
                    280:     }
                    281: }
                    282: 
                    283: /* 
                    284: ** End of md4.c
                    285: */
                    286: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.