No point putting RFC's in the krb5 sources
authorTheodore Tso <tytso@mit.edu>
Thu, 13 Oct 1994 22:04:52 +0000 (22:04 +0000)
committerTheodore Tso <tytso@mit.edu>
Thu, 13 Oct 1994 22:04:52 +0000 (22:04 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4501 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/crypto/md4/RFC1186.TXT [deleted file]
src/lib/crypto/md4/RFC1186B.TXT [deleted file]

diff --git a/src/lib/crypto/md4/RFC1186.TXT b/src/lib/crypto/md4/RFC1186.TXT
deleted file mode 100644 (file)
index 5c0d941..0000000
+++ /dev/null
@@ -1,1011 +0,0 @@
-
-
-
-
-
-
-Network Working Group                                         R. Rivest
-Request for Comments: 1186          MIT Laboratory for Computer Science
-                                                           October 1990
-
-
-                    The MD4 Message Digest Algorithm
-
-Status of this Memo
-
-   This RFC is the specification of the MD4 Digest Algorithm.  If you
-   are going to implement MD4, it is suggested you do it this way.  This
-   memo is for informational use and does not constitute a standard.
-   Distribution of this memo is unlimited.
-
-Table of Contents
-
-   1.  Abstract ....................................................    1
-   2.  Terminology and Notation ....................................    2
-   3.  MD4 Algorithm Description ...................................    2
-   4.  Extensions ..................................................    6
-   5.  Summary .....................................................    7
-   6.  Acknowledgements ............................................    7
-   APPENDIX - Reference Implementation .............................    7
-   Security Considerations..........................................   18
-   Author's Address.................................................   18
-
-1. Abstract
-
-   This note describes the MD4 message digest algorithm.  The algorithm
-   takes as input an input message of arbitrary length and produces as
-   output a 128-bit "fingerprint" or "message digest" of the input.  It
-   is conjectured that it is computationally infeasible to produce two
-   messages having the same message digest, or to produce any message
-   having a given prespecified target message digest.  The MD4 algorithm
-   is thus ideal for digital signature applications, where a large file
-   must be "compressed" in a secure manner before being signed with the
-   RSA public-key cryptosystem.
-
-   The MD4 algorithm is designed to be quite fast on 32-bit machines.
-   On a SUN Sparc station, MD4 runs at 1,450,000 bytes/second.  On a DEC
-   MicroVax II, MD4 runs at approximately 70,000 bytes/second.  On a
-   20MHz 80286, MD4 runs at approximately 32,000 bytes/second.  In
-   addition, the MD4 algorithm does not require any large substitution
-   tables; the algorithm can be coded quite compactly.
-
-   The MD4 algorithm is being placed in the public domain for review and
-   possible adoption as a standard.
-
-
-
-
-Rivest                                                          [Page 1]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-   (Note: The document supersedes an earlier draft.  The algorithm
-   described here is a slight modification of the one described in the
-   draft.)
-
-2.  Terminology and Notation
-
-   In this note a "word" is a 32-bit quantity and a byte is an 8-bit
-   quantity.  A sequence of bits can be interpreted in a natural manner
-   as a sequence of bytes, where each consecutive group of 8 bits is
-   interpreted as a byte with the high-order (most significant) bit of
-   each byte listed first.  Similarly, a sequence of bytes can be
-   interpreted as a sequence of 32-bit words, where each consecutive
-   group of 4 bytes is interpreted as a word with the low-order (least
-   significant) byte given first.
-
-   Let x_i denote "x sub i".  If the subscript is an expression, we
-   surround it in braces, as in x_{i+1}.  Similarly, we use ^ for
-   superscripts (exponentiation), so that x^i denotes x to the i-th
-   power.
-
-   Let the symbol "+" denote addition of words (i.e., modulo- 2^32
-   addition). Let X <<< s denote the 32-bit value obtained by circularly
-   shifting (rotating) X left by s bit positions.  Let not(X) denote the
-   bit-wise complement of X, and let X v Y denote the bit-wise OR of X
-   and Y.  Let X xor Y denote the bit-wise XOR of X and Y, and let XY
-   denote the bit-wise AND of X and Y.
-
-3.  MD4 Algorithm Description
-
-   We begin by supposing that we have a b-bit message as input, and that
-   we wish to find its message digest.  Here b is an arbitrary
-   nonnegative integer; b may be zero, it need not be a multiple of 8,
-   and it may be arbitrarily large.  We imagine the bits of the message
-   written down as follows:
-
-                m_0 m_1 ... m_{b-1} .
-
-   The following five steps are performed to compute the message digest
-   of the message.
-
-      Step 1. Append padding bits
-
-         The message is "padded" (extended) so that its length (in bits)
-         is congruent to 448, modulo 512.  That is, the message is
-         extended so that it is just 64 bits shy of being a multiple of
-         512 bits long.  Padding is always performed, even if the length
-         of the message is already congruent to 448, modulo 512 (in
-         which case 512 bits of padding are added).
-
-
-
-Rivest                                                          [Page 2]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-         Padding is performed as follows: a single "1" bit is appended
-         to the message, and then enough zero bits are appended so that
-         the length in bits of the padded message becomes congruent to
-         448, modulo 512.
-
-      Step 2. Append length
-
-         A 64-bit representation of b (the length of the message before
-         the padding bits were added) is appended to the result of the
-         previous step.  In the unlikely event that b is greater than
-         2^64, then only the low-order 64 bits of b are used.  (These
-         bits are appended as two 32-bit words and appended low-order
-         word first in accordance with the previous conventions.)
-
-         At this point the resulting message (after padding with bits
-         and with b) has a length that is an exact multiple of 512 bits.
-         Equivalently, this message has a length that is an exact
-         multiple of 16 (32-bit) words.  Let M[0 ... N-1] denote the
-         words of the resulting message, where N is a multiple of 16.
-
-      Step 3. Initialize MD buffer
-
-         A 4-word buffer (A,B,C,D) is used to compute the message
-         digest.  Here each of A,B,C,D are 32-bit registers.  These
-         registers are initialized to the following values in
-         hexadecimal, low-order bytes first):
-
-            word A:    01 23 45 67
-            word B:    89 ab cd ef
-            word C:    fe dc ba 98
-            word D:    76 54 32 10
-
-      Step 4. Process message in 16-word blocks
-
-         We first define three auxiliary functions that each take
-         as input three 32-bit words and produce as output one
-         32-bit word.
-
-            f(X,Y,Z)  =  XY v not(X)Z
-            g(X,Y,Z)  =  XY v XZ v YZ
-            h(X,Y,Z)  =  X xor Y xor Z
-
-         In each bit position f acts as a conditional: if x then y else
-         z.  (The function f could have been defined using + instead of
-         v since XY and not(X)Z will never have 1's in the same bit
-         position.)  In each bit position g acts as a majority function:
-         if at least two of x, y, z are on, then g has a one in that bit
-         position, else g has a zero. It is interesting to note that if
-
-
-
-Rivest                                                          [Page 3]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-         the bits of X, Y, and Z are independent and unbiased, the each
-         bit of f(X,Y,Z) will be independent and unbiased, and similarly
-         each bit of g(X,Y,Z) will be independent and unbiased.  The
-         function h is the bit-wise "xor" or "parity" function; it has
-         properties similar to those of f and g.
-
-         Do the following:
-
-         For i = 0 to N/16-1 do  /* process each 16-word block */
-                 For j = 0 to 15 do: /* copy block i into X */
-                   Set X[j] to M[i*16+j].
-                 end /* of loop on j */
-                 Save A as AA, B as BB, C as CC, and D as DD.
-
-                 [Round 1]
-                   Let [A B C D i s] denote the operation
-                         A = (A + f(B,C,D) + X[i]) <<< s  .
-                   Do the following 16 operations:
-                         [A B C D 0 3]
-                         [D A B C 1 7]
-                         [C D A B 2 11]
-                         [B C D A 3 19]
-                         [A B C D 4 3]
-                         [D A B C 5 7]
-                         [C D A B 6 11]
-                         [B C D A 7 19]
-                         [A B C D 8 3]
-                         [D A B C 9 7]
-                         [C D A B 10 11]
-                         [B C D A 11 19]
-                         [A B C D 12 3]
-                         [D A B C 13 7]
-                         [C D A B 14 11]
-                         [B C D A 15 19]
-
-                 [Round 2]
-                   Let [A B C D i s] denote the operation
-                         A = (A + g(B,C,D) + X[i] + 5A827999) <<< s .
-                   (The value 5A..99 is a hexadecimal 32-bit
-                   constant, written with the high-order digit
-                   first. This constant represents the square
-                   root of 2.  The octal value of this constant
-                   is 013240474631.  See Knuth, The Art of
-                   Programming, Volume 2 (Seminumerical
-                   Algorithms), Second Edition (1981),
-                   Addison-Wesley.  Table 2, page 660.)
-                   Do the following 16 operations:
-                         [A B C D 0  3]
-
-
-
-Rivest                                                          [Page 4]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-                         [D A B C 4  5]
-                         [C D A B 8  9]
-                         [B C D A 12 13]
-                         [A B C D 1  3]
-                         [D A B C 5  5]
-                         [C D A B 9  9]
-                         [B C D A 13 13]
-                         [A B C D 2  3]
-                         [D A B C 6  5]
-                         [C D A B 10 9]
-                         [B C D A 14 13]
-                         [A B C D 3  3]
-                         [D A B C 7  5]
-                         [C D A B 11 9]
-                         [B C D A 15 13]
-
-                 [Round 3]
-                   Let [A B C D i s] denote the operation
-                         A = (A + h(B,C,D) + X[i] + 6ED9EBA1) <<< s .
-                   (The value 6E..A1 is a hexadecimal 32-bit
-                   constant, written with the high-order digit
-                   first.  This constant represents the square
-                   root of 3.  The octal value of this constant
-                   is 015666365641.  See Knuth, The Art of
-                   Programming, Volume 2 (Seminumerical
-                   Algorithms), Second Edition (1981),
-                   Addison-Wesley.  Table 2, page 660.)
-                   Do the following 16 operations:
-                         [A B C D 0  3]
-                         [D A B C 8  9]
-                         [C D A B 4  11]
-                         [B C D A 12 15]
-                         [A B C D 2  3]
-                         [D A B C 10 9]
-                         [C D A B 6  11]
-                         [B C D A 14 15]
-                         [A B C D 1  3]
-                         [D A B C 9  9]
-                         [C D A B 5  11]
-                         [B C D A 13 15]
-                         [A B C D 3  3]
-                         [D A B C 11 9]
-                         [C D A B 7  11]
-                         [B C D A 15 15]
-
-         Then perform the following additions:
-                         A = A + AA
-                         B = B + BB
-
-
-
-Rivest                                                          [Page 5]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-                         C = C + CC
-                         D = D + DD
-         (That is, each of the four registers is incremented by
-         the value it had before this block was started.)
-
-         end /* of loop on i */
-
-      Step 5. Output
-
-         The message digest produced as output is A,B,C,D.  That is, we
-         begin with the low-order byte of A, and end with the high-order
-         byte of D.
-
-         This completes the description of MD4.  A reference
-         implementation in C is given in the Appendix.
-
-4.  Extensions
-
-   If more than 128 bits of output are required, then the following
-   procedure is recommended to obtain a 256-bit output.  (There is no
-   provision made for obtaining more than 256 bits.)
-
-   Two copies of MD4 are run in parallel over the input.  The first copy
-   is standard as described above.  The second copy is modified as
-   follows.
-
-   The initial state of the second copy is:
-                    word A:    00 11 22 33
-                    word B:    44 55 66 77
-                    word C:    88 99 aa bb
-                    word D:    cc dd ee ff
-
-   The magic constants in rounds 2 and 3 for the second copy of MD4 are
-   changed from sqrt(2) and sqrt(3) to cuberoot(2) and cuberoot(3):
-
-                                    Octal           Hex
-            Round 2 constant        012050505746    50a28be6
-            Round 3 constant        013423350444    5c4dd124
-
-   Finally, after every 16-word block is processed (including the last
-   block), the values of the A registers in the two copies are
-   exchanged.
-
-   The final message digest is obtaining by appending the result of the
-   second copy of MD4 to the end of the result of the first copy of MD4.
-
-
-
-
-
-
-Rivest                                                          [Page 6]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-5.  Summary
-
-   The MD4 message digest algorithm is simple to implement, and provides
-   a "fingerprint" or message digest of a message of arbitrary length.
-
-   It is conjectured that the difficulty of coming up with two messages
-   having the same message digest is on the order of 2^64 operations,
-   and that the difficulty of coming up with any message having a given
-   message digest is on the order of 2^128 operations.  The MD4
-   algorithm has been carefully scrutinized for weaknesses.  It is,
-   however, a relatively new algorithm and further security analysis is
-   of course justified, as is the case with any new proposal of this
-   sort.  The level of security provided by MD4 should be sufficient for
-   implementing very high security hybrid digital signature schemes
-   based on MD4 and the RSA public-key cryptosystem.
-
-6.  Acknowledgements
-
-   I'd like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle, and
-   Noam Nisan for numerous helpful comments and suggestions.
-
-APPENDIX - Reference Implementation
-
-This appendix contains the following files:
-
-         md4.h        -- header file for using MD4 implementation
-         md4.c        -- the source code for MD4 routines
-         md4driver.c  -- a sample "user" routine
-         session      -- sample results of running md4driver
-
- /*
- ** ********************************************************************
- ** md4.h -- Header file for implementation of                        **
- ** MD4 Message Digest Algorithm                                      **
- ** Updated: 2/13/90 by Ronald L. Rivest                              **
- ** (C) 1990 RSA Data Security, Inc.                                  **
- ** ********************************************************************
- */
-
- /* MDstruct is the data structure for a message digest computation.
- */
- typedef struct {
-   unsigned int buffer[4]; /* Holds 4-word result of MD computation */
-   unsigned char count[8]; /* Number of bits processed so far */
-   unsigned int done;      /* Nonzero means MD computation finished */
- } MDstruct, *MDptr;
-
- /* MDbegin(MD)
-
-
-
-Rivest                                                          [Page 7]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- ** Input: MD -- an MDptr
- ** Initialize the MDstruct prepatory to doing a message digest
- ** computation.
- */
- extern void MDbegin();
-
- /* MDupdate(MD,X,count)
- ** Input: MD -- an MDptr
- **        X -- a pointer to an array of unsigned characters.
- **        count -- the number of bits of X to use (an unsigned int).
- ** Updates MD using the first "count" bits of X.
- ** The array pointed to by X is not modified.
- ** If count is not a multiple of 8, MDupdate uses high bits of
- ** last byte.
- ** This is the basic input routine for a user.
- ** The routine terminates the MD computation when count < 512, so
- ** every MD computation should end with one call to MDupdate with a
- ** count less than 512.  Zero is OK for a count.
- */
- extern void MDupdate();
-
- /* MDprint(MD)
- ** Input: MD -- an MDptr
- ** Prints message digest buffer MD as 32 hexadecimal digits.
- ** Order is from low-order byte of buffer[0] to high-order byte
- ** of buffer[3].
- ** Each byte is printed with high-order hexadecimal digit first.
- */
- extern void MDprint();
-
- /*
- ** End of md4.h
- ****************************(cut)***********************************/
-
- /*
- ** ********************************************************************
- ** md4.c -- Implementation of MD4 Message Digest Algorithm           **
- ** Updated: 2/16/90 by Ronald L. Rivest                              **
- ** (C) 1990 RSA Data Security, Inc.                                  **
- ** ********************************************************************
- */
-
- /*
- ** To use MD4:
- **   -- Include md4.h in your program
- **   -- Declare an MDstruct MD to hold the state of the digest
- **          computation.
- **   -- Initialize MD using MDbegin(&MD)
-
-
-
-Rivest                                                          [Page 8]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- **   -- For each full block (64 bytes) X you wish to process, call
- **          MDupdate(&MD,X,512)
- **      (512 is the number of bits in a full block.)
- **   -- For the last block (less than 64 bytes) you wish to process,
- **          MDupdate(&MD,X,n)
- **      where n is the number of bits in the partial block. A partial
- **      block terminates the computation, so every MD computation
- **      should terminate by processing a partial block, even if it
- **      has n = 0.
- **   -- The message digest is available in MD.buffer[0] ...
- **      MD.buffer[3].  (Least-significant byte of each word
- **      should be output first.)
- **   -- You can print out the digest using MDprint(&MD)
- */
-
- /* Implementation notes:
- ** This implementation assumes that ints are 32-bit quantities.
- ** If the machine stores the least-significant byte of an int in the
- ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
- ** should be set to TRUE.  Otherwise (e.g., SUNS), LOWBYTEFIRST
- ** should be set to FALSE.  Note that on machines with LOWBYTEFIRST
- ** FALSE the routine MDupdate modifies has a side-effect on its input
- ** array (the order of bytes in each word are reversed).  If this is
- ** undesired a call to MDreverse(X) can reverse the bytes of X back
- ** into order after each call to MDupdate.
-
- */
- #define TRUE  1
- #define FALSE 0
- #define LOWBYTEFIRST FALSE
-
- /* Compile-time includes
- */
- #include <stdio.h>
- #include "md4.h"
-
- /* Compile-time declarations of MD4 "magic constants".
- */
- #define I0  0x67452301       /* Initial values for MD buffer */
- #define I1  0xefcdab89
- #define I2  0x98badcfe
- #define I3  0x10325476
- #define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
- #define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
- /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
- ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
- ** Table 2, page 660.
- */
-
-
-
-Rivest                                                          [Page 9]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- #define fs1  3               /* round 1 shift amounts */
- #define fs2  7
- #define fs3 11
- #define fs4 19
- #define gs1  3               /* round 2 shift amounts */
- #define gs2  5
- #define gs3  9
- #define gs4 13
- #define hs1  3               /* round 3 shift amounts */
- #define hs2  9
- #define hs3 11
- #define hs4 15
-
- /* Compile-time macro declarations for MD4.
- ** Note: The "rot" operator uses the variable "tmp".
- ** It assumes tmp is declared as unsigned int, so that the >>
- ** operator will shift in zeros rather than extending the sign bit.
- */
- #define f(X,Y,Z)             ((X&Y) | ((~X)&Z))
- #define g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
- #define h(X,Y,Z)             (X^Y^Z)
- #define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
- #define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
- #define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
- #define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
-
- /* MDprint(MDp)
- ** Print message digest buffer MDp as 32 hexadecimal digits.
- ** Order is from low-order byte of buffer[0] to high-order byte of
- ** buffer[3].
- ** Each byte is printed with high-order hexadecimal digit first.
- ** This is a user-callable routine.
- */
- void
- MDprint(MDp)
- MDptr MDp;
- { int i,j;
-   for (i=0;i<4;i++)
-     for (j=0;j<32;j=j+8)
-       printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
- }
-
- /* MDbegin(MDp)
- ** Initialize message digest buffer MDp.
- ** This is a user-callable routine.
- */
- void
- MDbegin(MDp)
-
-
-
-Rivest                                                         [Page 10]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- MDptr MDp;
- { int i;
-   MDp->buffer[0] = I0;
-   MDp->buffer[1] = I1;
-   MDp->buffer[2] = I2;
-   MDp->buffer[3] = I3;
-   for (i=0;i<8;i++) MDp->count[i] = 0;
-   MDp->done = 0;
- }
-
- /* MDreverse(X)
- ** Reverse the byte-ordering of every int in X.
- ** Assumes X is an array of 16 ints.
- ** The macro revx reverses the byte-ordering of the next word of X.
- */
- #define revx { t = (*X << 16) | (*X >> 16); \
-      *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
- MDreverse(X)
- unsigned int *X;
- { register unsigned int t;
-   revx; revx; revx; revx; revx; revx; revx; revx;
-   revx; revx; revx; revx; revx; revx; revx; revx;
- }
-
- /* MDblock(MDp,X)
- ** Update message digest buffer MDp->buffer using 16-word data block X.
- ** Assumes all 16 words of X are full of data.
- ** Does not update MDp->count.
- ** This routine is not user-callable.
- */
- static void
- MDblock(MDp,X)
- MDptr MDp;
- unsigned int *X;
- {
-   register unsigned int tmp, A, B, C, D;
- #if LOWBYTEFIRST == FALSE
-   MDreverse(X);
- #endif
-   A = MDp->buffer[0];
-   B = MDp->buffer[1];
-   C = MDp->buffer[2];
-   D = MDp->buffer[3];
-   /* Update the message digest buffer */
-   ff(A , B , C , D ,  0 , fs1); /* Round 1 */
-   ff(D , A , B , C ,  1 , fs2);
-   ff(C , D , A , B ,  2 , fs3);
-   ff(B , C , D , A ,  3 , fs4);
-
-
-
-Rivest                                                         [Page 11]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-   ff(A , B , C , D ,  4 , fs1);
-   ff(D , A , B , C ,  5 , fs2);
-   ff(C , D , A , B ,  6 , fs3);
-   ff(B , C , D , A ,  7 , fs4);
-   ff(A , B , C , D ,  8 , fs1);
-   ff(D , A , B , C ,  9 , fs2);
-   ff(C , D , A , B , 10 , fs3);
-   ff(B , C , D , A , 11 , fs4);
-   ff(A , B , C , D , 12 , fs1);
-   ff(D , A , B , C , 13 , fs2);
-   ff(C , D , A , B , 14 , fs3);
-   ff(B , C , D , A , 15 , fs4);
-   gg(A , B , C , D ,  0 , gs1); /* Round 2 */
-   gg(D , A , B , C ,  4 , gs2);
-   gg(C , D , A , B ,  8 , gs3);
-   gg(B , C , D , A , 12 , gs4);
-   gg(A , B , C , D ,  1 , gs1);
-   gg(D , A , B , C ,  5 , gs2);
-   gg(C , D , A , B ,  9 , gs3);
-   gg(B , C , D , A , 13 , gs4);
-   gg(A , B , C , D ,  2 , gs1);
-   gg(D , A , B , C ,  6 , gs2);
-   gg(C , D , A , B , 10 , gs3);
-   gg(B , C , D , A , 14 , gs4);
-   gg(A , B , C , D ,  3 , gs1);
-   gg(D , A , B , C ,  7 , gs2);
-   gg(C , D , A , B , 11 , gs3);
-   gg(B , C , D , A , 15 , gs4);
-   hh(A , B , C , D ,  0 , hs1); /* Round 3 */
-   hh(D , A , B , C ,  8 , hs2);
-   hh(C , D , A , B ,  4 , hs3);
-   hh(B , C , D , A , 12 , hs4);
-   hh(A , B , C , D ,  2 , hs1);
-   hh(D , A , B , C , 10 , hs2);
-   hh(C , D , A , B ,  6 , hs3);
-   hh(B , C , D , A , 14 , hs4);
-   hh(A , B , C , D ,  1 , hs1);
-   hh(D , A , B , C ,  9 , hs2);
-   hh(C , D , A , B ,  5 , hs3);
-   hh(B , C , D , A , 13 , hs4);
-   hh(A , B , C , D ,  3 , hs1);
-   hh(D , A , B , C , 11 , hs2);
-   hh(C , D , A , B ,  7 , hs3);
-   hh(B , C , D , A , 15 , hs4);
-   MDp->buffer[0] += A;
-   MDp->buffer[1] += B;
-   MDp->buffer[2] += C;
-   MDp->buffer[3] += D;
-
-
-
-Rivest                                                         [Page 12]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- }
-
- /* MDupdate(MDp,X,count)
- ** Input: MDp -- an MDptr
- **        X -- a pointer to an array of unsigned characters.
- **        count -- the number of bits of X to use.
- **          (if not a multiple of 8, uses high bits of last byte.)
- ** Update MDp using the number of bits of X given by count.
- ** This is the basic input routine for an MD4 user.
- ** The routine completes the MD computation when count < 512, so
- ** every MD computation should end with one call to MDupdate with a
- ** count less than 512.  A call with count 0 will be ignored if the
- ** MD has already been terminated (done != 0), so an extra call with
- ** count 0 can be given as a "courtesy close" to force termination
- ** if desired.
- */
- void
- MDupdate(MDp,X,count)
- MDptr MDp;
- unsigned char *X;
- unsigned int count;
- { unsigned int i, tmp, bit, byte, mask;
-   unsigned char XX[64];
-   unsigned char *p;
-   /* return with no error if this is a courtesy close with count
-   ** zero and MDp->done is true.
-   */
-   if (count == 0 && MDp->done) return;
-   /* check to see if MD is already done and report error */
-   if (MDp->done)
-          { printf("\nError: MDupdate MD already done."); return; }
-   /* Add count to MDp->count */
-   tmp = count;
-   p = MDp->count;
-   while (tmp)
-     { tmp += *p;
-       *p++ = tmp;
-       tmp = tmp >> 8;
-     }
-   /* Process data */
-   if (count == 512)
-     { /* Full block of data to handle */
-       MDblock(MDp,(unsigned int *)X);
-     }
-   else if (count > 512) /* Check for count too large */
-     { printf("\nError: MDupdate called with illegal count value %d."
-              ,count);
-       return;
-
-
-
-Rivest                                                         [Page 13]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-     }
-   else /* partial block -- must be last block so finish up */
-     { /* Find out how many bytes and residual bits there are */
-       byte = count >> 3;
-       bit =  count & 7;
-       /* Copy X into XX since we need to modify it */
-       for (i=0;i<=byte;i++)   XX[i] = X[i];
-       for (i=byte+1;i<64;i++) XX[i] = 0;
-       /* Add padding '1' bit and low-order zeros in last byte */
-       mask = 1 << (7 - bit);
-       XX[byte] = (XX[byte] | mask) & ~( mask - 1);
-       /* If room for bit count, finish up with this block */
-       if (byte <= 55)
-         { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
-           MDblock(MDp,(unsigned int *)XX);
-         }
-       else /* need to do two blocks to finish up */
-         { MDblock(MDp,(unsigned int *)XX);
-           for (i=0;i<56;i++) XX[i] = 0;
-           for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
-           MDblock(MDp,(unsigned int *)XX);
-         }
-       /* Set flag saying we're done with MD computation */
-       MDp->done = 1;
-     }
- }
-
- /*
- ** End of md4.c
- ****************************(cut)***********************************/
-
- /*
- ** ********************************************************************
- ** md4driver.c -- sample routines to test                            **
- ** MD4 message digest algorithm.                                     **
- ** Updated: 2/16/90 by Ronald L. Rivest                              **
- ** (C) 1990 RSA Data Security, Inc.                                  **
- ** ********************************************************************
- */
-
- #include <stdio.h>
- #include "md4.h"
-
- /* MDtimetrial()
- ** A time trial routine, to measure the speed of MD4.
- ** Measures speed for 1M blocks = 64M bytes.
- */
- MDtimetrial()
-
-
-
-Rivest                                                         [Page 14]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- { unsigned int X[16];
-   MDstruct MD;
-   int i;
-   double t;
-   for (i=0;i<16;i++) X[i] = 0x01234567 + i;
-   printf
-   ("MD4 time trial. Processing 1 million 64-character blocks...\n");
-   clock();
-   MDbegin(&MD);
-   for (i=0;i<1000000;i++) MDupdate(&MD,X,512);
-   MDupdate(&MD,X,0);
-   t = (double) clock(); /* in microseconds */
-   MDprint(&MD); printf(" is digest of 64M byte test input.\n");
-   printf("Seconds to process test input:   %g\n,t/1e6);
-   printf("Characters processed per second: %ld.\n,(int)(64e12/t));
- }
-
- /* MDstring(s)
- ** Computes the message digest for string s.
- ** Prints out message digest, a space, the string (in quotes) and a
- ** carriage return.
- */
- MDstring(s)
- unsigned char *s;
- { unsigned int i, len = strlen(s);
-   MDstruct MD;
-   MDbegin(&MD);
-   for (i=0;i+64<=len;i=i+64) MDupdate(&MD,s+i,512);
-   MDupdate(&MD,s+i,(len-i)*8);
-   MDprint(&MD);
-   printf(" \"%s\"\n",s);
- }
-
- /* MDfile(filename)
- ** Computes the message digest for a specified file.
- ** Prints out message digest, a space, the file name, and a
- ** carriage return.
- */
- MDfile(filename)
- char *filename;
- { FILE *f = fopen(filename,"rb");
-   unsigned char X[64];
-   MDstruct MD;
-   int b;
-   if (f == NULL)
-      { printf("%s can't be opened.\n",filename); return; }
-   MDbegin(&MD);
-   while ((b=fread(X,1,64,f))!=0) MDupdate(&MD,X,b*8);
-
-
-
-Rivest                                                         [Page 15]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-   MDupdate(&MD,X,0);
-   MDprint(&MD);
-   printf(" %s\n",filename);
-   fclose(f);
- }
-
- /* MDfilter()
- ** Writes the message digest of the data from stdin onto stdout,
- ** followed by a carriage return.
- */
- MDfilter()
- { unsigned char X[64];
-   MDstruct MD;
-   int b;
-   MDbegin(&MD);
-   while ((b=fread(X,1,64,stdin))!=0) MDupdate(&MD,X,b*8);
-   MDupdate(&MD,X,0);
-   MDprint(&MD);
-   printf("\n");
- }
-
- /* MDtestsuite()
- ** Run a standard suite of test data.
- */
- MDtestsuite()
- {
-   printf("MD4 test suite results:\n");
-   MDstring("");
-   MDstring("a");
-   MDstring("abc");
-   MDstring("message digest");
-   MDstring("abcdefghijklmnopqrstuvwxyz");
-   MDstring
-   ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
-   MDfile("foo"); /* Contents of file foo are "abc" */
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- { int i;
-   /* For each command line argument in turn:
-   ** filename          -- prints message digest and name of file
-   ** -sstring          -- prints message digest and contents of string
-   ** -t                -- prints time trial statistics for 64M bytes
-   ** -x                -- execute a standard suite of test data
-   ** (no args)         -- writes messages digest of stdin onto stdout
-   */
-
-
-
-Rivest                                                         [Page 16]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
-   if (argc==1) MDfilter();
-   else
-     for (i=1;i<argc;i++)
-       if (argv[i][0]=='-' && argv[i][1]=='s') MDstring(argv[i]+2);
-       else if (strcmp(argv[i],"-t")==0)       MDtimetrial();
-       else if (strcmp(argv[i],"-x")==0)       MDtestsuite();
-       else                                    MDfile(argv[i]);
- }
-
- /*
- ** end of md4driver.c
- ****************************(cut)***********************************/
-
-
- --------------------------------------------------------------------
- --- Sample session.  Compiling and using MD4 on SUN Sparcstation ---
- --------------------------------------------------------------------
- >ls
- total 66
- -rw-rw-r--  1 rivest          3 Feb 14 17:40 abcfile
- -rwxrwxr-x  1 rivest      24576 Feb 17 12:28 md4
- -rw-rw-r--  1 rivest       9347 Feb 17 00:37 md4.c
- -rw-rw-r--  1 rivest      25150 Feb 17 12:25 md4.doc
- -rw-rw-r--  1 rivest       1844 Feb 16 21:21 md4.h
- -rw-rw-r--  1 rivest       3497 Feb 17 12:27 md4driver.c
- >
- >cc -o md4 -O4 md4.c md4driver.c
- md4.c:
- md4driver.c:
- Linking:
- >
- >md4 -x
- MD4 test suite results:
- 31d6cfe0d16ae931b73c59d7e0c089c0 ""
- bde52cb31de33e46245e05fbdbd6fb24 "a"
- a448017aaf21d8525fc10ae87aa6729d "abc"
- d9130a8164549fe818874806e1c7014b "message digest"
- d79e1c308aa5bbcdeea8ed63df412da9 "abcdefghijklmnopqrstuvwxyz"
- 043f8582f241db351ce627e153e7f0e4
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
- a448017aaf21d8525fc10ae87aa6729d abcfile
- >
- >md4 -sabc -shi
- a448017aaf21d8525fc10ae87aa6729d "abc"
- cfaee2512bd25eb033236f0cd054e308 "hi"
- >
- >md4 *
- a448017aaf21d8525fc10ae87aa6729d abcfile
-
-
-
-Rivest                                                         [Page 17]
-\f
-RFC 1186              MD4 Message Digest Algorithm          October 1990
-
-
- d316f994da0e951cf9502928a1f73300 md4
- 379adb39eada0dfdbbdfdcd0d9def8c4 md4.c
- 9a3f73327c65954198b1f45a3aa12665 md4.doc
- 37fe165ac177b461ff78b86d10e4ff33 md4.h
- 7dcba2e2dc4d8f1408d08beb17dabb2a md4.o
- 08790161bfddc6f5788b4353875cb1c3 md4driver.c
- 1f84a7f690b0545d2d0480d5d3c26eea md4driver.o
- >
- >cat abcfile | md4
- a448017aaf21d8525fc10ae87aa6729d
- >
- >md4 -t
- MD4 time trial. Processing 1 million 64-character blocks...
- 6325bf77e5891c7c0d8104b64cc6e9ef is digest of 64M byte test input.
- Seconds to process test input:   44.0982
- Characters processed per second: 1451305.
- >
- >
- ------------------------ end of sample session --------------------
-
-      Note:  A version of this document including the C source code is
-      available for FTP from THEORY.LSC.MIT.EDU in the file "md4.doc".
-
-Security Considerations
-
-   The level of security discussed in this memo by MD4 is considered to
-   be sufficient for implementing very high security hybrid digital
-   signature schemes based on MD4 and the RSA public-key cryptosystem.
-
-Author's Address
-
-   Ronald L. Rivest
-   Massachusetts Institute of Technology
-   Laboratory for Computer Science
-   NE43-324
-   545 Technology Square
-   Cambridge, MA 02139-1986
-
-   Phone: (617) 253-5880
-
-   EMail: rivest@theory.lcs.mit.edu
-
-
-
-
-
-
-
-
-
-
-Rivest                                                         [Page 18]
-\f
\ No newline at end of file
diff --git a/src/lib/crypto/md4/RFC1186B.TXT b/src/lib/crypto/md4/RFC1186B.TXT
deleted file mode 100644 (file)
index 6be1a29..0000000
+++ /dev/null
@@ -1,1041 +0,0 @@
-*** Note: This is a revised version of "md4.doc", obtained as "md4.doc"
-*** by anonymous ftp from theory.lcs.mit.edu.  The original version is 
-*** still available as "md4.doc.old".  The MD4 algorithm is unchanged, but
-*** the newer version of the code is somewhat more portable, although slightly
-*** slower.                                    [Ronald L. Rivest 1/13/91]
-\f
-Network Working Group                                          R. Rivest
-Request for Comments: 1186B          MIT Laboratory for Computer Science
-Updates: RFC 1186                                               S. Dusse
-                                                 RSA Data Security, Inc.
-                                                          9 January 1991
-
-
-
-                    The MD4 Message Digest Algorithm
-
-
-STATUS OF THIS MEMO
-
-   This RFC is the specification of the MD4 Digest Algorithm.  If you
-   are going to implement MD4, it is suggested you do it this way.  This
-   memo is for informational use and does not constitute a standard.
-   Distribution of this memo is unlimited.
-
-Table of Contents
-
-   1.  Executive Summary                                               1
-   2.  Terminology and Notation                                        2
-   3.  MD4 Algorithm Description                                       2
-   4.  Extensions                                                      6
-   5.  Summary                                                         6
-   6.  Acknowledgements                                                7
-   Security Considerations                                             7
-   References                                                          7
-   APPENDIX - Reference Implementation                                 7
-
-1.  Executive Summary
-
-   This note describes the MD4 message digest algorithm.  The algorithm
-   takes as input an input message of arbitrary length and produces as
-   output a 128-bit "fingerprint" or "message digest" of the input.  It
-   is conjectured that it is computationally infeasible to produce two
-   messages having the same message digest, or to produce any message
-   having a given prespecified target message digest.  The MD4 algorithm
-   is thus ideal for digital signature applications, where a large file
-   must be "compressed" in a secure manner before being signed with the
-   RSA public-key cryptosystem.
-
-   The MD4 algorithm is designed to be quite fast on 32-bit machines.
-   In addition, the MD4 algorithm does not require any large
-   substitution tables; the algorithm can be coded quite compactly.
-
-   The MD4 algorithm is being placed in the public domain for review and
-   possible adoption as a standard.
-
-   This RFC is a revision of the October 1990 RFC 1186.  The main
-   difference is that the reference implementation of MD4 in the
-   appendix is more portable.
-
-
-Rivest                                                          [Page 1]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-2.  Terminology and Notation
-
-   In this note a "word" is a 32-bit quantity and a byte is an 8-bit
-   quantity.  A sequence of bits can be interpreted in a natural manner
-   as a sequence of bytes, where each consecutive group of 8 bits is
-   interpreted as a byte with the high-order (most significant) bit of
-   each byte listed first.  Similarly, a sequence of bytes can be
-   interpreted as a sequence of 32-bit words, where each consecutive
-   group of 4 bytes is interpreted as a word with the low-order (least
-   significant) byte given first.
-
-   Let x_i denote "x sub i".  If the subscript is an expression, we
-   surround it in braces, as in x_{i+1}.  Similarly, we use ^ for
-   superscripts (exponentiation), so that x^i denotes x to the i-th
-   power.
-
-   Let the symbol "+" denote addition of words (i.e., modulo- 2^32
-   addition).  Let X <<< s denote the 32-bit value obtained by
-   circularly shifting (rotating) X left by s bit positions.  Let not(X)
-   denote the bit-wise complement of X, and let X v Y denote the bit-
-   wise OR of X and Y.  Let X xor Y denote the bit-wise XOR of X and Y,
-   and let XY denote the bit-wise AND of X and Y.
-
-
-3.  MD4 Algorithm Description
-
-   We begin by supposing that we have a b-bit message as input, and that
-   we wish to find its message digest.  Here b is an arbitrary
-   nonnegative integer; b may be zero, it need not be a multiple of 8,
-   and it may be arbitrarily large.  We imagine the bits of the message
-   written down as follows:
-
-                    m_0 m_1 ... m_{b-1} .
-
-   The following five steps are performed to compute the message digest
-   of the message.
-
-
-3.1 Step 1. Append padding bits
-
-   The message is "padded" (extended) so that its length (in bits) is
-   congruent to 448, modulo 512.  That is, the message is extended so
-   that it is just 64 bits shy of being a multiple of 512 bits long.
-   Padding is always performed, even if the length of the message is
-   already congruent to 448, modulo 512 (in which case 512 bits of
-   padding are added).
-
-   Padding is performed as follows: a single "1" bit is appended to the
-   message, and then enough zero bits are appended so that the length in
-   bits of the padded message becomes congruent to 448, modulo 512.
-
-
-
-
-Rivest                                                          [Page 2]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-3.2 Step 2. Append length
-
-   A 64-bit representation of b (the length of the message before the
-   padding bits were added) is appended to the result of the previous
-   step.  In the unlikely event that b is greater than 2^64, then only
-   the low-order 64 bits of b are used.  (These bits are appended as two
-   32-bit words and appended low-order word first in accordance with the
-   previous conventions.)
-
-   At this point the resulting message (after padding with bits and with
-   b) has a length that is an exact multiple of 512 bits.  Equivalently,
-   this message has a length that is an exact multiple of 16 (32-bit)
-   words.  Let M[0 ... N-1] denote the words of the resulting message,
-   where N is a multiple of 16.
-
-
-3.3 Step 3. Initialize MD buffer
-
-   A 4-word buffer (A,B,C,D) is used to compute the message digest.
-   Here each of A,B,C,D are 32-bit registers.  These registers are
-   initialized to the following values in hexadecimal, low-order bytes
-   first):
-
-                    word A: 01 23 45 67
-                    word B: 89 ab cd ef
-                    word C: fe dc ba 98
-                    word D: 76 54 32 10
-
-
-3.4 Step 4. Process message in 16-word blocks
-
-   We first define three auxiliary functions that each take as input
-   three 32-bit words and produce as output one 32-bit word.
-
-                    f(X,Y,Z)  =  XY v not(X)Z
-                    g(X,Y,Z)  =  XY v XZ v YZ
-                    h(X,Y,Z)  =  X xor Y xor Z
-
-   In each bit position f acts as a conditional: if x then y else z.
-   (The function f could have been defined using + instead of v since XY
-   and not(X)Z will never have 1's in the same bit position.)  In each
-   bit position g acts as a majority function: if at least two of x, y,
-   z are on, then g has a one in that bit position, else g has a zero.
-   It is interesting to note that if the bits of X, Y, and Z are
-   independent and unbiased, the each bit of f(X,Y,Z) will be
-   independent and unbiased, and similarly each bit of g(X,Y,Z) will be
-   independent and unbiased.  The function h is the bit-wise "xor" or
-   "parity" function; it has properties similar to those of f and g.
-
-   Do the following:
-
-   For i = 0 to N/16-1 do:  /* process each 16-word block */
-       For j = 0 to 15 do:  /* copy block i into X */
-           Set X[j] to M[i*16+j].
-Rivest                                                          [Page 3]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-       end /* of loop on j */
-       Save A as AA, B as BB, C as CC, and D as DD.
-
-       [Round 1]
-         Let [A B C D i s] denote the operation
-             A = (A + f(B,C,D) + X[i]) <<< s .
-
-         Do the following 16 operations:
-             [A B C D 0 3]
-             [D A B C 1 7]
-             [C D A B 2 11]
-             [B C D A 3 19]
-             [A B C D 4 3]
-             [D A B C 5 7]
-             [C D A B 6 11]
-             [B C D A 7 19]
-             [A B C D 8 3]
-             [D A B C 9 7]
-             [C D A B 10 11]
-             [B C D A 11 19]
-             [A B C D 12 3]
-             [D A B C 13 7]
-             [C D A B 14 11]
-             [B C D A 15 19]
-
-       [Round 2]
-         Let [A B C D i s] denote the operation
-             A = (A + g(B,C,D) + X[i] + 5A827999) <<< s .
-
-         (The value 5A..99 is a hexadecimal 32-bit
-         constant, written with the high-order digit
-         first. This constant represents the square
-         root of 2.  The octal value of this constant
-         is 013240474631.  See Knuth, The Art of
-         Programming, Volume 2 (Seminumerical
-         Algorithms), Second Edition (1981),
-         Addison-Wesley.  Table 2, page 660.)
-
-         Do the following 16 operations:
-             [A B C D 0  3]
-             [D A B C 4  5]
-             [C D A B 8  9]
-             [B C D A 12 13]
-             [A B C D 1  3]
-             [D A B C 5  5]
-             [C D A B 9  9]
-             [B C D A 13 13]
-             [A B C D 2  3]
-             [D A B C 6  5]
-             [C D A B 10 9]
-             [B C D A 14 13]
-             [A B C D 3  3]
-             [D A B C 7  5]
-             [C D A B 11 9]
-Rivest                                                          [Page 4]             [B C D A 15 13]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-
-       [Round 3]
-         Let [A B C D i s] denote the operation
-             A = (A + h(B,C,D) + X[i] + 6ED9EBA1) <<< s .
-
-         (The value 6E..A1 is a hexadecimal 32-bit
-         constant, written with the high-order digit
-         first.  This constant represents the square
-         root of 3.  The octal value of this constant
-         is 015666365641.  See Knuth, The Art of
-         Programming, Volume 2 (Seminumerical
-         Algorithms), Second Edition (1981),
-         Addison-Wesley.  Table 2, page 660.)
-
-         Do the following 16 operations:
-             [A B C D 0  3]
-             [D A B C 8  9]
-             [C D A B 4  11]
-             [B C D A 12 15]
-             [A B C D 2  3]
-             [D A B C 10 9]
-             [C D A B 6  11]
-             [B C D A 14 15]
-             [A B C D 1  3]
-             [D A B C 9  9]
-             [C D A B 5  11]
-             [B C D A 13 15]
-             [A B C D 3  3]
-             [D A B C 11 9]
-             [C D A B 7  11]
-             [B C D A 15 15]
-
-         Then perform the following additions:
-             A = A + AA
-             B = B + BB
-             C = C + CC
-             D = D + DD
-
-         (That is, each of the four registers is
-         incremented by the value it had before
-         this block was started.)
-
-   end /* of loop on i */
-
-
-3.5 Step 5. Output
-
-   The message digest produced as output is A,B,C,D.  That is, we begin
-   with the low-order byte of A, and end with the high-order byte of D.
-
-   This completes the description of MD4.  A reference implementation in
-   C is given in the Appendix.
-
-
-Rivest                                                          [Page 5]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-4.  Extensions
-
-   If more than 128 bits of output are required, then the following
-   procedure is recommended to obtain a 256-bit output.  (There is no
-   provision made for obtaining more than 256 bits.)
-
-   Two copies of MD4 are run in parallel over the input.  The first copy
-   is standard as described above.  The second copy is modified as
-   follows.
-
-   The initial state of the second copy is:
-
-                    word A: 00 11 22 33
-                    word B: 44 55 66 77
-                    word C: 88 99 aa bb
-                    word D: cc dd ee ff
-
-   The magic constants in rounds 2 and 3 for the second copy of MD4 are
-   changed from sqrt(2) and sqrt(3) to cuberoot(2) and cuberoot(3):
-
-                           Octal             Hex
-      Round 2 constant     012050505746      50a28be6
-      Round 3 constant     013423350444      5c4dd124
-
-   Finally, after every 16-word block is processed (including the last
-   block), the values of the A registers in the two copies are
-   exchanged.
-
-   The final message digest is obtaining by appending the result of the
-   second copy of MD4 to the end of the result of the first copy of MD4.
-
-
-5.  Summary
-
-   The MD4 message digest algorithm is simple to implement, and provides
-   a "fingerprint" or message digest of a message of arbitrary length.
-   It is conjectured that the difficulty of coming up with two messages
-   having the same message digest is on the order of 2^64 operations,
-   and that the difficulty of coming up with any message having a given
-   message digest is on the order of 2^128 operations.  The MD4
-   algorithm has been carefully scrutinized for weaknesses.  It is,
-   however, a relatively new algorithm and further security analysis is
-   of course justified, as is the case with any new proposal of this
-   sort.  The level of security provided by MD4 should be sufficient for
-   implementing very high security hybrid digital signature schemes
-   based on MD4 and the RSA public-key cryptosystem.
-
-
-6.  Acknowledgements
-
-   We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
-   and Noam Nisan for numerous helpful comments and suggestions.
-
-
-Rivest                                                          [Page 6]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-Security Considerations
-
-   The level of security discussed in this memo by MD4 is considered to
-   be sufficient for implementing very high security hybrid digital
-   signature schemes based on MD4 and the RSA public-key cryptosystem.
-
-
-Authors' Addresses
-
-   Ronald L. Rivest
-   Massachusetts Institute of Technology
-   Laboratory for Computer Science
-   NE43-324
-   545 Technology Square
-   Cambridge, MA 02139-1986
-   Phone: (617) 253-5880
-   EMail: rivest@theory.lcs.mit.edu
-
-   Steve Dusse
-   RSA Data Security, Inc.
-   10 Twin Dolphin Dr.
-   Redwood City, CA 94065
-   Phone: (415) 595-8782
-   EMail: dusse@rsa.com
-
-
-References
-
-   [1] Rivest, R.L. The MD4 message digest algorithm. Presented at
-   CRYPTO '90 (Santa Barbara, CA, August 11-15, 1990).
-
-
-APPENDIX - Reference Implementation
-
-   This appendix contains the following files:
-
-     md4.h -- header file for using MD4 implementation
-
-     md4.c -- the source code for MD4 routines
-
-     md4driver.c -- a sample "user" routine
-
-     session -- sample results of running md4driver
-
-   The implementation of MD4 given in this appendix differs from the one
-   given in [1] and again in RFC 1186.  The main difference is that this
-   version should compile and run correctly on more platforms than the
-   other ones.  We have sacrificed performance for portability.  MD4
-   speeds given in [1] and RFC 1186 are not necessarily the same as
-   those one might obtain with this reference implementation.  However,
-   it is not difficult to improve this implementation on particular
-   platforms, an exercise left to the reader.  Following are some
-   suggestions:
-
-Rivest                                                          [Page 7]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-     1. Change MD4Block so that the context is not used at all if
-        it is empty (mdi == 0) and 64 or more bytes remain (inLen
-        >= 64). In other words, call Transform with inBuf in this
-        case. (This requires that byte ordering is correct in
-        inBuf.)
-
-     2. Implement a procedure MD4BlockLong modeled after MD4Block
-        where inBuf is UINT4 * instead of unsigned char *.
-        MD4BlockLong would call Transform directly with 16 word
-        blocks from inBuf.  Call this instead of MD4Block in
-        general. This works well if you have an I/O procedure that
-        can read long words from a file.
-
-     3. On "little-endian" platforms where the lowest-address byte
-        in a long word is the least significant (and there are no
-        alignment restrictions), change MD4Block to call Transform
-        directly with 64-byte blocks from inBuf (casted to a UINT4
-        *).
-
-/*
- **********************************************************************
- ** md4.h -- Header file for implementation of MD4                   **
- ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
- ** Created: 2/17/90 RLR                                             **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version              **
- **********************************************************************
- */
-
-/*
- **********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
- **                                                                  **
- ** License to copy and use this software is granted provided that   **
- ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
- ** Digest Algorithm" in all material mentioning or referencing this **
- ** software or this function.                                       **
- **                                                                  **
- ** License is also granted to make and use derivative works         **
- ** provided that such works are identified as "derived from the RSA **
- ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
- ** material mentioning or referencing the derived work.             **
- **                                                                  **
- ** RSA Data Security, Inc. makes no representations concerning      **
- ** either the merchantability of this software or the suitability   **
- ** of this software for any particular purpose.  It is provided "as **
- ** is" without express or implied warranty of any kind.             **
- **                                                                  **
- ** These notices must be retained in any copies of any part of this **
- ** documentation and/or software.                                   **
- **********************************************************************
- */
-
-/* typedef a 32 bit type */
-typedef unsigned long int UINT4;
-Rivest                                                          [Page 8]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-
-/* Data structure for MD4 (Message Digest) computation */
-typedef struct {
-  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
-  UINT4 buf[4];                                    /* scratch buffer */
-  unsigned char in[64];                              /* input buffer */
-  unsigned char digest[16];     /* actual digest after MD4Final call */
-} MD4_CTX;
-
-void MD4Init ();
-void MD4Update ();
-void MD4Final ();
-
-/*
- **********************************************************************
- ** End of md4.h                                                     **
- ******************************* (cut) ********************************
- */
-
-/*
- **********************************************************************
- ** md4.c                                                            **
- ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
- ** Created: 2/17/90 RLR                                             **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
- **********************************************************************
- */
-
-/*
- **********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
- **                                                                  **
- ** License to copy and use this software is granted provided that   **
- ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
- ** Digest Algorithm" in all material mentioning or referencing this **
- ** software or this function.                                       **
- **                                                                  **
- ** License is also granted to make and use derivative works         **
- ** provided that such works are identified as "derived from the RSA **
- ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
- ** material mentioning or referencing the derived work.             **
- **                                                                  **
- ** RSA Data Security, Inc. makes no representations concerning      **
- ** either the merchantability of this software or the suitability   **
- ** of this software for any particular purpose.  It is provided "as **
- ** is" without express or implied warranty of any kind.             **
- **                                                                  **
- ** These notices must be retained in any copies of any part of this **
- ** documentation and/or software.                                   **
- **********************************************************************
- */
-
-#include "md4.h"
-
-Rivest                                                          [Page 9]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-/* forward declaration */
-static void Transform ();
-
-static unsigned char PADDING[64] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G and H are basic MD4 functions: selection, majority, parity */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s) \
-  {(a) += F ((b), (c), (d)) + (x); \
-   (a) = ROTATE_LEFT ((a), (s));}
-#define GG(a, b, c, d, x, s) \
-  {(a) += G ((b), (c), (d)) + (x) + (UINT4)013240474631; \
-   (a) = ROTATE_LEFT ((a), (s));}
-#define HH(a, b, c, d, x, s) \
-  {(a) += H ((b), (c), (d)) + (x) + (UINT4)015666365641; \
-   (a) = ROTATE_LEFT ((a), (s));}
-
-void MD4Init (mdContext)
-MD4_CTX *mdContext;
-{
-  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
-
-  /* Load magic initialization constants.
-   */
-  mdContext->buf[0] = (UINT4)0x67452301;
-  mdContext->buf[1] = (UINT4)0xefcdab89;
-  mdContext->buf[2] = (UINT4)0x98badcfe;
-  mdContext->buf[3] = (UINT4)0x10325476;
-}
-
-void MD4Update (mdContext, inBuf, inLen)
-MD4_CTX *mdContext;
-unsigned char *inBuf;
-unsigned int inLen;
-{
-  UINT4 in[16];
-  int mdi;
-Rivest                                                         [Page 10]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-  unsigned int i, ii;
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* update number of bits */
-  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
-    mdContext->i[1]++;
-  mdContext->i[0] += ((UINT4)inLen << 3);
-  mdContext->i[1] += ((UINT4)inLen >> 29);
-
-  while (inLen--) {
-    /* add new character to buffer, increment mdi */
-    mdContext->in[mdi++] = *inBuf++;
-
-    /* transform if necessary */
-    if (mdi == 0x40) {
-      for (i = 0, ii = 0; i < 16; i++, ii += 4)
-        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-                (((UINT4)mdContext->in[ii+2]) << 16) |
-                (((UINT4)mdContext->in[ii+1]) << 8) |
-                ((UINT4)mdContext->in[ii]);
-      Transform (mdContext->buf, in);
-      mdi = 0;
-    }
-  }
-}
-
-void MD4Final (mdContext)
-MD4_CTX *mdContext;
-{
-  UINT4 in[16];
-  int mdi;
-  unsigned int i, ii;
-  unsigned int padLen;
-
-  /* save number of bits */
-  in[14] = mdContext->i[0];
-  in[15] = mdContext->i[1];
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* pad out to 56 mod 64 */
-  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-  MD4Update (mdContext, PADDING, padLen);
-
-  /* append length in bits and transform */
-  for (i = 0, ii = 0; i < 14; i++, ii += 4)
-    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-            (((UINT4)mdContext->in[ii+2]) << 16) |
-            (((UINT4)mdContext->in[ii+1]) << 8) |
-            ((UINT4)mdContext->in[ii]);
-  Transform (mdContext->buf, in);
-Rivest                                                         [Page 11]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-
-  /* store buffer in digest */
-  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-    mdContext->digest[ii+1] =
-      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-    mdContext->digest[ii+2] =
-      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-    mdContext->digest[ii+3] =
-      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-  }
-}
-
-/* Basic MD4 step. Transform buf based on in.
- */
-static void Transform (buf, in)
-UINT4 *buf;
-UINT4 *in;
-{
-  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
-  /* Round 1 */
-  FF (a, b, c, d, in[ 0],  3);
-  FF (d, a, b, c, in[ 1],  7);
-  FF (c, d, a, b, in[ 2], 11);
-  FF (b, c, d, a, in[ 3], 19);
-  FF (a, b, c, d, in[ 4],  3);
-  FF (d, a, b, c, in[ 5],  7);
-  FF (c, d, a, b, in[ 6], 11);
-  FF (b, c, d, a, in[ 7], 19);
-  FF (a, b, c, d, in[ 8],  3);
-  FF (d, a, b, c, in[ 9],  7);
-  FF (c, d, a, b, in[10], 11);
-  FF (b, c, d, a, in[11], 19);
-  FF (a, b, c, d, in[12],  3);
-  FF (d, a, b, c, in[13],  7);
-  FF (c, d, a, b, in[14], 11);
-  FF (b, c, d, a, in[15], 19);
-
-  /* Round 2 */
-  GG (a, b, c, d, in[ 0],  3);
-  GG (d, a, b, c, in[ 4],  5);
-  GG (c, d, a, b, in[ 8],  9);
-  GG (b, c, d, a, in[12], 13);
-  GG (a, b, c, d, in[ 1],  3);
-  GG (d, a, b, c, in[ 5],  5);
-  GG (c, d, a, b, in[ 9],  9);
-  GG (b, c, d, a, in[13], 13);
-  GG (a, b, c, d, in[ 2],  3);
-  GG (d, a, b, c, in[ 6],  5);
-  GG (c, d, a, b, in[10],  9);
-  GG (b, c, d, a, in[14], 13);
-  GG (a, b, c, d, in[ 3],  3);
-  GG (d, a, b, c, in[ 7],  5);
-Rivest                                                         [Page 12]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-  GG (c, d, a, b, in[11],  9);
-  GG (b, c, d, a, in[15], 13);
-
-  /* Round 3 */
-  HH (a, b, c, d, in[ 0],  3);
-  HH (d, a, b, c, in[ 8],  9);
-  HH (c, d, a, b, in[ 4], 11);
-  HH (b, c, d, a, in[12], 15);
-  HH (a, b, c, d, in[ 2],  3);
-  HH (d, a, b, c, in[10],  9);
-  HH (c, d, a, b, in[ 6], 11);
-  HH (b, c, d, a, in[14], 15);
-  HH (a, b, c, d, in[ 1],  3);
-  HH (d, a, b, c, in[ 9],  9);
-  HH (c, d, a, b, in[ 5], 11);
-  HH (b, c, d, a, in[13], 15);
-  HH (a, b, c, d, in[ 3],  3);
-  HH (d, a, b, c, in[11],  9);
-  HH (c, d, a, b, in[ 7], 11);
-  HH (b, c, d, a, in[15], 15);
-
-  buf[0] += a;
-  buf[1] += b;
-  buf[2] += c;
-  buf[3] += d;
-}
-
-/*
- **********************************************************************
- ** End of md4.c                                                     **
- ******************************* (cut) ********************************
- */
-
-/*
- **********************************************************************
- ** md4driver.c -- sample routines to test                           **
- ** RSA Data Security, Inc. MD4 message digest algorithm.            **
- ** Created: 2/16/90 RLR                                             **
- ** Updated: 1/91 SRD                                                **
- **********************************************************************
- */
-
-/*
- **********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
- **                                                                  **
- ** RSA Data Security, Inc. makes no representations concerning      **
- ** either the merchantability of this software or the suitability   **
- ** of this software for any particular purpose.  It is provided "as **
- ** is" without express or implied warranty of any kind.             **
- **                                                                  **
- ** These notices must be retained in any copies of any part of this **
- ** documentation and/or software.                                   **
- **********************************************************************
-Rivest                                                         [Page 13]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <time.h>
-#include <string.h>
-#include "md4.h"
-
-/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
-   Order is from low-order byte to high-order byte of digest.
-   Each byte is printed with high-order hexadecimal digit first.
- */
-static void MDPrint (mdContext)
-MD4_CTX *mdContext;
-{
-  int i;
-
-  for (i = 0; i < 16; i++)
-    printf ("%02x", mdContext->digest[i]);
-}
-
-/* size of test block */
-#define TEST_BLOCK_SIZE 1000
-
-/* number of blocks to process */
-#define TEST_BLOCKS 2000
-
-/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
-static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
-
-/* A time trial routine, to measure the speed of MD4.
-   Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
-   characters.
- */
-static void MDTimeTrial ()
-{
-  MD4_CTX mdContext;
-  time_t endTime, startTime;
-  unsigned char data[TEST_BLOCK_SIZE];
-  unsigned int i;
-
-  /* initialize test data */
-  for (i = 0; i < TEST_BLOCK_SIZE; i++)
-    data[i] = (unsigned char)(i & 0xFF);
-
-  /* start timer */
-  printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES);
-  time (&startTime);
-
-  /* digest data in TEST_BLOCK_SIZE byte blocks */
-  MD4Init (&mdContext);
-  for (i = TEST_BLOCKS; i > 0; i--)
-    MD4Update (&mdContext, data, TEST_BLOCK_SIZE);
-  MD4Final (&mdContext);
-Rivest                                                         [Page 14]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-
-  /* stop timer, get time difference */
-  time (&endTime);
-  MDPrint (&mdContext);
-  printf (" is digest of test input.\n");
-  printf
-    ("Seconds to process test input: %ld\n", (long)(endTime-startTime));
-  printf
-    ("Characters processed per second: %ld\n",
-     TEST_BYTES/(endTime-startTime));
-}
-
-/* Computes the message digest for string inString.
-   Prints out message digest, a space, the string (in quotes) and a
-   carriage return.
- */
-static void MDString (inString)
-char *inString;
-{
-  MD4_CTX mdContext;
-  unsigned int len = strlen (inString);
-
-  MD4Init (&mdContext);
-  MD4Update (&mdContext, inString, len);
-  MD4Final (&mdContext);
-  MDPrint (&mdContext);
-  printf (" \"%s\"\n\n", inString);
-}
-
-/* Computes the message digest for a specified file.
-   Prints out message digest, a space, the file name, and a carriage
-   return.
- */
-static void MDFile (filename)
-char *filename;
-{
-  FILE *inFile = fopen (filename, "rb");
-  MD4_CTX mdContext;
-  int bytes;
-  unsigned char data[1024];
-
-  if (inFile == NULL) {
-    printf ("%s can't be opened.\n", filename);
-    return;
-  }
-
-  MD4Init (&mdContext);
-  while ((bytes = fread (data, 1, 1024, inFile)) != 0)
-    MD4Update (&mdContext, data, bytes);
-  MD4Final (&mdContext);
-  MDPrint (&mdContext);
-  printf (" %s\n", filename);
-  fclose (inFile);
-}
-Rivest                                                         [Page 15]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-
-/* Writes the message digest of the data from stdin onto stdout,
-   followed by a carriage return.
- */
-static void MDFilter ()
-{
-  MD4_CTX mdContext;
-  int bytes;
-  unsigned char data[16];
-
-  MD4Init (&mdContext);
-  while ((bytes = fread (data, 1, 16, stdin)) != 0)
-    MD4Update (&mdContext, data, bytes);
-  MD4Final (&mdContext);
-  MDPrint (&mdContext);
-  printf ("\n");
-}
-
-/* Runs a standard suite of test data.
- */
-static void MDTestSuite ()
-{
-  printf ("MD4 test suite results:\n\n");
-  MDString ("");
-  MDString ("a");
-  MDString ("abc");
-  MDString ("message digest");
-  MDString ("abcdefghijklmnopqrstuvwxyz");
-  MDString
-    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
-  MDString
-    ("1234567890123456789012345678901234567890\
-1234567890123456789012345678901234567890");
-  /* Contents of file foo are "abc" */
-  MDFile ("foo");
-}
-
-void main (argc, argv)
-int argc;
-char *argv[];
-{
-  int i;
-
-  /* For each command line argument in turn:
-  ** filename          -- prints message digest and name of file
-  ** -sstring          -- prints message digest and contents of string
-  ** -t                -- prints time trial statistics for 1M characters
-  ** -x                -- execute a standard suite of test data
-  ** (no args)         -- writes messages digest of stdin onto stdout
-  */
-  if (argc == 1)
-    MDFilter ();
-  else
-    for (i = 1; i < argc; i++)
-Rivest                                                         [Page 16]\f
-
-
-RFC 1186B         The MD4 Message Digest Algorithm        9 January 1991
-
-
-
-      if (argv[i][0] == '-' && argv[i][1] == 's')
-        MDString (argv[i] + 2);
-      else if (strcmp (argv[i], "-t") == 0)
-        MDTimeTrial ();
-      else if (strcmp (argv[i], "-x") == 0)
-        MDTestSuite ();
-      else MDFile (argv[i]);
-}
-
-/*
- **********************************************************************
- ** End of md4driver.c                                               **
- ******************************* (cut) ********************************
- */
-
------------------------------------------------------------------------
--- Sample session output obtained by running md4driver test suite    --
------------------------------------------------------------------------
-
-  MD4 test suite results:
-
-  31d6cfe0d16ae931b73c59d7e0c089c0 ""
-
-  bde52cb31de33e46245e05fbdbd6fb24 "a"
-
-  a448017aaf21d8525fc10ae87aa6729d "abc"
-
-  d9130a8164549fe818874806e1c7014b "message digest"
-
-  d79e1c308aa5bbcdeea8ed63df412da9 "abcdefghijklmnopqrstuvwxyz"
-
-  043f8582f241db351ce627e153e7f0e4 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghij
-  klmnopqrstuvwxyz0123456789"
-
-  e33b4ddc9c38f2199c3e7b164fcc0536 "123456789012345678901234567890123456
-  78901234567890123456789012345678901234567890"
-
-  a448017aaf21d8525fc10ae87aa6729d foo
-
-
------------------------------------------------------------------------
--- End of sample session                                             --
--------------------------------- (cut) --------------------------------
-
-
-   Note: A version of this document including the C source code is
-   available for FTP from RSA.COM in the file "md4.doc".
-
-
-
-
-
-
-
-Rivest                                                         [Page 17]\f
-
-
-
-\1f