1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44:
57: public class Haval
58: extends BaseHash
59: {
60: public static final int HAVAL_VERSION = 1;
61:
62: public static final int HAVAL_128_BIT = 16;
63:
64: public static final int HAVAL_160_BIT = 20;
65:
66: public static final int HAVAL_192_BIT = 24;
67:
68: public static final int HAVAL_224_BIT = 28;
69:
70: public static final int HAVAL_256_BIT = 32;
71:
72: public static final int HAVAL_3_ROUND = 3;
73:
74: public static final int HAVAL_4_ROUND = 4;
75:
76: public static final int HAVAL_5_ROUND = 5;
77:
78: private static final int BLOCK_SIZE = 128;
79:
80: private static final String DIGEST0 = "C68F39913F901F3DDF44C707357A7D70";
81:
82:
83: private static Boolean valid;
84:
85:
90: private int rounds = HAVAL_3_ROUND;
91:
92:
93: private int h0, h1, h2, h3, h4, h5, h6, h7;
94:
95:
100: public Haval()
101: {
102: this(HAVAL_128_BIT, HAVAL_3_ROUND);
103: }
104:
105:
117: public Haval(int size)
118: {
119: this(size, HAVAL_3_ROUND);
120: }
121:
122:
142: public Haval(int size, int rounds)
143: {
144: super(Registry.HAVAL_HASH, size, BLOCK_SIZE);
145:
146: if (size != HAVAL_128_BIT
147: && size != HAVAL_160_BIT
148: && size != HAVAL_192_BIT
149: && size != HAVAL_224_BIT
150: && size != HAVAL_256_BIT)
151: throw new IllegalArgumentException("Invalid HAVAL output size");
152:
153: if (rounds != HAVAL_3_ROUND
154: && rounds != HAVAL_4_ROUND
155: && rounds != HAVAL_5_ROUND)
156: throw new IllegalArgumentException("Invalid HAVAL number of rounds");
157:
158: this.rounds = rounds;
159: }
160:
161:
166: private Haval(Haval md)
167: {
168: this(md.hashSize, md.rounds);
169:
170: this.h0 = md.h0;
171: this.h1 = md.h1;
172: this.h2 = md.h2;
173: this.h3 = md.h3;
174: this.h4 = md.h4;
175: this.h5 = md.h5;
176: this.h6 = md.h6;
177: this.h7 = md.h7;
178: this.count = md.count;
179: this.buffer = (byte[]) md.buffer.clone();
180: }
181:
182: public Object clone()
183: {
184: return new Haval(this);
185: }
186:
187: protected synchronized void transform(byte[] in, int i)
188: {
189: int X0 = (in[i++] & 0xFF)
190: | (in[i++] & 0xFF) << 8
191: | (in[i++] & 0xFF) << 16
192: | (in[i++] & 0xFF) << 24;
193: int X1 = (in[i++] & 0xFF)
194: | (in[i++] & 0xFF) << 8
195: | (in[i++] & 0xFF) << 16
196: | (in[i++] & 0xFF) << 24;
197: int X2 = (in[i++] & 0xFF)
198: | (in[i++] & 0xFF) << 8
199: | (in[i++] & 0xFF) << 16
200: | (in[i++] & 0xFF) << 24;
201: int X3 = (in[i++] & 0xFF)
202: | (in[i++] & 0xFF) << 8
203: | (in[i++] & 0xFF) << 16
204: | (in[i++] & 0xFF) << 24;
205: int X4 = (in[i++] & 0xFF)
206: | (in[i++] & 0xFF) << 8
207: | (in[i++] & 0xFF) << 16
208: | (in[i++] & 0xFF) << 24;
209: int X5 = (in[i++] & 0xFF)
210: | (in[i++] & 0xFF) << 8
211: | (in[i++] & 0xFF) << 16
212: | (in[i++] & 0xFF) << 24;
213: int X6 = (in[i++] & 0xFF)
214: | (in[i++] & 0xFF) << 8
215: | (in[i++] & 0xFF) << 16
216: | (in[i++] & 0xFF) << 24;
217: int X7 = (in[i++] & 0xFF)
218: | (in[i++] & 0xFF) << 8
219: | (in[i++] & 0xFF) << 16
220: | (in[i++] & 0xFF) << 24;
221: int X8 = (in[i++] & 0xFF)
222: | (in[i++] & 0xFF) << 8
223: | (in[i++] & 0xFF) << 16
224: | (in[i++] & 0xFF) << 24;
225: int X9 = (in[i++] & 0xFF)
226: | (in[i++] & 0xFF) << 8
227: | (in[i++] & 0xFF) << 16
228: | (in[i++] & 0xFF) << 24;
229: int X10 = (in[i++] & 0xFF)
230: | (in[i++] & 0xFF) << 8
231: | (in[i++] & 0xFF) << 16
232: | (in[i++] & 0xFF) << 24;
233: int X11 = (in[i++] & 0xFF)
234: | (in[i++] & 0xFF) << 8
235: | (in[i++] & 0xFF) << 16
236: | (in[i++] & 0xFF) << 24;
237: int X12 = (in[i++] & 0xFF)
238: | (in[i++] & 0xFF) << 8
239: | (in[i++] & 0xFF) << 16
240: | (in[i++] & 0xFF) << 24;
241: int X13 = (in[i++] & 0xFF)
242: | (in[i++] & 0xFF) << 8
243: | (in[i++] & 0xFF) << 16
244: | (in[i++] & 0xFF) << 24;
245: int X14 = (in[i++] & 0xFF)
246: | (in[i++] & 0xFF) << 8
247: | (in[i++] & 0xFF) << 16
248: | (in[i++] & 0xFF) << 24;
249: int X15 = (in[i++] & 0xFF)
250: | (in[i++] & 0xFF) << 8
251: | (in[i++] & 0xFF) << 16
252: | (in[i++] & 0xFF) << 24;
253: int X16 = (in[i++] & 0xFF)
254: | (in[i++] & 0xFF) << 8
255: | (in[i++] & 0xFF) << 16
256: | (in[i++] & 0xFF) << 24;
257: int X17 = (in[i++] & 0xFF)
258: | (in[i++] & 0xFF) << 8
259: | (in[i++] & 0xFF) << 16
260: | (in[i++] & 0xFF) << 24;
261: int X18 = (in[i++] & 0xFF)
262: | (in[i++] & 0xFF) << 8
263: | (in[i++] & 0xFF) << 16
264: | (in[i++] & 0xFF) << 24;
265: int X19 = (in[i++] & 0xFF)
266: | (in[i++] & 0xFF) << 8
267: | (in[i++] & 0xFF) << 16
268: | (in[i++] & 0xFF) << 24;
269: int X20 = (in[i++] & 0xFF)
270: | (in[i++] & 0xFF) << 8
271: | (in[i++] & 0xFF) << 16
272: | (in[i++] & 0xFF) << 24;
273: int X21 = (in[i++] & 0xFF)
274: | (in[i++] & 0xFF) << 8
275: | (in[i++] & 0xFF) << 16
276: | (in[i++] & 0xFF) << 24;
277: int X22 = (in[i++] & 0xFF)
278: | (in[i++] & 0xFF) << 8
279: | (in[i++] & 0xFF) << 16
280: | (in[i++] & 0xFF) << 24;
281: int X23 = (in[i++] & 0xFF)
282: | (in[i++] & 0xFF) << 8
283: | (in[i++] & 0xFF) << 16
284: | (in[i++] & 0xFF) << 24;
285: int X24 = (in[i++] & 0xFF)
286: | (in[i++] & 0xFF) << 8
287: | (in[i++] & 0xFF) << 16
288: | (in[i++] & 0xFF) << 24;
289: int X25 = (in[i++] & 0xFF)
290: | (in[i++] & 0xFF) << 8
291: | (in[i++] & 0xFF) << 16
292: | (in[i++] & 0xFF) << 24;
293: int X26 = (in[i++] & 0xFF)
294: | (in[i++] & 0xFF) << 8
295: | (in[i++] & 0xFF) << 16
296: | (in[i++] & 0xFF) << 24;
297: int X27 = (in[i++] & 0xFF)
298: | (in[i++] & 0xFF) << 8
299: | (in[i++] & 0xFF) << 16
300: | (in[i++] & 0xFF) << 24;
301: int X28 = (in[i++] & 0xFF)
302: | (in[i++] & 0xFF) << 8
303: | (in[i++] & 0xFF) << 16
304: | (in[i++] & 0xFF) << 24;
305: int X29 = (in[i++] & 0xFF)
306: | (in[i++] & 0xFF) << 8
307: | (in[i++] & 0xFF) << 16
308: | (in[i++] & 0xFF) << 24;
309: int X30 = (in[i++] & 0xFF)
310: | (in[i++] & 0xFF) << 8
311: | (in[i++] & 0xFF) << 16
312: | (in[i++] & 0xFF) << 24;
313: int X31 = (in[i++] & 0xFF)
314: | (in[i++] & 0xFF) << 8
315: | (in[i++] & 0xFF) << 16
316: | (in[i++] & 0xFF) << 24;
317: int t0 = h0, t1 = h1, t2 = h2, t3 = h3, t4 = h4, t5 = h5, t6 = h6, t7 = h7;
318:
319: t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X0);
320: t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X1);
321: t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X2);
322: t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X3);
323: t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X4);
324: t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X5);
325: t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X6);
326: t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X7);
327:
328: t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X8);
329: t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X9);
330: t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X10);
331: t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X11);
332: t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X12);
333: t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X13);
334: t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X14);
335: t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X15);
336:
337: t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X16);
338: t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X17);
339: t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X18);
340: t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X19);
341: t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X20);
342: t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X21);
343: t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X22);
344: t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X23);
345:
346: t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X24);
347: t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X25);
348: t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X26);
349: t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X27);
350: t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X28);
351: t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X29);
352: t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X30);
353: t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X31);
354:
355:
356: t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x452821E6);
357: t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0x38D01377);
358: t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X26, 0xBE5466CF);
359: t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X18, 0x34E90C6C);
360: t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X11, 0xC0AC29B7);
361: t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X28, 0xC97C50DD);
362: t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X7, 0x3F84D5B5);
363: t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X16, 0xB5470917);
364:
365: t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X0, 0x9216D5D9);
366: t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0x8979FB1B);
367: t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X20, 0xD1310BA6);
368: t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0x98DFB5AC);
369: t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0x2FFD72DB);
370: t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xD01ADFB7);
371: t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X4, 0xB8E1AFED);
372: t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X8, 0x6A267E96);
373:
374: t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X30, 0xBA7C9045);
375: t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0xF12C7F99);
376: t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x24A19947);
377: t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X9, 0xB3916CF7);
378: t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x0801F2E2);
379: t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X24, 0x858EFC16);
380: t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X29, 0x636920D8);
381: t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X6, 0x71574E69);
382:
383: t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0xA458FEA3);
384: t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X12, 0xF4933D7E);
385: t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X15, 0x0D95748F);
386: t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X13, 0x728EB658);
387: t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0x718BCD58);
388: t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0x82154AEE);
389: t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x7B54A41D);
390: t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0xC25A59B5);
391:
392:
393: t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x9C30D539);
394: t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x2AF26013);
395: t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X4, 0xC5D1B023);
396: t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0x286085F0);
397: t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X28, 0xCA417918);
398: t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X17, 0xB8DB38EF);
399: t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X8, 0x8E79DCB0);
400: t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X22, 0x603A180E);
401:
402: t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X29, 0x6C9E0E8B);
403: t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0xB01E8A3E);
404: t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X25, 0xD71577C1);
405: t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X12, 0xBD314B27);
406: t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X24, 0x78AF2FDA);
407: t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X30, 0x55605C60);
408: t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0xE65525F3);
409: t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X26, 0xAA55AB94);
410:
411: t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X31, 0x57489862);
412: t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X15, 0x63E81440);
413: t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X7, 0x55CA396A);
414: t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X3, 0x2AAB10B6);
415: t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0xB4CC5C34);
416: t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X0, 0x1141E8CE);
417: t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X18, 0xA15486AF);
418: t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0x7C72E993);
419:
420: t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X13, 0xB3EE1411);
421: t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x636FBC2A);
422: t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x2BA9C55D);
423: t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X10, 0x741831F6);
424: t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X23, 0xCE5C3E16);
425: t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x9B87931E);
426: t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X5, 0xAFD6BA33);
427: t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X2, 0x6C24CF5C);
428:
429: if (rounds >= 4)
430: {
431: t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X24, 0x7A325381);
432: t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X4, 0x28958677);
433: t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X0, 0x3B8F4898);
434: t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X14, 0x6B4BB9AF);
435: t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0xC4BFE81B);
436: t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X7, 0x66282193);
437: t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x61D809CC);
438: t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X23, 0xFB21A991);
439: t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X26, 0x487CAC60);
440: t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x5DEC8032);
441: t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X30, 0xEF845D5D);
442: t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0xE98575B1);
443: t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDC262302);
444: t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0xEB651B88);
445: t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X19, 0x23893E81);
446: t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X3, 0xD396ACC5);
447:
448: t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X22, 0x0F6D6FF3);
449: t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X11, 0x83F44239);
450: t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X31, 0x2E0B4482);
451: t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X21, 0xA4842004);
452: t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X8, 0x69C8F04A);
453: t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X27, 0x9E1F9B5E);
454: t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X12, 0x21C66842);
455: t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X9, 0xF6E96C9A);
456: t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X1, 0x670C9C61);
457: t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X29, 0xABD388F0);
458: t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X5, 0x6A51A0D2);
459: t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X15, 0xD8542F68);
460: t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x960FA728);
461: t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xAB5133A3);
462: t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0x6EEF0B6C);
463: t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X13, 0x137A3BE4);
464:
465: if (rounds == 5)
466: {
467: t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X27, 0xBA3BF050);
468: t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0x7EFB2A98);
469: t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0xA1F1651D);
470: t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X26, 0x39AF0176);
471: t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x66CA593E);
472: t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x82430E88);
473: t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X20, 0x8CEE8619);
474: t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X29, 0x456F9FB4);
475:
476: t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x7D84A5C3);
477: t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X0, 0x3B8B5EBE);
478: t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X12, 0xE06F75D8);
479: t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X7, 0x85C12073);
480: t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X13, 0x401A449F);
481: t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X8, 0x56C16AA6);
482: t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x4ED3AA62);
483: t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X10, 0x363F7706);
484:
485: t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x1BFEDF72);
486: t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x429B023D);
487: t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X14, 0x37D0D724);
488: t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X30, 0xD00A1248);
489: t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDB0FEAD3);
490: t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X6, 0x49F1C09B);
491: t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x075372C9);
492: t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X24, 0x80991B7B);
493:
494: t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X2, 0x25D479D8);
495: t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0xF6E8DEF7);
496: t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X16, 0xE3FE501A);
497: t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0xB6794C3B);
498: t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X4, 0x976CE0BD);
499: t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X1, 0x04C006BA);
500: t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X25, 0xC1A94FB6);
501: t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X15, 0x409F60C4);
502: }
503: }
504: h7 += t7;
505: h6 += t6;
506: h5 += t5;
507: h4 += t4;
508: h3 += t3;
509: h2 += t2;
510: h1 += t1;
511: h0 += t0;
512: }
513:
514: protected byte[] padBuffer()
515: {
516:
517: int n = (int)(count % BLOCK_SIZE);
518: int padding = (n < 118) ? (118 - n) : (246 - n);
519: byte[] result = new byte[padding + 10];
520: result[0] = (byte) 0x01;
521:
522:
523:
524: int bl = hashSize * 8;
525: int sigByte = (bl & 0x03) << 6;
526: sigByte |= (rounds & 0x07) << 3;
527: sigByte |= HAVAL_VERSION & 0x07;
528: result[padding++] = (byte) sigByte;
529: result[padding++] = (byte)(bl >>> 2);
530:
531: long bits = count << 3;
532: result[padding++] = (byte) bits;
533: result[padding++] = (byte)(bits >>> 8);
534: result[padding++] = (byte)(bits >>> 16);
535: result[padding++] = (byte)(bits >>> 24);
536: result[padding++] = (byte)(bits >>> 32);
537: result[padding++] = (byte)(bits >>> 40);
538: result[padding++] = (byte)(bits >>> 48);
539: result[padding ] = (byte)(bits >>> 56);
540: return result;
541: }
542:
543: protected byte[] getResult()
544: {
545: tailorDigestBits();
546:
547: byte[] result = new byte[hashSize];
548: if (hashSize >= HAVAL_256_BIT)
549: {
550: result[31] = (byte)(h7 >>> 24);
551: result[30] = (byte)(h7 >>> 16);
552: result[29] = (byte)(h7 >>> 8);
553: result[28] = (byte) h7;
554: }
555: if (hashSize >= HAVAL_224_BIT)
556: {
557: result[27] = (byte)(h6 >>> 24);
558: result[26] = (byte)(h6 >>> 16);
559: result[25] = (byte)(h6 >>> 8);
560: result[24] = (byte) h6;
561: }
562: if (hashSize >= HAVAL_192_BIT)
563: {
564: result[23] = (byte)(h5 >>> 24);
565: result[22] = (byte)(h5 >>> 16);
566: result[21] = (byte)(h5 >>> 8);
567: result[20] = (byte) h5;
568: }
569: if (hashSize >= HAVAL_160_BIT)
570: {
571: result[19] = (byte)(h4 >>> 24);
572: result[18] = (byte)(h4 >>> 16);
573: result[17] = (byte)(h4 >>> 8);
574: result[16] = (byte) h4;
575: }
576: result[15] = (byte)(h3 >>> 24);
577: result[14] = (byte)(h3 >>> 16);
578: result[13] = (byte)(h3 >>> 8);
579: result[12] = (byte) h3;
580: result[11] = (byte)(h2 >>> 24);
581: result[10] = (byte)(h2 >>> 16);
582: result[ 9] = (byte)(h2 >>> 8);
583: result[ 8] = (byte) h2;
584: result[ 7] = (byte)(h1 >>> 24);
585: result[ 6] = (byte)(h1 >>> 16);
586: result[ 5] = (byte)(h1 >>> 8);
587: result[ 4] = (byte) h1;
588: result[ 3] = (byte)(h0 >>> 24);
589: result[ 2] = (byte)(h0 >>> 16);
590: result[ 1] = (byte)(h0 >>> 8);
591: result[ 0] = (byte) h0;
592: return result;
593: }
594:
595: protected void resetContext()
596: {
597: h0 = 0x243F6A88;
598: h1 = 0x85A308D3;
599: h2 = 0x13198A2E;
600: h3 = 0x03707344;
601: h4 = 0xA4093822;
602: h5 = 0x299F31D0;
603: h6 = 0x082EFA98;
604: h7 = 0xEC4E6C89;
605: }
606:
607: public boolean selfTest()
608: {
609: if (valid == null)
610: {
611: String d = Util.toString(new Haval().digest());
612: valid = Boolean.valueOf(DIGEST0.equals(d));
613: }
614: return valid.booleanValue();
615: }
616:
617:
618: private void tailorDigestBits()
619: {
620: int t;
621: switch (hashSize)
622: {
623: case HAVAL_128_BIT:
624: t = (h7 & 0x000000FF)
625: | (h6 & 0xFF000000)
626: | (h5 & 0x00FF0000)
627: | (h4 & 0x0000FF00);
628: h0 += t >>> 8 | t << 24;
629: t = (h7 & 0x0000FF00)
630: | (h6 & 0x000000FF)
631: | (h5 & 0xFF000000)
632: | (h4 & 0x00FF0000);
633: h1 += t >>> 16 | t << 16;
634: t = (h7 & 0x00FF0000)
635: | (h6 & 0x0000FF00)
636: | (h5 & 0x000000FF)
637: | (h4 & 0xFF000000);
638: h2 += t >>> 24 | t << 8;
639: t = (h7 & 0xFF000000)
640: | (h6 & 0x00FF0000)
641: | (h5 & 0x0000FF00)
642: | (h4 & 0x000000FF);
643: h3 += t;
644: break;
645: case HAVAL_160_BIT:
646: t = (h7 & 0x3F) | (h6 & (0x7F << 25)) | (h5 & (0x3F << 19));
647: h0 += t >>> 19 | t << 13;
648: t = (h7 & (0x3F << 6)) | (h6 & 0x3F) | (h5 & (0x7F << 25));
649: h1 += t >>> 25 | t << 7;
650: t = (h7 & (0x7F << 12)) | (h6 & (0x3F << 6)) | (h5 & 0x3F);
651: h2 += t;
652: t = (h7 & (0x3F << 19)) | (h6 & (0x7F << 12)) | (h5 & (0x3F << 6));
653: h3 += (t >>> 6);
654: t = (h7 & (0x7F << 25)) | (h6 & (0x3F << 19)) | (h5 & (0x7F << 12));
655: h4 += (t >>> 12);
656: break;
657: case HAVAL_192_BIT:
658: t = (h7 & 0x1F) | (h6 & (0x3F << 26));
659: h0 += t >>> 26 | t << 6;
660: t = (h7 & (0x1F << 5)) | (h6 & 0x1F);
661: h1 += t;
662: t = (h7 & (0x3F << 10)) | (h6 & (0x1F << 5));
663: h2 += (t >>> 5);
664: t = (h7 & (0x1F << 16)) | (h6 & (0x3F << 10));
665: h3 += (t >>> 10);
666: t = (h7 & (0x1F << 21)) | (h6 & (0x1F << 16));
667: h4 += (t >>> 16);
668: t = (h7 & (0x3F << 26)) | (h6 & (0x1F << 21));
669: h5 += (t >>> 21);
670: break;
671: case HAVAL_224_BIT:
672: h0 += ((h7 >>> 27) & 0x1F);
673: h1 += ((h7 >>> 22) & 0x1F);
674: h2 += ((h7 >>> 18) & 0x0F);
675: h3 += ((h7 >>> 13) & 0x1F);
676: h4 += ((h7 >>> 9) & 0x0F);
677: h5 += ((h7 >>> 4) & 0x1F);
678: h6 += (h7 & 0x0F);
679: }
680: }
681:
682:
706: private int FF1(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
707: int x0, int w)
708: {
709: int t;
710: switch (rounds)
711: {
712: case 3:
713: t = f1(x1, x0, x3, x5, x6, x2, x4);
714: break;
715: case 4:
716: t = f1(x2, x6, x1, x4, x5, x3, x0);
717: break;
718: default:
719: t = f1(x3, x4, x1, x0, x5, x2, x6);
720: }
721: return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w;
722: }
723:
724: private int FF2(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
725: int x0, int w, int c)
726: {
727: int t;
728: switch (rounds)
729: {
730: case 3:
731: t = f2(x4, x2, x1, x0, x5, x3, x6);
732: break;
733: case 4:
734: t = f2(x3, x5, x2, x0, x1, x6, x4);
735: break;
736: default:
737: t = f2(x6, x2, x1, x0, x3, x4, x5);
738: }
739: return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
740: }
741:
742: private int FF3(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
743: int x0, int w, int c)
744: {
745: int t;
746: switch (rounds)
747: {
748: case 3:
749: t = f3(x6, x1, x2, x3, x4, x5, x0);
750: break;
751: case 4:
752: t = f3(x1, x4, x3, x6, x0, x2, x5);
753: break;
754: default:
755: t = f3(x2, x6, x0, x4, x3, x1, x5);
756: }
757: return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
758: }
759:
760: private int FF4(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
761: int x0, int w, int c)
762: {
763: int t;
764: switch (rounds)
765: {
766: case 4:
767: t = f4(x6, x4, x0, x5, x2, x1, x3);
768: break;
769: default:
770: t = f4(x1, x5, x3, x2, x0, x4, x6);
771: }
772: return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
773: }
774:
775: private int FF5(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
776: int x0, int w, int c)
777: {
778: int t = f5(x2, x5, x0, x6, x4, x3, x1);
779: return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
780: }
781:
782: private int f1(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
783: {
784: return x1 & (x0 ^ x4) ^ x2 & x5 ^ x3 & x6 ^ x0;
785: }
786:
787: private int f2(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
788: {
789: return x2 & (x1 & ~x3 ^ x4 & x5 ^ x6 ^ x0) ^ x4 & (x1 ^ x5) ^ x3 & x5 ^ x0;
790: }
791:
792: private int f3(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
793: {
794: return x3 & (x1 & x2 ^ x6 ^ x0) ^ x1 & x4 ^ x2 & x5 ^ x0;
795: }
796:
797: private int f4(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
798: {
799: return x4 & (x5 & ~x2 ^ x3 & ~x6 ^ x1 ^ x6 ^ x0) ^ x3
800: & (x1 & x2 ^ x5 ^ x6) ^ x2 & x6 ^ x0;
801: }
802:
803: private int f5(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
804: {
805: return x0 & (x1 & x2 & x3 ^ ~x5) ^ x1 & x4 ^ x2 & x5 ^ x3 & x6;
806: }
807: }