summaryrefslogtreecommitdiffstats
path: root/test/jake2/qcommon/TestMD4.java
diff options
context:
space:
mode:
Diffstat (limited to 'test/jake2/qcommon/TestMD4.java')
-rw-r--r--test/jake2/qcommon/TestMD4.java1145
1 files changed, 1145 insertions, 0 deletions
diff --git a/test/jake2/qcommon/TestMD4.java b/test/jake2/qcommon/TestMD4.java
new file mode 100644
index 0000000..9b86058
--- /dev/null
+++ b/test/jake2/qcommon/TestMD4.java
@@ -0,0 +1,1145 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+// Created on 02.02.2004 by RST.
+// $Id: TestMD4.java,v 1.1 2004-07-07 19:59:57 hzi Exp $
+
+package jake2.qcommon;
+
+import jake2.*;
+import jake2.client.*;
+import jake2.game.*;
+import jake2.render.*;
+import jake2.server.*;
+import jake2.util.Lib;
+
+//
+//
+//
+//
+//Network Working Group R. Rivest
+//Request for Comments: 1320 MIT Laboratory for Computer Science
+//Obsoletes: RFC 1186 and RSA Data Security, Inc.
+// April 1992
+//
+//
+// The MD4 Message-Digest Algorithm
+//
+//Status of thie Memo
+//
+// This memo provides information for the Internet community. It does
+// not specify an Internet standard. Distribution of this memo is
+// unlimited.
+//
+//Acknowlegements
+//
+// We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
+// and Noam Nisan for numerous helpful comments and suggestions.
+//
+//Table of Contents
+//
+// 1. Executive Summary 1
+// 2. Terminology and Notation 2
+// 3. MD4 Algorithm Description 2
+// 4. Summary 6
+// References 6
+// APPENDIX A - Reference Implementation 6
+// Security Considerations 20
+// Author's Address 20
+//
+//1. Executive Summary
+//
+// This document describes the MD4 message-digest algorithm [1]. The
+// algorithm takes as input a 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 intended for digital signature applications, where a
+// large file must be "compressed" in a secure manner before being
+// encrypted with a private (secret) key under a public-key cryptosystem
+// such as RSA.
+//
+// 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.
+//
+//
+//
+//
+//
+//Rivest [Page 1]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// The MD4 algorithm is being placed in the public domain for review and
+// possible adoption as a standard.
+//
+// This document replaces the October 1990 RFC 1186 [2]. The main
+// difference is that the reference implementation of MD4 in the
+// appendix is more portable.
+//
+// For OSI-based applications, MD4's object identifier is
+//
+// md4 OBJECT IDENTIFIER ::=
+// {iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 4}
+//
+// In the X.509 type AlgorithmIdentifier [3], the parameters for MD4
+// should have type NULL.
+//
+//2. Terminology and Notation
+//
+// In this document a "word" is a 32-bit quantity and a "byte" is an
+// eight-bit quantity. A sequence of bits can be interpreted in a
+// natural manner as a sequence of bytes, where each consecutive group
+// of eight 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 four 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
+// eight, and it may be arbitrarily large. We imagine the bits of the
+// message written down as follows:
+//
+// m_0 m_1 ... m_{b-1}
+//
+//
+//
+//
+//Rivest [Page 2]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// 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.
+//
+// Padding is performed as follows: a single "1" bit is appended to the
+// message, and then "0" bits are appended so that the length in bits of
+// the padded message becomes congruent to 448, modulo 512. In all, at
+// least one bit and at most 512 bits are appended.
+//
+//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 four-word buffer (A,B,C,D) is used to compute the message digest.
+// Here each of A, B, C, D is a 32-bit register. 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
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//Rivest [Page 3]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//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" bits 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 "1" bit in that bit position, else G has
+// a "0" bit. 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:
+//
+// Process each 16-word block. */
+// For i = 0 to N/16-1 do
+//
+// /* Copy block i into X. */
+// For j = 0 to 15 do
+// 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. */
+// AA = A
+// BB = B
+// CC = C
+// DD = D
+//
+// /* Round 1. */
+// /* Let [abcd k s] denote the operation
+// a = (a + F(b,c,d) + X[k]) <<< s. */
+// /* Do the following 16 operations. */
+// [ABCD 0 3] [DABC 1 7] [CDAB 2 11] [BCDA 3 19]
+// [ABCD 4 3] [DABC 5 7] [CDAB 6 11] [BCDA 7 19]
+// [ABCD 8 3] [DABC 9 7] [CDAB 10 11] [BCDA 11 19]
+// [ABCD 12 3] [DABC 13 7] [CDAB 14 11] [BCDA 15 19]
+//
+// /* Round 2. */
+// /* Let [abcd k s] denote the operation
+// a = (a + G(b,c,d) + X[k] + 5A827999) <<< s. */
+//
+//
+//
+//Rivest [Page 4]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// /* Do the following 16 operations. */
+// [ABCD 0 3] [DABC 4 5] [CDAB 8 9] [BCDA 12 13]
+// [ABCD 1 3] [DABC 5 5] [CDAB 9 9] [BCDA 13 13]
+// [ABCD 2 3] [DABC 6 5] [CDAB 10 9] [BCDA 14 13]
+// [ABCD 3 3] [DABC 7 5] [CDAB 11 9] [BCDA 15 13]
+//
+// /* Round 3. */
+// /* Let [abcd k s] denote the operation
+// a = (a + H(b,c,d) + X[k] + 6ED9EBA1) <<< s. */
+// /* Do the following 16 operations. */
+// [ABCD 0 3] [DABC 8 9] [CDAB 4 11] [BCDA 12 15]
+// [ABCD 2 3] [DABC 10 9] [CDAB 6 11] [BCDA 14 15]
+// [ABCD 1 3] [DABC 9 9] [CDAB 5 11] [BCDA 13 15]
+// [ABCD 3 3] [DABC 11 9] [CDAB 7 11] [BCDA 15 15]
+//
+// /* Then perform the following additions. (That is, increment each
+// of the four registers by the value it had before this block
+// was started.) */
+// A = A + AA
+// B = B + BB
+// C = C + CC
+// D = D + DD
+//
+// end /* of loop on i */
+//
+// Note. 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.
+//
+// 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.
+//
+//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]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//4. 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.
+//
+//References
+//
+// [1] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes
+// and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90
+// Proceedings, pages 303-311, Springer-Verlag, 1991.
+//
+// [2] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1186, MIT,
+// October 1990.
+//
+// [3] CCITT Recommendation X.509 (1988), "The Directory -
+// Authentication Framework".
+//
+// [4] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, MIT and
+// RSA Data Security, Inc, April 1992.
+//
+//APPENDIX A - Reference Implementation
+//
+// This appendix contains the following files:
+//
+// global.h -- global header file
+//
+// md4.h -- header file for MD4
+//
+// md4c.c -- source code for MD4
+//
+// mddriver.c -- test driver for MD2, MD4 and MD5
+//
+// The driver compiles for MD5 by default but can compile for MD2 or MD4
+// if the symbol MD is defined on the C compiler command line as 2 or 4.
+//
+// The implementation is portable and should work on many different
+// plaforms. However, it is not difficult to optimize the implementation
+// on particular platforms, an exercise left to the reader. For example,
+// on "little-endian" platforms where the lowest-addressed byte in a 32-
+// bit word is the least significant and there are no alignment
+// restrictions, the call to Decode in MD4Transform can be replaced with
+//
+//
+//
+//Rivest [Page 6]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// a typecast.
+//
+//A.1 global.h
+//
+///* GLOBAL.H - RSAREF types and constants
+// */
+//
+///* PROTOTYPES should be set to one if and only if the compiler supports
+// function argument prototyping.
+// The following makes PROTOTYPES default to 0 if it has not already
+// been defined with C compiler flags.
+// */
+//#ifndef PROTOTYPES
+//#define PROTOTYPES 0
+//#endif
+//
+///* POINTER defines a generic pointer type */
+//typedef unsigned char *POINTER;
+//
+///* UINT2 defines a two byte word */
+//typedef unsigned short int UINT2;
+//
+///* UINT4 defines a four byte word */
+//typedef unsigned long int UINT4;
+//
+///* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+// If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+// returns an empty list.
+// */
+//
+//#if PROTOTYPES
+//#define PROTO_LIST(list) list
+//#else
+//#define PROTO_LIST(list) ()
+//#endif
+//
+//A.2 md4.h
+//
+///* MD4.H - header file for MD4C.C
+// */
+//
+///* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. 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.
+//
+//
+//
+//Rivest [Page 7]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// 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.
+// */
+//
+///* MD4 context. */
+//typedef struct {
+// UINT4 state[4]; /* state (ABCD) */
+// UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+// unsigned char buffer[64]; /* input buffer */
+//} MD4_CTX;
+//
+//void MD4Init PROTO_LIST ((MD4_CTX *));
+//void MD4Update PROTO_LIST
+// ((MD4_CTX *, unsigned char *, unsigned int));
+//void MD4Final PROTO_LIST ((unsigned char [16], MD4_CTX *));
+//
+//A.3 md4c.c
+//
+///* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
+// */
+//
+///* Copyright (C) 1990-2, 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.
+//
+//
+//
+//
+//Rivest [Page 8]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// These notices must be retained in any copies of any part of this
+// documentation and/or software.
+// */
+//
+//#include "global.h"
+//#include "md4.h"
+//
+///* Constants for MD4Transform routine.
+// */
+//#define S11 3
+//#define S12 7
+//#define S13 11
+//#define S14 19
+//#define S21 3
+//#define S22 5
+//#define S23 9
+//#define S24 13
+//#define S31 3
+//#define S32 9
+//#define S33 11
+//#define S34 15
+//
+//static void MD4Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+//static void Encode PROTO_LIST
+// ((unsigned char *, UINT4 *, unsigned int));
+//static void Decode PROTO_LIST
+// ((UINT4 *, unsigned char *, unsigned int));
+//static void MD4_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+//static void MD4_memset PROTO_LIST ((POINTER, int, unsigned int));
+//
+//static unsigned char PADDING[64] = {
+// 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+//};
+//
+///* F, G and H are basic MD4 functions.
+// */
+//#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 transformations for rounds 1, 2 and 3 */
+///* Rotation is separate from addition to prevent recomputation */
+//
+//
+//
+//Rivest [Page 9]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//#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)0x5a827999; \
+// (a) = ROTATE_LEFT ((a), (s)); \
+// }
+//#define HH(a, b, c, d, x, s) { \
+// (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
+// (a) = ROTATE_LEFT ((a), (s)); \
+// }
+//
+///* MD4 initialization. Begins an MD4 operation, writing a new context.
+// */
+//void MD4Init (context)
+//MD4_CTX *context; /* context */
+//{
+// context->count[0] = context->count[1] = 0;
+//
+// /* Load magic initialization constants.
+// */
+// context->state[0] = 0x67452301;
+// context->state[1] = 0xefcdab89;
+// context->state[2] = 0x98badcfe;
+// context->state[3] = 0x10325476;
+//}
+//
+///* MD4 block update operation. Continues an MD4 message-digest
+// operation, processing another message block, and updating the
+// context.
+// */
+//void MD4Update (context, input, inputLen)
+//MD4_CTX *context; /* context */
+//unsigned char *input; /* input block */
+//unsigned int inputLen; /* length of input block */
+//{
+// unsigned int i, index, partLen;
+//
+// /* Compute number of bytes mod 64 */
+// index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+// /* Update number of bits */
+// if ((context->count[0] += ((UINT4)inputLen << 3))
+// < ((UINT4)inputLen << 3))
+// context->count[1]++;
+// context->count[1] += ((UINT4)inputLen >> 29);
+//
+// partLen = 64 - index;
+//
+//
+//
+//Rivest [Page 10]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// /* Transform as many times as possible.
+// */
+// if (inputLen >= partLen) {
+// MD4_memcpy
+// ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+// MD4Transform (context->state, context->buffer);
+//
+// for (i = partLen; i + 63 < inputLen; i += 64)
+// MD4Transform (context->state, &input[i]);
+//
+// index = 0;
+// }
+// else
+// i = 0;
+//
+// /* Buffer remaining input */
+// MD4_memcpy
+// ((POINTER)&context->buffer[index], (POINTER)&input[i],
+// inputLen-i);
+//}
+//
+///* MD4 finalization. Ends an MD4 message-digest operation, writing the
+// the message digest and zeroizing the context.
+// */
+//void MD4Final (digest, context)
+//unsigned char digest[16]; /* message digest */
+//MD4_CTX *context; /* context */
+//{
+// unsigned char bits[8];
+// unsigned int index, padLen;
+//
+// /* Save number of bits */
+// Encode (bits, context->count, 8);
+//
+// /* Pad out to 56 mod 64.
+// */
+// index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+// padLen = (index < 56) ? (56 - index) : (120 - index);
+// MD4Update (context, PADDING, padLen);
+//
+// /* Append length (before padding) */
+// MD4Update (context, bits, 8);
+// /* Store state in digest */
+// Encode (digest, context->state, 16);
+//
+// /* Zeroize sensitive information.
+// */
+// MD4_memset ((POINTER)context, 0, sizeof (*context));
+//
+//
+//
+//Rivest [Page 11]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//}
+//
+///* MD4 basic transformation. Transforms state based on block.
+// */
+//static void MD4Transform (state, block)
+//UINT4 state[4];
+//unsigned char block[64];
+//{
+// UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+//
+// Decode (x, block, 64);
+//
+// /* Round 1 */
+// FF (a, b, c, d, x[ 0], S11); /* 1 */
+// FF (d, a, b, c, x[ 1], S12); /* 2 */
+// FF (c, d, a, b, x[ 2], S13); /* 3 */
+// FF (b, c, d, a, x[ 3], S14); /* 4 */
+// FF (a, b, c, d, x[ 4], S11); /* 5 */
+// FF (d, a, b, c, x[ 5], S12); /* 6 */
+// FF (c, d, a, b, x[ 6], S13); /* 7 */
+// FF (b, c, d, a, x[ 7], S14); /* 8 */
+// FF (a, b, c, d, x[ 8], S11); /* 9 */
+// FF (d, a, b, c, x[ 9], S12); /* 10 */
+// FF (c, d, a, b, x[10], S13); /* 11 */
+// FF (b, c, d, a, x[11], S14); /* 12 */
+// FF (a, b, c, d, x[12], S11); /* 13 */
+// FF (d, a, b, c, x[13], S12); /* 14 */
+// FF (c, d, a, b, x[14], S13); /* 15 */
+// FF (b, c, d, a, x[15], S14); /* 16 */
+//
+// /* Round 2 */
+// GG (a, b, c, d, x[ 0], S21); /* 17 */
+// GG (d, a, b, c, x[ 4], S22); /* 18 */
+// GG (c, d, a, b, x[ 8], S23); /* 19 */
+// GG (b, c, d, a, x[12], S24); /* 20 */
+// GG (a, b, c, d, x[ 1], S21); /* 21 */
+// GG (d, a, b, c, x[ 5], S22); /* 22 */
+// GG (c, d, a, b, x[ 9], S23); /* 23 */
+// GG (b, c, d, a, x[13], S24); /* 24 */
+// GG (a, b, c, d, x[ 2], S21); /* 25 */
+// GG (d, a, b, c, x[ 6], S22); /* 26 */
+// GG (c, d, a, b, x[10], S23); /* 27 */
+// GG (b, c, d, a, x[14], S24); /* 28 */
+// GG (a, b, c, d, x[ 3], S21); /* 29 */
+// GG (d, a, b, c, x[ 7], S22); /* 30 */
+// GG (c, d, a, b, x[11], S23); /* 31 */
+// GG (b, c, d, a, x[15], S24); /* 32 */
+//
+//
+//
+//
+//Rivest [Page 12]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// /* Round 3 */
+// HH (a, b, c, d, x[ 0], S31); /* 33 */
+// HH (d, a, b, c, x[ 8], S32); /* 34 */
+// HH (c, d, a, b, x[ 4], S33); /* 35 */
+// HH (b, c, d, a, x[12], S34); /* 36 */
+// HH (a, b, c, d, x[ 2], S31); /* 37 */
+// HH (d, a, b, c, x[10], S32); /* 38 */
+// HH (c, d, a, b, x[ 6], S33); /* 39 */
+// HH (b, c, d, a, x[14], S34); /* 40 */
+// HH (a, b, c, d, x[ 1], S31); /* 41 */
+// HH (d, a, b, c, x[ 9], S32); /* 42 */
+// HH (c, d, a, b, x[ 5], S33); /* 43 */
+// HH (b, c, d, a, x[13], S34); /* 44 */
+// HH (a, b, c, d, x[ 3], S31); /* 45 */
+// HH (d, a, b, c, x[11], S32); /* 46 */
+// HH (c, d, a, b, x[ 7], S33); /* 47 */
+// HH (b, c, d, a, x[15], S34); /* 48 */
+//
+// state[0] += a;
+// state[1] += b;
+// state[2] += c;
+// state[3] += d;
+//
+// /* Zeroize sensitive information.
+// */
+// MD4_memset ((POINTER)x, 0, sizeof (x));
+//}
+//
+///* Encodes input (UINT4) into output (unsigned char). Assumes len is
+// a multiple of 4.
+// */
+//static void Encode (output, input, len)
+//unsigned char *output;
+//UINT4 *input;
+//unsigned int len;
+//{
+// unsigned int i, j;
+//
+// for (i = 0, j = 0; j < len; i++, j += 4) {
+// output[j] = (unsigned char)(input[i] & 0xff);
+// output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+// output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+// output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+// }
+//}
+//
+///* Decodes input (unsigned char) into output (UINT4). Assumes len is
+// a multiple of 4.
+//
+//
+//
+//Rivest [Page 13]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// */
+//static void Decode (output, input, len)
+//
+//UINT4 *output;
+//unsigned char *input;
+//unsigned int len;
+//{
+// unsigned int i, j;
+//
+// for (i = 0, j = 0; j < len; i++, j += 4)
+// output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+// (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+//}
+//
+///* Note: Replace "for loop" with standard memcpy if possible.
+// */
+//static void MD4_memcpy (output, input, len)
+//POINTER output;
+//POINTER input;
+//unsigned int len;
+//{
+// unsigned int i;
+//
+// for (i = 0; i < len; i++)
+// output[i] = input[i];
+//}
+//
+///* Note: Replace "for loop" with standard memset if possible.
+// */
+//static void MD4_memset (output, value, len)
+//POINTER output;
+//int value;
+//unsigned int len;
+//{
+// unsigned int i;
+//
+// for (i = 0; i < len; i++)
+// ((char *)output)[i] = (char)value;
+//}
+//
+//A.4 mddriver.c
+//
+///* MDDRIVER.C - test driver for MD2, MD4 and MD5
+// */
+//
+///* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+// rights reserved.
+//
+//
+//
+//
+//Rivest [Page 14]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// 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.
+//
+// */
+//
+///* The following makes MD default to MD5 if it has not already been
+// defined with C compiler flags.
+// */
+//#ifndef MD
+//#define MD MD5
+//#endif
+//
+//#include <stdio.h>
+//#include <time.h>
+//#include <string.h>
+//#include "global.h"
+//#if MD == 2
+//#include "md2.h"
+//#endif
+//#if MD == 4
+//#include "md4.h"
+//#endif
+//#if MD == 5
+//#include "md5.h"
+//#endif
+//
+///* Length of test block, number of test blocks.
+// */
+//#define TEST_BLOCK_LEN 1000
+//#define TEST_BLOCK_COUNT 1000
+//
+//static void MDString PROTO_LIST ((char *));
+//static void MDTimeTrial PROTO_LIST ((void));
+//static void MDTestSuite PROTO_LIST ((void));
+//static void MDFile PROTO_LIST ((char *));
+//static void MDFilter PROTO_LIST ((void));
+//static void MDPrint PROTO_LIST ((unsigned char [16]));
+//
+//#if MD == 2
+//#define MD_CTX MD2_CTX
+//#define MDInit MD2Init
+//#define MDUpdate MD2Update
+//#define MDFinal MD2Final
+//
+//
+//
+//Rivest [Page 15]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//#endif
+//#if MD == 4
+//#define MD_CTX MD4_CTX
+//#define MDInit MD4Init
+//#define MDUpdate MD4Update
+//#define MDFinal MD4Final
+//#endif
+//#if MD == 5
+//#define MD_CTX MD5_CTX
+//#define MDInit MD5Init
+//#define MDUpdate MD5Update
+//#define MDFinal MD5Final
+//#endif
+//
+///* Main driver.
+//
+// Arguments (may be any combination):
+// -sstring - digests string
+// -t - runs time trial
+// -x - runs test script
+// filename - digests file
+// (none) - digests standard input
+// */
+//int main (argc, argv)
+//int argc;
+//char *argv[];
+//{
+// int i;
+//
+// if (argc > 1)
+// 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]);
+// else
+// MDFilter ();
+//
+// return (0);
+//}
+//
+///* Digests a string and prints the result.
+// */
+//static void MDString (string)
+//
+//
+//
+//Rivest [Page 16]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//char *string;
+//{
+// MD_CTX context;
+// unsigned char digest[16];
+// unsigned int len = strlen (string);
+//
+// MDInit (&context);
+// MDUpdate (&context, string, len);
+// MDFinal (digest, &context);
+//
+// printf ("MD%d (\"%s\") = ", MD, string);
+// MDPrint (digest);
+// printf ("\n");
+//}
+//
+///* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
+// blocks.
+// */
+//static void MDTimeTrial ()
+//{
+// MD_CTX context;
+// time_t endTime, startTime;
+// unsigned char block[TEST_BLOCK_LEN], digest[16];
+// unsigned int i;
+//
+// printf
+// ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
+// TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
+//
+// /* Initialize block */
+// for (i = 0; i < TEST_BLOCK_LEN; i++)
+// block[i] = (unsigned char)(i & 0xff);
+//
+// /* Start timer */
+// time (&startTime);
+//
+// /* Digest blocks */
+// MDInit (&context);
+// for (i = 0; i < TEST_BLOCK_COUNT; i++)
+// MDUpdate (&context, block, TEST_BLOCK_LEN);
+// MDFinal (digest, &context);
+//
+// /* Stop timer */
+// time (&endTime);
+//
+// printf (" done\n");
+// printf ("Digest = ");
+// MDPrint (digest);
+//
+//
+//
+//Rivest [Page 17]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
+// printf
+// ("Speed = %ld bytes/second\n",
+// (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
+//}
+//
+///* Digests a reference suite of strings and prints the results.
+// */
+//static void MDTestSuite ()
+//{
+// printf ("MD%d test suite:\n", MD);
+//
+// MDString ("");
+// MDString ("a");
+// MDString ("abc");
+// MDString ("message digest");
+// MDString ("abcdefghijklmnopqrstuvwxyz");
+// MDString
+// ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+// MDString
+//
+// ("1234567890123456789012345678901234567890\
+//1234567890123456789012345678901234567890");
+//}
+//
+///* Digests a file and prints the result.
+// */
+//static void MDFile (filename)
+//char *filename;
+//{
+// FILE *file;
+// MD_CTX context;
+// int len;
+// unsigned char buffer[1024], digest[16];
+//
+// if ((file = fopen (filename, "r")) == NULL)
+// printf ("%s can't be opened\n", filename);
+//
+// else {
+// MDInit (&context);
+// while (len = fread (buffer, 1, 1024, file))
+// MDUpdate (&context, buffer, len);
+// MDFinal (digest, &context);
+//
+// fclose (file);
+//
+// printf ("MD%d (%s) = ", MD, filename);
+// MDPrint (digest);
+//
+//
+//
+//Rivest [Page 18]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+// printf ("\n");
+// }
+//}
+//
+///* Digests the standard input and prints the result.
+// */
+//static void MDFilter ()
+//{
+// MD_CTX context;
+// int len;
+// unsigned char buffer[16], digest[16];
+//
+// MDInit (&context);
+// while (len = fread (buffer, 1, 16, stdin))
+// MDUpdate (&context, buffer, len);
+// MDFinal (digest, &context);
+//
+// MDPrint (digest);
+// printf ("\n");
+//}
+//
+///* Prints a message digest in hexadecimal.
+// */
+//static void MDPrint (digest)
+//unsigned char digest[16];
+//
+//{
+// unsigned int i;
+//
+// for (i = 0; i < 16; i++)
+// printf ("%02x", digest[i]);
+//}
+//
+//A.5 Test suite
+//
+// The MD4 test suite (driver option "-x") should print the following
+// results:
+//
+//MD4 test suite:
+//MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
+//MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
+//MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
+//MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
+//MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
+//MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+//043f8582f241db351ce627e153e7f0e4
+//MD4 ("123456789012345678901234567890123456789012345678901234567890123456
+//78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
+//
+//
+//
+//Rivest [Page 19]
+//
+//RFC 1320 MD4 Message-Digest Algorithm April 1992
+//
+//
+//Security Considerations
+//
+// The level of security discussed in this memo is considered to be
+// sufficient for implementing moderate security hybrid digital-
+// signature schemes based on MD4 and a public-key cryptosystem. We do
+// not know of any reason that MD4 would not be sufficient for
+// implementing very high security digital-signature schemes, but
+// because MD4 was designed to be exceptionally fast, it is "at the
+// edge" in terms of risking successful cryptanalytic attack. After
+// further critical review, it may be appropriate to consider MD4 for
+// very high security applications. For very high security applications
+// before the completion of that review, the MD5 algorithm [4] is
+// recommended.
+//
+//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
+//
+
+
+public class TestMD4 {
+ public static void main(String args[]) {
+ test("");
+ test("a");
+ test("abc");
+ test("abcdefghijklmnopqrstuvwxyz");
+ test("hi");
+ }
+
+ public static void test(String s) {
+ MD4 md4 = new MD4();
+
+ md4.engineUpdate(s.getBytes(), 0, s.length());
+ System.out.println("\"" + s + "\"");
+ System.out.print(Lib.hexDump(md4.engineDigest(), 16, false));
+ }
+}