Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / security / hash / MD4.java
bloba09eb1705543141a34ed08f3034290f9eb3ff6c1
1 /* MD4.java --
2 Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
4 This file is a part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.security.hash;
41 import gnu.java.security.Registry;
42 import gnu.java.security.util.Util;
44 /**
45 * <p>An implementation of Ron Rivest's MD4 message digest algorithm.</p>
47 * <p>MD4 was the precursor to the stronger {@link gnu.crypto.hash.MD5}
48 * algorithm, and while not considered cryptograpically secure itself, MD4 is
49 * in use in various applications. It is slightly faster than MD5.</p>
51 * <p>References:</p>
53 * <ol>
54 * <li>The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a>
55 * Message-Digest Algorithm.<br>
56 * R. Rivest.</li>
57 * </ol>
59 * @author Casey Marshall (rsdio@metastatic.org)
61 public class MD4 extends BaseHash
64 // Constants and variables
65 // -------------------------------------------------------------------------
67 /** An MD4 message digest is always 128-bits long, or 16 bytes. */
68 private static final int DIGEST_LENGTH = 16;
70 /** The MD4 algorithm operates on 512-bit blocks, or 64 bytes. */
71 private static final int BLOCK_LENGTH = 64;
73 private static final int A = 0x67452301;
75 private static final int B = 0xefcdab89;
77 private static final int C = 0x98badcfe;
79 private static final int D = 0x10325476;
81 /** The output of this message digest when no data has been input. */
82 private static final String DIGEST0 = "31D6CFE0D16AE931B73C59D7E0C089C0";
84 /** caches the result of the correctness test, once executed. */
85 private static Boolean valid;
87 private int a, b, c, d;
89 // Constructor(s)
90 // -------------------------------------------------------------------------
92 /**
93 * <p>Public constructor. Initializes the chaining variables, sets the byte
94 * count to <code>0</code>, and creates a new block of <code>512</code> bits.
95 * </p>
97 public MD4()
99 super(Registry.MD4_HASH, DIGEST_LENGTH, BLOCK_LENGTH);
103 * <p>Trivial private constructor for cloning purposes.</p>
105 * @param that the instance to clone.
107 private MD4(MD4 that)
109 this();
111 this.a = that.a;
112 this.b = that.b;
113 this.c = that.c;
114 this.d = that.d;
115 this.count = that.count;
116 this.buffer = (byte[]) that.buffer.clone();
119 // Class methods
120 // -------------------------------------------------------------------------
122 // Instance methods
123 // -------------------------------------------------------------------------
125 // java.lang.Cloneable interface implementation ----------------------------
127 public Object clone()
129 return new MD4(this);
132 // Implementation of abstract methods in BashHash --------------------------
134 protected byte[] getResult()
136 byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16),
137 (byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
138 (byte) (b >>> 16), (byte) (b >>> 24), (byte) c,
139 (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
140 (byte) d, (byte) (d >>> 8), (byte) (d >>> 16),
141 (byte) (d >>> 24) };
142 return digest;
145 protected void resetContext()
147 a = A;
148 b = B;
149 c = C;
150 d = D;
153 public boolean selfTest()
155 if (valid == null)
157 valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD4().digest())));
159 return valid.booleanValue();
162 protected byte[] padBuffer()
164 int n = (int) (count % BLOCK_LENGTH);
165 int padding = (n < 56) ? (56 - n) : (120 - n);
166 byte[] pad = new byte[padding + 8];
168 pad[0] = (byte) 0x80;
169 long bits = count << 3;
170 pad[padding++] = (byte) bits;
171 pad[padding++] = (byte) (bits >>> 8);
172 pad[padding++] = (byte) (bits >>> 16);
173 pad[padding++] = (byte) (bits >>> 24);
174 pad[padding++] = (byte) (bits >>> 32);
175 pad[padding++] = (byte) (bits >>> 40);
176 pad[padding++] = (byte) (bits >>> 48);
177 pad[padding] = (byte) (bits >>> 56);
179 return pad;
182 protected void transform(byte[] in, int i)
184 int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
185 | in[i++] << 24;
186 int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
187 | in[i++] << 24;
188 int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
189 | in[i++] << 24;
190 int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
191 | in[i++] << 24;
192 int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
193 | in[i++] << 24;
194 int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
195 | in[i++] << 24;
196 int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
197 | in[i++] << 24;
198 int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
199 | in[i++] << 24;
200 int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
201 | in[i++] << 24;
202 int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
203 | in[i++] << 24;
204 int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
205 | in[i++] << 24;
206 int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
207 | in[i++] << 24;
208 int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
209 | in[i++] << 24;
210 int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
211 | in[i++] << 24;
212 int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
213 | in[i++] << 24;
214 int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
215 | in[i] << 24;
217 int aa, bb, cc, dd;
219 aa = a;
220 bb = b;
221 cc = c;
222 dd = d;
224 aa += ((bb & cc) | ((~bb) & dd)) + X0;
225 aa = aa << 3 | aa >>> -3;
226 dd += ((aa & bb) | ((~aa) & cc)) + X1;
227 dd = dd << 7 | dd >>> -7;
228 cc += ((dd & aa) | ((~dd) & bb)) + X2;
229 cc = cc << 11 | cc >>> -11;
230 bb += ((cc & dd) | ((~cc) & aa)) + X3;
231 bb = bb << 19 | bb >>> -19;
232 aa += ((bb & cc) | ((~bb) & dd)) + X4;
233 aa = aa << 3 | aa >>> -3;
234 dd += ((aa & bb) | ((~aa) & cc)) + X5;
235 dd = dd << 7 | dd >>> -7;
236 cc += ((dd & aa) | ((~dd) & bb)) + X6;
237 cc = cc << 11 | cc >>> -11;
238 bb += ((cc & dd) | ((~cc) & aa)) + X7;
239 bb = bb << 19 | bb >>> -19;
240 aa += ((bb & cc) | ((~bb) & dd)) + X8;
241 aa = aa << 3 | aa >>> -3;
242 dd += ((aa & bb) | ((~aa) & cc)) + X9;
243 dd = dd << 7 | dd >>> -7;
244 cc += ((dd & aa) | ((~dd) & bb)) + X10;
245 cc = cc << 11 | cc >>> -11;
246 bb += ((cc & dd) | ((~cc) & aa)) + X11;
247 bb = bb << 19 | bb >>> -19;
248 aa += ((bb & cc) | ((~bb) & dd)) + X12;
249 aa = aa << 3 | aa >>> -3;
250 dd += ((aa & bb) | ((~aa) & cc)) + X13;
251 dd = dd << 7 | dd >>> -7;
252 cc += ((dd & aa) | ((~dd) & bb)) + X14;
253 cc = cc << 11 | cc >>> -11;
254 bb += ((cc & dd) | ((~cc) & aa)) + X15;
255 bb = bb << 19 | bb >>> -19;
257 aa += ((bb & (cc | dd)) | (cc & dd)) + X0 + 0x5a827999;
258 aa = aa << 3 | aa >>> -3;
259 dd += ((aa & (bb | cc)) | (bb & cc)) + X4 + 0x5a827999;
260 dd = dd << 5 | dd >>> -5;
261 cc += ((dd & (aa | bb)) | (aa & bb)) + X8 + 0x5a827999;
262 cc = cc << 9 | cc >>> -9;
263 bb += ((cc & (dd | aa)) | (dd & aa)) + X12 + 0x5a827999;
264 bb = bb << 13 | bb >>> -13;
265 aa += ((bb & (cc | dd)) | (cc & dd)) + X1 + 0x5a827999;
266 aa = aa << 3 | aa >>> -3;
267 dd += ((aa & (bb | cc)) | (bb & cc)) + X5 + 0x5a827999;
268 dd = dd << 5 | dd >>> -5;
269 cc += ((dd & (aa | bb)) | (aa & bb)) + X9 + 0x5a827999;
270 cc = cc << 9 | cc >>> -9;
271 bb += ((cc & (dd | aa)) | (dd & aa)) + X13 + 0x5a827999;
272 bb = bb << 13 | bb >>> -13;
273 aa += ((bb & (cc | dd)) | (cc & dd)) + X2 + 0x5a827999;
274 aa = aa << 3 | aa >>> -3;
275 dd += ((aa & (bb | cc)) | (bb & cc)) + X6 + 0x5a827999;
276 dd = dd << 5 | dd >>> -5;
277 cc += ((dd & (aa | bb)) | (aa & bb)) + X10 + 0x5a827999;
278 cc = cc << 9 | cc >>> -9;
279 bb += ((cc & (dd | aa)) | (dd & aa)) + X14 + 0x5a827999;
280 bb = bb << 13 | bb >>> -13;
281 aa += ((bb & (cc | dd)) | (cc & dd)) + X3 + 0x5a827999;
282 aa = aa << 3 | aa >>> -3;
283 dd += ((aa & (bb | cc)) | (bb & cc)) + X7 + 0x5a827999;
284 dd = dd << 5 | dd >>> -5;
285 cc += ((dd & (aa | bb)) | (aa & bb)) + X11 + 0x5a827999;
286 cc = cc << 9 | cc >>> -9;
287 bb += ((cc & (dd | aa)) | (dd & aa)) + X15 + 0x5a827999;
288 bb = bb << 13 | bb >>> -13;
290 aa += (bb ^ cc ^ dd) + X0 + 0x6ed9eba1;
291 aa = aa << 3 | aa >>> -3;
292 dd += (aa ^ bb ^ cc) + X8 + 0x6ed9eba1;
293 dd = dd << 9 | dd >>> -9;
294 cc += (dd ^ aa ^ bb) + X4 + 0x6ed9eba1;
295 cc = cc << 11 | cc >>> -11;
296 bb += (cc ^ dd ^ aa) + X12 + 0x6ed9eba1;
297 bb = bb << 15 | bb >>> -15;
298 aa += (bb ^ cc ^ dd) + X2 + 0x6ed9eba1;
299 aa = aa << 3 | aa >>> -3;
300 dd += (aa ^ bb ^ cc) + X10 + 0x6ed9eba1;
301 dd = dd << 9 | dd >>> -9;
302 cc += (dd ^ aa ^ bb) + X6 + 0x6ed9eba1;
303 cc = cc << 11 | cc >>> -11;
304 bb += (cc ^ dd ^ aa) + X14 + 0x6ed9eba1;
305 bb = bb << 15 | bb >>> -15;
306 aa += (bb ^ cc ^ dd) + X1 + 0x6ed9eba1;
307 aa = aa << 3 | aa >>> -3;
308 dd += (aa ^ bb ^ cc) + X9 + 0x6ed9eba1;
309 dd = dd << 9 | dd >>> -9;
310 cc += (dd ^ aa ^ bb) + X5 + 0x6ed9eba1;
311 cc = cc << 11 | cc >>> -11;
312 bb += (cc ^ dd ^ aa) + X13 + 0x6ed9eba1;
313 bb = bb << 15 | bb >>> -15;
314 aa += (bb ^ cc ^ dd) + X3 + 0x6ed9eba1;
315 aa = aa << 3 | aa >>> -3;
316 dd += (aa ^ bb ^ cc) + X11 + 0x6ed9eba1;
317 dd = dd << 9 | dd >>> -9;
318 cc += (dd ^ aa ^ bb) + X7 + 0x6ed9eba1;
319 cc = cc << 11 | cc >>> -11;
320 bb += (cc ^ dd ^ aa) + X15 + 0x6ed9eba1;
321 bb = bb << 15 | bb >>> -15;
323 a += aa;
324 b += bb;
325 c += cc;
326 d += dd;