home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 1218.MD4.C < prev    next >
Text File  |  1990-10-25  |  10KB  |  287 lines

  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.   register Word32Type tmp, A, B, C, D;
  153. #if LOWBYTEFIRST == FALSE
  154.   MDreverse(X);
  155. #endif
  156.   A = MDp->buffer[0];
  157.   B = MDp->buffer[1];
  158.   C = MDp->buffer[2];
  159.   D = MDp->buffer[3];
  160.   /* Update the message digest buffer */
  161.   ff(A , B , C , D ,  0 , fs1); /* Round 1 */
  162.   ff(D , A , B , C ,  1 , fs2); 
  163.   ff(C , D , A , B ,  2 , fs3); 
  164.   ff(B , C , D , A ,  3 , fs4); 
  165.   ff(A , B , C , D ,  4 , fs1); 
  166.   ff(D , A , B , C ,  5 , fs2); 
  167.   ff(C , D , A , B ,  6 , fs3); 
  168.   ff(B , C , D , A ,  7 , fs4); 
  169.   ff(A , B , C , D ,  8 , fs1); 
  170.   ff(D , A , B , C ,  9 , fs2); 
  171.   ff(C , D , A , B , 10 , fs3); 
  172.   ff(B , C , D , A , 11 , fs4); 
  173.   ff(A , B , C , D , 12 , fs1); 
  174.   ff(D , A , B , C , 13 , fs2); 
  175.   ff(C , D , A , B , 14 , fs3); 
  176.   ff(B , C , D , A , 15 , fs4); 
  177.   gg(A , B , C , D ,  0 , gs1); /* Round 2 */
  178.   gg(D , A , B , C ,  4 , gs2); 
  179.   gg(C , D , A , B ,  8 , gs3); 
  180.   gg(B , C , D , A , 12 , gs4); 
  181.   gg(A , B , C , D ,  1 , gs1); 
  182.   gg(D , A , B , C ,  5 , gs2); 
  183.   gg(C , D , A , B ,  9 , gs3); 
  184.   gg(B , C , D , A , 13 , gs4); 
  185.   gg(A , B , C , D ,  2 , gs1); 
  186.   gg(D , A , B , C ,  6 , gs2); 
  187.   gg(C , D , A , B , 10 , gs3); 
  188.   gg(B , C , D , A , 14 , gs4); 
  189.   gg(A , B , C , D ,  3 , gs1); 
  190.   gg(D , A , B , C ,  7 , gs2); 
  191.   gg(C , D , A , B , 11 , gs3); 
  192.   gg(B , C , D , A , 15 , gs4);  
  193.   hh(A , B , C , D ,  0 , hs1); /* Round 3 */
  194.   hh(D , A , B , C ,  8 , hs2); 
  195.   hh(C , D , A , B ,  4 , hs3); 
  196.   hh(B , C , D , A , 12 , hs4); 
  197.   hh(A , B , C , D ,  2 , hs1); 
  198.   hh(D , A , B , C , 10 , hs2); 
  199.   hh(C , D , A , B ,  6 , hs3); 
  200.   hh(B , C , D , A , 14 , hs4); 
  201.   hh(A , B , C , D ,  1 , hs1); 
  202.   hh(D , A , B , C ,  9 , hs2); 
  203.   hh(C , D , A , B ,  5 , hs3); 
  204.   hh(B , C , D , A , 13 , hs4); 
  205.   hh(A , B , C , D ,  3 , hs1); 
  206.   hh(D , A , B , C , 11 , hs2); 
  207.   hh(C , D , A , B ,  7 , hs3); 
  208.   hh(B , C , D , A , 15 , hs4);
  209.   MDp->buffer[0] += A; 
  210.   MDp->buffer[1] += B;
  211.   MDp->buffer[2] += C;
  212.   MDp->buffer[3] += D; 
  213. }
  214.  
  215. /* MDupdate(MDp,X,count)
  216. ** Input: MDp -- an MDptr
  217. **        X -- a pointer to an array of unsigned characters.
  218. **        count -- the number of bits of X to use.
  219. **                 (if not a multiple of 8, uses high bits of last byte.)
  220. ** Update MDp using the number of bits of X given by count.
  221. ** This is the basic input routine for an MD4 user.
  222. ** The routine completes the MD computation when count < 512, so
  223. ** every MD computation should end with one call to MDupdate with a
  224. ** count less than 512.  A call with count 0 will be ignored if the
  225. ** MD has already been terminated (done != 0), so an extra call with count
  226. ** 0 can be given as a ``courtesy close'' to force termination if desired.
  227. */
  228. void MDupdate(MDptr MDp, unsigned char *X, Word32Type count)
  229. { int i, byte ;
  230.   Word32Type tmp, bit, mask;
  231.   unsigned char XX[64];
  232.   unsigned char *p;
  233.   /* return with no error if this is a courtesy close with count
  234.   ** zero and MDp->done is true.
  235.   */
  236.   if (count == 0 && MDp->done) return;
  237.   /* check to see if MD is already done and report error */
  238.   if (MDp->done) { printf("\nError: MDupdate MD already done."); return; }
  239.   /* Add count to MDp->count */
  240.   tmp = count;
  241.   p = MDp->count;
  242.   while (tmp)
  243.     { tmp += *p;
  244.       *p++ = tmp;
  245.       tmp = tmp >> 8;
  246.     }
  247.   /* Process data */
  248.   if (count == 512) 
  249.     { /* Full block of data to handle */
  250.       MDblock(MDp,(Word32Type *)X);
  251.     }
  252.   else if (count > 512) /* Check for count too large */
  253.     { printf("\nError: MDupdate called with illegal count value %d.",count);
  254.       return;
  255.     }
  256.   else /* partial block -- must be last block so finish up */
  257.     { /* Find out how many bytes and residual bits there are */
  258.       byte = (int) count >> 3;
  259.       bit =  count & 7;
  260.       /* Copy X into XX since we need to modify it */
  261.       for (i=0;i<=byte;i++)   XX[i] = X[i];
  262.       for (i=byte+1;i<64;i++) XX[i] = 0;
  263.       /* Add padding '1' bit and low-order zeros in last byte */
  264.       mask = 1 << (7 - bit);
  265.       XX[byte] = (XX[byte] | mask) & ~( mask - 1);
  266.       /* If room for bit count, finish up with this block */
  267.       if (byte <= 55)
  268.     { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
  269.       MDblock(MDp,(Word32Type *)XX);
  270.     }
  271.       else /* need to do two blocks to finish up */
  272.     { MDblock(MDp,(Word32Type *)XX);
  273.       for (i=0;i<56;i++) XX[i] = 0;
  274.       for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
  275.       MDblock(MDp,(Word32Type *)XX);
  276.     }
  277.       /* Set flag saying we're done with MD computation */
  278.       MDp->done = 1;
  279.     }
  280. }
  281.  
  282. /* 
  283. ** End of md4.c
  284. */
  285.  
  286.