Annotation of pgp/src/md4.c, revision 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.