Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / security / hash / Haval.java
blob1bf75652de7a3d0db0272b0e06aa5b299034e0ef
1 /* Haval.java --
2 Copyright (C) 2003, 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>The <i>HAVAL</i> message-digest algorithm is a variable output length,
46 * with variable number of rounds. By default, this implementation allows
47 * <i>HAVAL</i> to be used as a drop-in replacement for <i>MD5</i>.</p>
49 * <p>References:</p>
51 * <ol>
52 * <li>HAVAL - A One-Way Hashing Algorithm with Variable Length of Output<br>
53 * Advances in Cryptology - AUSCRYPT'92, Lecture Notes in Computer Science,<br>
54 * Springer-Verlag, 1993; <br>
55 * Y. Zheng, J. Pieprzyk and J. Seberry.</li>
56 * </ol>
58 public class Haval extends BaseHash
61 // Constants and variables
62 // -------------------------------------------------------------------------
64 public static final int HAVAL_VERSION = 1;
66 public static final int HAVAL_128_BIT = 16;
68 public static final int HAVAL_160_BIT = 20;
70 public static final int HAVAL_192_BIT = 24;
72 public static final int HAVAL_224_BIT = 28;
74 public static final int HAVAL_256_BIT = 32;
76 public static final int HAVAL_3_ROUND = 3;
78 public static final int HAVAL_4_ROUND = 4;
80 public static final int HAVAL_5_ROUND = 5;
82 private static final int BLOCK_SIZE = 128; // inner block size in bytes
84 private static final String DIGEST0 = "C68F39913F901F3DDF44C707357A7D70";
86 /** caches the result of the correctness test, once executed. */
87 private static Boolean valid;
89 /**
90 * Number of HAVAL rounds. Allowed values are integers in the range <code>3
91 * .. 5</code>. The default is <code>3</code>.
93 private int rounds = HAVAL_3_ROUND;
95 /** 128-bit interim result. */
96 private int h0, h1, h2, h3, h4, h5, h6, h7;
98 // Constructor(s)
99 // -------------------------------------------------------------------------
102 * <p>Calls the constructor with two argument using {@link #HAVAL_128_BIT} as
103 * the value for the output size (i.e. <code>128</code> bits, and
104 * {@link #HAVAL_3_ROUND} for the value of number of rounds.</p>
106 public Haval()
108 this(HAVAL_128_BIT, HAVAL_3_ROUND);
112 * <p>Calls the constructor with two arguments using the designated output
113 * size, and {@link #HAVAL_3_ROUND} for the value of number of rounds.</p>
115 * @param size the output size in bytes of this instance.
116 * @throws IllegalArgumentException if the designated output size is invalid.
117 * @see #HAVAL_128_BIT
118 * @see #HAVAL_160_BIT
119 * @see #HAVAL_192_BIT
120 * @see #HAVAL_224_BIT
121 * @see #HAVAL_256_BIT
123 public Haval(int size)
125 this(size, HAVAL_3_ROUND);
129 * <p>Constructs a <code>Haval</code> instance with the designated output
130 * size (in bytes). Valid output <code>size</code> values are <code>16</code>,
131 * <code>20</code>, <code>24</code>, <code>28</code> and <code>32</code>.
132 * Valid values for <code>rounds</code> are in the range <code>3..5</code>
133 * inclusive.</p>
135 * @param size the output size in bytes of this instance.
136 * @param rounds the number of rounds to apply when transforming data.
137 * @throws IllegalArgumentException if the designated output size is invalid,
138 * or if the number of rounds is invalid.
139 * @see #HAVAL_128_BIT
140 * @see #HAVAL_160_BIT
141 * @see #HAVAL_192_BIT
142 * @see #HAVAL_224_BIT
143 * @see #HAVAL_256_BIT
144 * @see #HAVAL_3_ROUND
145 * @see #HAVAL_4_ROUND
146 * @see #HAVAL_5_ROUND
148 public Haval(int size, int rounds)
150 super(Registry.HAVAL_HASH, size, BLOCK_SIZE);
152 if (size != HAVAL_128_BIT && size != HAVAL_160_BIT && size != HAVAL_192_BIT
153 && size != HAVAL_224_BIT && size != HAVAL_256_BIT)
155 throw new IllegalArgumentException("Invalid HAVAL output size");
158 if (rounds != HAVAL_3_ROUND && rounds != HAVAL_4_ROUND
159 && rounds != HAVAL_5_ROUND)
161 throw new IllegalArgumentException("Invalid HAVAL number of rounds");
164 this.rounds = rounds;
168 * <p>Private constructor for cloning purposes.</p>
170 * @param md the instance to clone.
172 private Haval(Haval md)
174 this(md.hashSize, md.rounds);
176 this.h0 = md.h0;
177 this.h1 = md.h1;
178 this.h2 = md.h2;
179 this.h3 = md.h3;
180 this.h4 = md.h4;
181 this.h5 = md.h5;
182 this.h6 = md.h6;
183 this.h7 = md.h7;
184 this.count = md.count;
185 this.buffer = (byte[]) md.buffer.clone();
188 // Constructor(s)
189 // -------------------------------------------------------------------------
191 // Class methods
192 // -------------------------------------------------------------------------
194 // Instance methods
195 // -------------------------------------------------------------------------
197 // java.lang.Cloneable interface implementation ----------------------------
199 public Object clone()
201 return new Haval(this);
204 // Implementation of concrete methods in BaseHash --------------------------
206 protected synchronized void transform(byte[] in, int i)
208 int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
209 | (in[i++] & 0xFF) << 24;
210 int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
211 | (in[i++] & 0xFF) << 24;
212 int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
213 | (in[i++] & 0xFF) << 24;
214 int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
215 | (in[i++] & 0xFF) << 24;
216 int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
217 | (in[i++] & 0xFF) << 24;
218 int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
219 | (in[i++] & 0xFF) << 24;
220 int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
221 | (in[i++] & 0xFF) << 24;
222 int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
223 | (in[i++] & 0xFF) << 24;
224 int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
225 | (in[i++] & 0xFF) << 24;
226 int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
227 | (in[i++] & 0xFF) << 24;
228 int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
229 | (in[i++] & 0xFF) << 24;
230 int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
231 | (in[i++] & 0xFF) << 24;
232 int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
233 | (in[i++] & 0xFF) << 24;
234 int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
235 | (in[i++] & 0xFF) << 24;
236 int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
237 | (in[i++] & 0xFF) << 24;
238 int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
239 | (in[i++] & 0xFF) << 24;
240 int X16 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
241 | (in[i++] & 0xFF) << 24;
242 int X17 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
243 | (in[i++] & 0xFF) << 24;
244 int X18 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
245 | (in[i++] & 0xFF) << 24;
246 int X19 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
247 | (in[i++] & 0xFF) << 24;
248 int X20 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
249 | (in[i++] & 0xFF) << 24;
250 int X21 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
251 | (in[i++] & 0xFF) << 24;
252 int X22 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
253 | (in[i++] & 0xFF) << 24;
254 int X23 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
255 | (in[i++] & 0xFF) << 24;
256 int X24 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
257 | (in[i++] & 0xFF) << 24;
258 int X25 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
259 | (in[i++] & 0xFF) << 24;
260 int X26 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
261 | (in[i++] & 0xFF) << 24;
262 int X27 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
263 | (in[i++] & 0xFF) << 24;
264 int X28 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
265 | (in[i++] & 0xFF) << 24;
266 int X29 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
267 | (in[i++] & 0xFF) << 24;
268 int X30 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
269 | (in[i++] & 0xFF) << 24;
270 int X31 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
271 | (in[i++] & 0xFF) << 24;
273 int t0 = h0, t1 = h1, t2 = h2, t3 = h3, t4 = h4, t5 = h5, t6 = h6, t7 = h7;
275 // Pass 1
276 t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X0);
277 t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X1);
278 t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X2);
279 t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X3);
280 t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X4);
281 t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X5);
282 t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X6);
283 t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X7);
285 t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X8);
286 t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X9);
287 t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X10);
288 t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X11);
289 t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X12);
290 t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X13);
291 t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X14);
292 t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X15);
294 t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X16);
295 t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X17);
296 t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X18);
297 t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X19);
298 t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X20);
299 t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X21);
300 t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X22);
301 t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X23);
303 t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X24);
304 t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X25);
305 t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X26);
306 t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X27);
307 t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X28);
308 t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X29);
309 t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X30);
310 t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X31);
312 // Pass 2
313 t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x452821E6);
314 t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0x38D01377);
315 t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X26, 0xBE5466CF);
316 t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X18, 0x34E90C6C);
317 t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X11, 0xC0AC29B7);
318 t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X28, 0xC97C50DD);
319 t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X7, 0x3F84D5B5);
320 t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X16, 0xB5470917);
322 t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X0, 0x9216D5D9);
323 t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0x8979FB1B);
324 t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X20, 0xD1310BA6);
325 t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0x98DFB5AC);
326 t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0x2FFD72DB);
327 t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xD01ADFB7);
328 t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X4, 0xB8E1AFED);
329 t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X8, 0x6A267E96);
331 t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X30, 0xBA7C9045);
332 t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0xF12C7F99);
333 t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x24A19947);
334 t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X9, 0xB3916CF7);
335 t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x0801F2E2);
336 t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X24, 0x858EFC16);
337 t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X29, 0x636920D8);
338 t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X6, 0x71574E69);
340 t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0xA458FEA3);
341 t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X12, 0xF4933D7E);
342 t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X15, 0x0D95748F);
343 t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X13, 0x728EB658);
344 t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0x718BCD58);
345 t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0x82154AEE);
346 t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x7B54A41D);
347 t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0xC25A59B5);
349 // Pass 3
350 t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x9C30D539);
351 t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x2AF26013);
352 t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X4, 0xC5D1B023);
353 t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0x286085F0);
354 t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X28, 0xCA417918);
355 t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X17, 0xB8DB38EF);
356 t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X8, 0x8E79DCB0);
357 t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X22, 0x603A180E);
359 t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X29, 0x6C9E0E8B);
360 t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0xB01E8A3E);
361 t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X25, 0xD71577C1);
362 t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X12, 0xBD314B27);
363 t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X24, 0x78AF2FDA);
364 t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X30, 0x55605C60);
365 t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0xE65525F3);
366 t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X26, 0xAA55AB94);
368 t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X31, 0x57489862);
369 t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X15, 0x63E81440);
370 t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X7, 0x55CA396A);
371 t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X3, 0x2AAB10B6);
372 t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0xB4CC5C34);
373 t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X0, 0x1141E8CE);
374 t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X18, 0xA15486AF);
375 t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0x7C72E993);
377 t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X13, 0xB3EE1411);
378 t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x636FBC2A);
379 t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x2BA9C55D);
380 t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X10, 0x741831F6);
381 t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X23, 0xCE5C3E16);
382 t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x9B87931E);
383 t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X5, 0xAFD6BA33);
384 t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X2, 0x6C24CF5C);
386 if (rounds >= 4)
388 t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X24, 0x7A325381);
389 t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X4, 0x28958677);
390 t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X0, 0x3B8F4898);
391 t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X14, 0x6B4BB9AF);
392 t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0xC4BFE81B);
393 t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X7, 0x66282193);
394 t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x61D809CC);
395 t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X23, 0xFB21A991);
396 t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X26, 0x487CAC60);
397 t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x5DEC8032);
398 t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X30, 0xEF845D5D);
399 t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0xE98575B1);
400 t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDC262302);
401 t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0xEB651B88);
402 t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X19, 0x23893E81);
403 t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X3, 0xD396ACC5);
405 t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X22, 0x0F6D6FF3);
406 t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X11, 0x83F44239);
407 t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X31, 0x2E0B4482);
408 t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X21, 0xA4842004);
409 t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X8, 0x69C8F04A);
410 t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X27, 0x9E1F9B5E);
411 t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X12, 0x21C66842);
412 t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X9, 0xF6E96C9A);
413 t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X1, 0x670C9C61);
414 t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X29, 0xABD388F0);
415 t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X5, 0x6A51A0D2);
416 t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X15, 0xD8542F68);
417 t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x960FA728);
418 t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xAB5133A3);
419 t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0x6EEF0B6C);
420 t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X13, 0x137A3BE4);
422 if (rounds == 5)
424 t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X27, 0xBA3BF050);
425 t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0x7EFB2A98);
426 t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0xA1F1651D);
427 t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X26, 0x39AF0176);
428 t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x66CA593E);
429 t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x82430E88);
430 t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X20, 0x8CEE8619);
431 t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X29, 0x456F9FB4);
433 t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x7D84A5C3);
434 t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X0, 0x3B8B5EBE);
435 t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X12, 0xE06F75D8);
436 t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X7, 0x85C12073);
437 t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X13, 0x401A449F);
438 t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X8, 0x56C16AA6);
439 t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x4ED3AA62);
440 t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X10, 0x363F7706);
442 t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x1BFEDF72);
443 t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x429B023D);
444 t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X14, 0x37D0D724);
445 t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X30, 0xD00A1248);
446 t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDB0FEAD3);
447 t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X6, 0x49F1C09B);
448 t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x075372C9);
449 t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X24, 0x80991B7B);
451 t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X2, 0x25D479D8);
452 t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0xF6E8DEF7);
453 t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X16, 0xE3FE501A);
454 t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0xB6794C3B);
455 t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X4, 0x976CE0BD);
456 t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X1, 0x04C006BA);
457 t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X25, 0xC1A94FB6);
458 t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X15, 0x409F60C4);
462 h7 += t7;
463 h6 += t6;
464 h5 += t5;
465 h4 += t4;
466 h3 += t3;
467 h2 += t2;
468 h1 += t1;
469 h0 += t0;
472 protected byte[] padBuffer()
474 // pad out to 118 mod 128. other 10 bytes have special use.
475 int n = (int) (count % BLOCK_SIZE);
476 int padding = (n < 118) ? (118 - n) : (246 - n);
477 byte[] result = new byte[padding + 10];
478 result[0] = (byte) 0x01;
480 // save the version number (LSB 3), the number of rounds (3 bits in the
481 // middle), the fingerprint length (MSB 2 bits and next byte) and the
482 // number of bits in the unpadded message.
483 int bl = hashSize * 8;
484 result[padding++] = (byte) (((bl & 0x03) << 6) | ((rounds & 0x07) << 3) | (HAVAL_VERSION & 0x07));
485 result[padding++] = (byte) (bl >>> 2);
487 // save number of bits, casting the long to an array of 8 bytes
488 long bits = count << 3;
489 result[padding++] = (byte) bits;
490 result[padding++] = (byte) (bits >>> 8);
491 result[padding++] = (byte) (bits >>> 16);
492 result[padding++] = (byte) (bits >>> 24);
493 result[padding++] = (byte) (bits >>> 32);
494 result[padding++] = (byte) (bits >>> 40);
495 result[padding++] = (byte) (bits >>> 48);
496 result[padding] = (byte) (bits >>> 56);
498 return result;
501 protected byte[] getResult()
503 tailorDigestBits(); // tailor context for the designated output size
504 // cast enough top context values into an array of hashSize bytes
505 byte[] result = new byte[hashSize];
506 if (hashSize >= HAVAL_256_BIT)
508 result[31] = (byte) (h7 >>> 24);
509 result[30] = (byte) (h7 >>> 16);
510 result[29] = (byte) (h7 >>> 8);
511 result[28] = (byte) h7;
513 if (hashSize >= HAVAL_224_BIT)
515 result[27] = (byte) (h6 >>> 24);
516 result[26] = (byte) (h6 >>> 16);
517 result[25] = (byte) (h6 >>> 8);
518 result[24] = (byte) h6;
520 if (hashSize >= HAVAL_192_BIT)
522 result[23] = (byte) (h5 >>> 24);
523 result[22] = (byte) (h5 >>> 16);
524 result[21] = (byte) (h5 >>> 8);
525 result[20] = (byte) h5;
527 if (hashSize >= HAVAL_160_BIT)
529 result[19] = (byte) (h4 >>> 24);
530 result[18] = (byte) (h4 >>> 16);
531 result[17] = (byte) (h4 >>> 8);
532 result[16] = (byte) h4;
534 result[15] = (byte) (h3 >>> 24);
535 result[14] = (byte) (h3 >>> 16);
536 result[13] = (byte) (h3 >>> 8);
537 result[12] = (byte) h3;
538 result[11] = (byte) (h2 >>> 24);
539 result[10] = (byte) (h2 >>> 16);
540 result[9] = (byte) (h2 >>> 8);
541 result[8] = (byte) h2;
542 result[7] = (byte) (h1 >>> 24);
543 result[6] = (byte) (h1 >>> 16);
544 result[5] = (byte) (h1 >>> 8);
545 result[4] = (byte) h1;
546 result[3] = (byte) (h0 >>> 24);
547 result[2] = (byte) (h0 >>> 16);
548 result[1] = (byte) (h0 >>> 8);
549 result[0] = (byte) h0;
551 return result;
554 protected void resetContext()
556 h0 = 0x243F6A88;
557 h1 = 0x85A308D3;
558 h2 = 0x13198A2E;
559 h3 = 0x03707344;
560 h4 = 0xA4093822;
561 h5 = 0x299F31D0;
562 h6 = 0x082EFA98;
563 h7 = 0xEC4E6C89;
566 public boolean selfTest()
568 if (valid == null)
570 valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Haval().digest())));
572 return valid.booleanValue();
575 // helper methods ----------------------------------------------------------
577 /** Tailors the last output. */
578 private void tailorDigestBits()
580 int t;
581 switch (hashSize)
583 case HAVAL_128_BIT:
584 t = (h7 & 0x000000FF) | (h6 & 0xFF000000) | (h5 & 0x00FF0000)
585 | (h4 & 0x0000FF00);
586 h0 += t >>> 8 | t << 24;
587 t = (h7 & 0x0000FF00) | (h6 & 0x000000FF) | (h5 & 0xFF000000)
588 | (h4 & 0x00FF0000);
589 h1 += t >>> 16 | t << 16;
590 t = (h7 & 0x00FF0000) | (h6 & 0x0000FF00) | (h5 & 0x000000FF)
591 | (h4 & 0xFF000000);
592 h2 += t >>> 24 | t << 8;
593 t = (h7 & 0xFF000000) | (h6 & 0x00FF0000) | (h5 & 0x0000FF00)
594 | (h4 & 0x000000FF);
595 h3 += t;
596 break;
597 case HAVAL_160_BIT:
598 t = (h7 & 0x3F) | (h6 & (0x7F << 25)) | (h5 & (0x3F << 19));
599 h0 += t >>> 19 | t << 13;
600 t = (h7 & (0x3F << 6)) | (h6 & 0x3F) | (h5 & (0x7F << 25));
601 h1 += t >>> 25 | t << 7;
602 t = (h7 & (0x7F << 12)) | (h6 & (0x3F << 6)) | (h5 & 0x3F);
603 h2 += t;
604 t = (h7 & (0x3F << 19)) | (h6 & (0x7F << 12)) | (h5 & (0x3F << 6));
605 h3 += (t >>> 6);
606 t = (h7 & (0x7F << 25)) | (h6 & (0x3F << 19)) | (h5 & (0x7F << 12));
607 h4 += (t >>> 12);
608 break;
609 case HAVAL_192_BIT:
610 t = (h7 & 0x1F) | (h6 & (0x3F << 26));
611 h0 += t >>> 26 | t << 6;
612 t = (h7 & (0x1F << 5)) | (h6 & 0x1F);
613 h1 += t;
614 t = (h7 & (0x3F << 10)) | (h6 & (0x1F << 5));
615 h2 += (t >>> 5);
616 t = (h7 & (0x1F << 16)) | (h6 & (0x3F << 10));
617 h3 += (t >>> 10);
618 t = (h7 & (0x1F << 21)) | (h6 & (0x1F << 16));
619 h4 += (t >>> 16);
620 t = (h7 & (0x3F << 26)) | (h6 & (0x1F << 21));
621 h5 += (t >>> 21);
622 break;
623 case HAVAL_224_BIT:
624 h0 += ((h7 >>> 27) & 0x1F);
625 h1 += ((h7 >>> 22) & 0x1F);
626 h2 += ((h7 >>> 18) & 0x0F);
627 h3 += ((h7 >>> 13) & 0x1F);
628 h4 += ((h7 >>> 9) & 0x0F);
629 h5 += ((h7 >>> 4) & 0x1F);
630 h6 += (h7 & 0x0F);
635 * Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
637 * rounds = 3: 6 5 4 3 2 1 0
638 * | | | | | | | (replaced by)
639 * phi_{3,1}: 1 0 3 5 6 2 4
640 * phi_{3,2}: 4 2 1 0 5 3 6
641 * phi_{3,3}: 6 1 2 3 4 5 0
643 * rounds = 4: 6 5 4 3 2 1 0
644 * | | | | | | | (replaced by)
645 * phi_{4,1}: 2 6 1 4 5 3 0
646 * phi_{4,2}: 3 5 2 0 1 6 4
647 * phi_{4,3}: 1 4 3 6 0 2 5
648 * phi_{4,4}: 6 4 0 5 2 1 3
650 * rounds = 5: 6 5 4 3 2 1 0
651 * | | | | | | | (replaced by)
652 * phi_{5,1}: 3 4 1 0 5 2 6
653 * phi_{5,2}: 6 2 1 0 3 4 5
654 * phi_{5,3}: 2 6 0 4 3 1 5
655 * phi_{5,4}: 1 5 3 2 0 4 6
656 * phi_{5,5}: 2 5 0 6 4 3 1
658 private int FF1(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
659 int x0, int w)
661 int t;
662 switch (rounds)
664 case 3:
665 t = f1(x1, x0, x3, x5, x6, x2, x4);
666 break;
667 case 4:
668 t = f1(x2, x6, x1, x4, x5, x3, x0);
669 break;
670 default:
671 t = f1(x3, x4, x1, x0, x5, x2, x6);
673 return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w;
676 private int FF2(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
677 int x0, int w, int c)
679 int t;
680 switch (rounds)
682 case 3:
683 t = f2(x4, x2, x1, x0, x5, x3, x6);
684 break;
685 case 4:
686 t = f2(x3, x5, x2, x0, x1, x6, x4);
687 break;
688 default:
689 t = f2(x6, x2, x1, x0, x3, x4, x5);
691 return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
694 private int FF3(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
695 int x0, int w, int c)
697 int t;
698 switch (rounds)
700 case 3:
701 t = f3(x6, x1, x2, x3, x4, x5, x0);
702 break;
703 case 4:
704 t = f3(x1, x4, x3, x6, x0, x2, x5);
705 break;
706 default:
707 t = f3(x2, x6, x0, x4, x3, x1, x5);
709 return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
712 private int FF4(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
713 int x0, int w, int c)
715 int t;
716 switch (rounds)
718 case 4:
719 t = f4(x6, x4, x0, x5, x2, x1, x3);
720 break;
721 default:
722 t = f4(x1, x5, x3, x2, x0, x4, x6);
724 return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
727 private int FF5(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
728 int x0, int w, int c)
730 int t = f5(x2, x5, x0, x6, x4, x3, x1);
731 return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
734 private int f1(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
736 return x1 & (x0 ^ x4) ^ x2 & x5 ^ x3 & x6 ^ x0;
739 private int f2(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
741 return x2 & (x1 & ~x3 ^ x4 & x5 ^ x6 ^ x0) ^ x4 & (x1 ^ x5) ^ x3 & x5 ^ x0;
744 private int f3(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
746 return x3 & (x1 & x2 ^ x6 ^ x0) ^ x1 & x4 ^ x2 & x5 ^ x0;
749 private int f4(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
751 return x4 & (x5 & ~x2 ^ x3 & ~x6 ^ x1 ^ x6 ^ x0) ^ x3 & (x1 & x2 ^ x5 ^ x6)
752 ^ x2 & x6 ^ x0;
755 private int f5(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
757 return x0 & (x1 & x2 & x3 ^ ~x5) ^ x1 & x4 ^ x2 & x5 ^ x3 & x6;