2 Copyright (C) 2001, 2002, 2006, 2010 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
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
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.lang.CPStringBuilder;
43 import gnu.java.security.Configuration;
44 import gnu.java.security.Registry;
45 import gnu.java.security.util.Util;
47 import java.util.logging.Logger;
50 * Whirlpool, a new 512-bit hashing function operating on messages less than
51 * 2 ** 256 bits in length. The function structure is designed according to the
52 * Wide Trail strategy and permits a wide variety of implementation trade-offs.
54 * This implementation is of Whirlpool Version 3, described in [1] last revised
57 * <b>IMPORTANT</b>: This implementation is not thread-safe.
61 * <li><a href="http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html">
62 * The WHIRLPOOL Hashing Function</a>.<br>
63 * <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and
64 * <a href="mailto:vincent.rijmen@iaik.tugraz.at">Vincent Rijmen</a>.</li>
67 public final class Whirlpool
70 private static final Logger log = Configuration.DEBUG ?
71 Logger.getLogger(Whirlpool.class.getName()) : null;
73 private static final int BLOCK_SIZE = 64; // inner block size in bytes
75 /** The digest of the 0-bit long message. */
76 private static final String DIGEST0 =
77 "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A7"
78 + "3E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3";
80 /** Default number of rounds. */
81 private static final int R = 10;
83 /** Whirlpool S-box; p. 19. */
84 private static final String S_box = // p. 19 [WHIRLPOOL]
85 "\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152"
86 + "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57"
87 + "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85"
88 + "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8"
89 + "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333"
90 + "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0"
91 + "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE"
92 + "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d"
93 + "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF"
94 + "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A"
95 + "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c"
96 + "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04"
97 + "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB"
98 + "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9"
99 + "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1"
100 + "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886";
102 /** The 64-bit lookup tables; section 7.1 p. 13. */
103 private static final long[] T0 = new long[256];
104 private static final long[] T1 = new long[256];
105 private static final long[] T2 = new long[256];
106 private static final long[] T3 = new long[256];
107 private static final long[] T4 = new long[256];
108 private static final long[] T5 = new long[256];
109 private static final long[] T6 = new long[256];
110 private static final long[] T7 = new long[256];
112 /** The round constants. */
113 private static final long[] rc = new long[R];
115 /** caches the result of the correctness test, once executed. */
116 private static Boolean valid;
118 /** The 512-bit context as 8 longs. */
119 private long H0, H1, H2, H3, H4, H5, H6, H7;
121 /** Work area for computing the round key schedule. */
122 private long k00, k01, k02, k03, k04, k05, k06, k07;
123 private long Kr0, Kr1, Kr2, Kr3, Kr4, Kr5, Kr6, Kr7;
125 /** work area for transforming the 512-bit buffer. */
126 private long n0, n1, n2, n3, n4, n5, n6, n7;
127 private long nn0, nn1, nn2, nn3, nn4, nn5, nn6, nn7;
129 /** work area for holding block cipher's intermediate values. */
130 private long w0, w1, w2, w3, w4, w5, w6, w7;
134 long time = System.currentTimeMillis();
135 int ROOT = 0x11D; // para. 2.1 [WHIRLPOOL]
137 long s1, s2, s4, s5, s8, s9, t;
139 final byte[] S = new byte[256];
140 for (i = 0; i < 256; i++)
142 c = S_box.charAt(i >>> 1);
144 s1 = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL;
160 T0[i] = t = s1 << 56 | s1 << 48 | s4 << 40 | s1 << 32
161 | s8 << 24 | s5 << 16 | s2 << 8 | s9;
162 T1[i] = t >>> 8 | t << 56;
163 T2[i] = t >>> 16 | t << 48;
164 T3[i] = t >>> 24 | t << 40;
165 T4[i] = t >>> 32 | t << 32;
166 T5[i] = t >>> 40 | t << 24;
167 T6[i] = t >>> 48 | t << 16;
168 T7[i] = t >>> 56 | t << 8;
170 for (r = 0, i = 0; r < R; )
171 rc[r++] = (T0[i++] & 0xFF00000000000000L)
172 ^ (T1[i++] & 0x00FF000000000000L)
173 ^ (T2[i++] & 0x0000FF0000000000L)
174 ^ (T3[i++] & 0x000000FF00000000L)
175 ^ (T4[i++] & 0x00000000FF000000L)
176 ^ (T5[i++] & 0x0000000000FF0000L)
177 ^ (T6[i++] & 0x000000000000FF00L)
178 ^ (T7[i++] & 0x00000000000000FFL);
179 time = System.currentTimeMillis() - time;
180 if (Configuration.DEBUG)
182 log.fine("Static data");
185 for (i = 0; i < 64; i++)
187 sb = new CPStringBuilder();
188 for (j = 0; j < 4; j++)
189 sb.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
191 log.fine(sb.toString());
194 for (i = 0; i < 64; i++)
196 sb = new CPStringBuilder();
197 for (j = 0; j < 4; j++)
198 sb.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
200 log.fine(sb.toString());
203 for (i = 0; i < 64; i++)
205 sb = new CPStringBuilder();
206 for (j = 0; j < 4; j++)
207 sb.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
209 log.fine(sb.toString());
212 for (i = 0; i < 64; i++)
214 sb = new CPStringBuilder();
215 for (j = 0; j < 4; j++)
216 sb.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
218 log.fine(sb.toString());
221 for (i = 0; i < 64; i++)
223 sb = new CPStringBuilder();
224 for (j = 0; j < 4; j++)
225 sb.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
227 log.fine(sb.toString());
230 for (i = 0; i < 64; i++)
232 sb = new CPStringBuilder();
233 for (j = 0; j < 4; j++)
234 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
236 log.fine(sb.toString());
239 for (i = 0; i < 64; i++)
241 sb = new CPStringBuilder();
242 for (j = 0; j < 4; j++)
243 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
245 log.fine(sb.toString());
248 for (i = 0; i < 64; i++)
250 sb = new CPStringBuilder();
251 for (j = 0; j < 4; j++)
252 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
254 log.fine(sb.toString());
257 for (i = 0; i < R; i++)
258 log.fine("0x" + Util.toString(rc[i]));
260 log.fine("Total initialization time: " + time + " ms.");
264 /** Trivial 0-arguments constructor. */
267 super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE);
271 * Private constructor for cloning purposes.
273 * @param md the instance to clone.
275 private Whirlpool(Whirlpool md)
287 this.count = md.count;
288 this.buffer = (byte[]) md.buffer.clone();
291 public Object clone()
293 return (new Whirlpool(this));
296 protected void transform(byte[] in, int offset)
298 // apply mu to the input
299 n0 = (in[offset++] & 0xFFL) << 56
300 | (in[offset++] & 0xFFL) << 48
301 | (in[offset++] & 0xFFL) << 40
302 | (in[offset++] & 0xFFL) << 32
303 | (in[offset++] & 0xFFL) << 24
304 | (in[offset++] & 0xFFL) << 16
305 | (in[offset++] & 0xFFL) << 8
306 | (in[offset++] & 0xFFL);
307 n1 = (in[offset++] & 0xFFL) << 56
308 | (in[offset++] & 0xFFL) << 48
309 | (in[offset++] & 0xFFL) << 40
310 | (in[offset++] & 0xFFL) << 32
311 | (in[offset++] & 0xFFL) << 24
312 | (in[offset++] & 0xFFL) << 16
313 | (in[offset++] & 0xFFL) << 8
314 | (in[offset++] & 0xFFL);
315 n2 = (in[offset++] & 0xFFL) << 56
316 | (in[offset++] & 0xFFL) << 48
317 | (in[offset++] & 0xFFL) << 40
318 | (in[offset++] & 0xFFL) << 32
319 | (in[offset++] & 0xFFL) << 24
320 | (in[offset++] & 0xFFL) << 16
321 | (in[offset++] & 0xFFL) << 8
322 | (in[offset++] & 0xFFL);
323 n3 = (in[offset++] & 0xFFL) << 56
324 | (in[offset++] & 0xFFL) << 48
325 | (in[offset++] & 0xFFL) << 40
326 | (in[offset++] & 0xFFL) << 32
327 | (in[offset++] & 0xFFL) << 24
328 | (in[offset++] & 0xFFL) << 16
329 | (in[offset++] & 0xFFL) << 8
330 | (in[offset++] & 0xFFL);
331 n4 = (in[offset++] & 0xFFL) << 56
332 | (in[offset++] & 0xFFL) << 48
333 | (in[offset++] & 0xFFL) << 40
334 | (in[offset++] & 0xFFL) << 32
335 | (in[offset++] & 0xFFL) << 24
336 | (in[offset++] & 0xFFL) << 16
337 | (in[offset++] & 0xFFL) << 8
338 | (in[offset++] & 0xFFL);
339 n5 = (in[offset++] & 0xFFL) << 56
340 | (in[offset++] & 0xFFL) << 48
341 | (in[offset++] & 0xFFL) << 40
342 | (in[offset++] & 0xFFL) << 32
343 | (in[offset++] & 0xFFL) << 24
344 | (in[offset++] & 0xFFL) << 16
345 | (in[offset++] & 0xFFL) << 8
346 | (in[offset++] & 0xFFL);
347 n6 = (in[offset++] & 0xFFL) << 56
348 | (in[offset++] & 0xFFL) << 48
349 | (in[offset++] & 0xFFL) << 40
350 | (in[offset++] & 0xFFL) << 32
351 | (in[offset++] & 0xFFL) << 24
352 | (in[offset++] & 0xFFL) << 16
353 | (in[offset++] & 0xFFL) << 8
354 | (in[offset++] & 0xFFL);
355 n7 = (in[offset++] & 0xFFL) << 56
356 | (in[offset++] & 0xFFL) << 48
357 | (in[offset++] & 0xFFL) << 40
358 | (in[offset++] & 0xFFL) << 32
359 | (in[offset++] & 0xFFL) << 24
360 | (in[offset++] & 0xFFL) << 16
361 | (in[offset++] & 0xFFL) << 8
362 | (in[offset++] & 0xFFL);
363 // transform K into the key schedule Kr; 0 <= r <= R
380 // intermediate cipher output
381 w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0L;
382 for (int r = 0; r < R; r++)
384 // 1. compute intermediate round key schedule by applying ro[rc]
385 // to the previous round key schedule --rc being the round constant
386 Kr0 = T0[(int)((k00 >> 56) & 0xFFL)]
387 ^ T1[(int)((k07 >> 48) & 0xFFL)]
388 ^ T2[(int)((k06 >> 40) & 0xFFL)]
389 ^ T3[(int)((k05 >> 32) & 0xFFL)]
390 ^ T4[(int)((k04 >> 24) & 0xFFL)]
391 ^ T5[(int)((k03 >> 16) & 0xFFL)]
392 ^ T6[(int)((k02 >> 8) & 0xFFL)]
393 ^ T7[(int)( k01 & 0xFFL)] ^ rc[r];
394 Kr1 = T0[(int)((k01 >> 56) & 0xFFL)]
395 ^ T1[(int)((k00 >> 48) & 0xFFL)]
396 ^ T2[(int)((k07 >> 40) & 0xFFL)]
397 ^ T3[(int)((k06 >> 32) & 0xFFL)]
398 ^ T4[(int)((k05 >> 24) & 0xFFL)]
399 ^ T5[(int)((k04 >> 16) & 0xFFL)]
400 ^ T6[(int)((k03 >> 8) & 0xFFL)]
401 ^ T7[(int)( k02 & 0xFFL)];
402 Kr2 = T0[(int)((k02 >> 56) & 0xFFL)]
403 ^ T1[(int)((k01 >> 48) & 0xFFL)]
404 ^ T2[(int)((k00 >> 40) & 0xFFL)]
405 ^ T3[(int)((k07 >> 32) & 0xFFL)]
406 ^ T4[(int)((k06 >> 24) & 0xFFL)]
407 ^ T5[(int)((k05 >> 16) & 0xFFL)]
408 ^ T6[(int)((k04 >> 8) & 0xFFL)]
409 ^ T7[(int)( k03 & 0xFFL)];
410 Kr3 = T0[(int)((k03 >> 56) & 0xFFL)]
411 ^ T1[(int)((k02 >> 48) & 0xFFL)]
412 ^ T2[(int)((k01 >> 40) & 0xFFL)]
413 ^ T3[(int)((k00 >> 32) & 0xFFL)]
414 ^ T4[(int)((k07 >> 24) & 0xFFL)]
415 ^ T5[(int)((k06 >> 16) & 0xFFL)]
416 ^ T6[(int)((k05 >> 8) & 0xFFL)]
417 ^ T7[(int)( k04 & 0xFFL)];
418 Kr4 = T0[(int)((k04 >> 56) & 0xFFL)]
419 ^ T1[(int)((k03 >> 48) & 0xFFL)]
420 ^ T2[(int)((k02 >> 40) & 0xFFL)]
421 ^ T3[(int)((k01 >> 32) & 0xFFL)]
422 ^ T4[(int)((k00 >> 24) & 0xFFL)]
423 ^ T5[(int)((k07 >> 16) & 0xFFL)]
424 ^ T6[(int)((k06 >> 8) & 0xFFL)]
425 ^ T7[(int)( k05 & 0xFFL)];
426 Kr5 = T0[(int)((k05 >> 56) & 0xFFL)]
427 ^ T1[(int)((k04 >> 48) & 0xFFL)]
428 ^ T2[(int)((k03 >> 40) & 0xFFL)]
429 ^ T3[(int)((k02 >> 32) & 0xFFL)]
430 ^ T4[(int)((k01 >> 24) & 0xFFL)]
431 ^ T5[(int)((k00 >> 16) & 0xFFL)]
432 ^ T6[(int)((k07 >> 8) & 0xFFL)]
433 ^ T7[(int)( k06 & 0xFFL)];
434 Kr6 = T0[(int)((k06 >> 56) & 0xFFL)]
435 ^ T1[(int)((k05 >> 48) & 0xFFL)]
436 ^ T2[(int)((k04 >> 40) & 0xFFL)]
437 ^ T3[(int)((k03 >> 32) & 0xFFL)]
438 ^ T4[(int)((k02 >> 24) & 0xFFL)]
439 ^ T5[(int)((k01 >> 16) & 0xFFL)]
440 ^ T6[(int)((k00 >> 8) & 0xFFL)]
441 ^ T7[(int)( k07 & 0xFFL)];
442 Kr7 = T0[(int)((k07 >> 56) & 0xFFL)]
443 ^ T1[(int)((k06 >> 48) & 0xFFL)]
444 ^ T2[(int)((k05 >> 40) & 0xFFL)]
445 ^ T3[(int)((k04 >> 32) & 0xFFL)]
446 ^ T4[(int)((k03 >> 24) & 0xFFL)]
447 ^ T5[(int)((k02 >> 16) & 0xFFL)]
448 ^ T6[(int)((k01 >> 8) & 0xFFL)]
449 ^ T7[(int)( k00 & 0xFFL)];
458 // 2. incrementally compute the cipher output
459 w0 = T0[(int)((nn0 >> 56) & 0xFFL)]
460 ^ T1[(int)((nn7 >> 48) & 0xFFL)]
461 ^ T2[(int)((nn6 >> 40) & 0xFFL)]
462 ^ T3[(int)((nn5 >> 32) & 0xFFL)]
463 ^ T4[(int)((nn4 >> 24) & 0xFFL)]
464 ^ T5[(int)((nn3 >> 16) & 0xFFL)]
465 ^ T6[(int)((nn2 >> 8) & 0xFFL)]
466 ^ T7[(int)( nn1 & 0xFFL)] ^ Kr0;
467 w1 = T0[(int)((nn1 >> 56) & 0xFFL)]
468 ^ T1[(int)((nn0 >> 48) & 0xFFL)]
469 ^ T2[(int)((nn7 >> 40) & 0xFFL)]
470 ^ T3[(int)((nn6 >> 32) & 0xFFL)]
471 ^ T4[(int)((nn5 >> 24) & 0xFFL)]
472 ^ T5[(int)((nn4 >> 16) & 0xFFL)]
473 ^ T6[(int)((nn3 >> 8) & 0xFFL)]
474 ^ T7[(int)( nn2 & 0xFFL)] ^ Kr1;
475 w2 = T0[(int)((nn2 >> 56) & 0xFFL)]
476 ^ T1[(int)((nn1 >> 48) & 0xFFL)]
477 ^ T2[(int)((nn0 >> 40) & 0xFFL)]
478 ^ T3[(int)((nn7 >> 32) & 0xFFL)]
479 ^ T4[(int)((nn6 >> 24) & 0xFFL)]
480 ^ T5[(int)((nn5 >> 16) & 0xFFL)]
481 ^ T6[(int)((nn4 >> 8) & 0xFFL)]
482 ^ T7[(int)( nn3 & 0xFFL)] ^ Kr2;
483 w3 = T0[(int)((nn3 >> 56) & 0xFFL)]
484 ^ T1[(int)((nn2 >> 48) & 0xFFL)]
485 ^ T2[(int)((nn1 >> 40) & 0xFFL)]
486 ^ T3[(int)((nn0 >> 32) & 0xFFL)]
487 ^ T4[(int)((nn7 >> 24) & 0xFFL)]
488 ^ T5[(int)((nn6 >> 16) & 0xFFL)]
489 ^ T6[(int)((nn5 >> 8) & 0xFFL)]
490 ^ T7[(int)( nn4 & 0xFFL)] ^ Kr3;
491 w4 = T0[(int)((nn4 >> 56) & 0xFFL)]
492 ^ T1[(int)((nn3 >> 48) & 0xFFL)]
493 ^ T2[(int)((nn2 >> 40) & 0xFFL)]
494 ^ T3[(int)((nn1 >> 32) & 0xFFL)]
495 ^ T4[(int)((nn0 >> 24) & 0xFFL)]
496 ^ T5[(int)((nn7 >> 16) & 0xFFL)]
497 ^ T6[(int)((nn6 >> 8) & 0xFFL)]
498 ^ T7[(int)( nn5 & 0xFFL)] ^ Kr4;
499 w5 = T0[(int)((nn5 >> 56) & 0xFFL)]
500 ^ T1[(int)((nn4 >> 48) & 0xFFL)]
501 ^ T2[(int)((nn3 >> 40) & 0xFFL)]
502 ^ T3[(int)((nn2 >> 32) & 0xFFL)]
503 ^ T4[(int)((nn1 >> 24) & 0xFFL)]
504 ^ T5[(int)((nn0 >> 16) & 0xFFL)]
505 ^ T6[(int)((nn7 >> 8) & 0xFFL)]
506 ^ T7[(int)( nn6 & 0xFFL)] ^ Kr5;
507 w6 = T0[(int)((nn6 >> 56) & 0xFFL)]
508 ^ T1[(int)((nn5 >> 48) & 0xFFL)]
509 ^ T2[(int)((nn4 >> 40) & 0xFFL)]
510 ^ T3[(int)((nn3 >> 32) & 0xFFL)]
511 ^ T4[(int)((nn2 >> 24) & 0xFFL)]
512 ^ T5[(int)((nn1 >> 16) & 0xFFL)]
513 ^ T6[(int)((nn0 >> 8) & 0xFFL)]
514 ^ T7[(int)( nn7 & 0xFFL)] ^ Kr6;
515 w7 = T0[(int)((nn7 >> 56) & 0xFFL)]
516 ^ T1[(int)((nn6 >> 48) & 0xFFL)]
517 ^ T2[(int)((nn5 >> 40) & 0xFFL)]
518 ^ T3[(int)((nn4 >> 32) & 0xFFL)]
519 ^ T4[(int)((nn3 >> 24) & 0xFFL)]
520 ^ T5[(int)((nn2 >> 16) & 0xFFL)]
521 ^ T6[(int)((nn1 >> 8) & 0xFFL)]
522 ^ T7[(int)( nn0 & 0xFFL)] ^ Kr7;
532 // apply the Miyaguchi-Preneel hash scheme
543 protected byte[] padBuffer()
546 // "...padded with a 1-bit, then with as few 0-bits as necessary to
547 // obtain a bit string whose length is an odd multiple of 256, and
548 // finally with the 256-bit right-justified binary representation of L."
549 // in this implementation we use 'count' as the number of bytes hashed
550 // so far. hence the minimal number of bytes added to the message proper
551 // are 33 (1 for the 1-bit followed by the 0-bits and the encoding of
552 // the count framed in a 256-bit block). our formula is then:
553 // count + 33 + padding = 0 (mod BLOCK_SIZE)
554 int n = (int)((count + 33) % BLOCK_SIZE);
555 int padding = n == 0 ? 33 : BLOCK_SIZE - n + 33;
556 byte[] result = new byte[padding];
557 // padding is always binary 1 followed by binary 0s
558 result[0] = (byte) 0x80;
559 // save (right justified) the number of bits hashed
560 long bits = count * 8;
562 result[i++] = (byte)(bits >>> 56);
563 result[i++] = (byte)(bits >>> 48);
564 result[i++] = (byte)(bits >>> 40);
565 result[i++] = (byte)(bits >>> 32);
566 result[i++] = (byte)(bits >>> 24);
567 result[i++] = (byte)(bits >>> 16);
568 result[i++] = (byte)(bits >>> 8);
569 result[i ] = (byte) bits;
573 protected byte[] getResult()
575 // apply inverse mu to the context
577 (byte)(H0 >>> 56), (byte)(H0 >>> 48), (byte)(H0 >>> 40), (byte)(H0 >>> 32),
578 (byte)(H0 >>> 24), (byte)(H0 >>> 16), (byte)(H0 >>> 8), (byte) H0,
579 (byte)(H1 >>> 56), (byte)(H1 >>> 48), (byte)(H1 >>> 40), (byte)(H1 >>> 32),
580 (byte)(H1 >>> 24), (byte)(H1 >>> 16), (byte)(H1 >>> 8), (byte) H1,
581 (byte)(H2 >>> 56), (byte)(H2 >>> 48), (byte)(H2 >>> 40), (byte)(H2 >>> 32),
582 (byte)(H2 >>> 24), (byte)(H2 >>> 16), (byte)(H2 >>> 8), (byte) H2,
583 (byte)(H3 >>> 56), (byte)(H3 >>> 48), (byte)(H3 >>> 40), (byte)(H3 >>> 32),
584 (byte)(H3 >>> 24), (byte)(H3 >>> 16), (byte)(H3 >>> 8), (byte) H3,
585 (byte)(H4 >>> 56), (byte)(H4 >>> 48), (byte)(H4 >>> 40), (byte)(H4 >>> 32),
586 (byte)(H4 >>> 24), (byte)(H4 >>> 16), (byte)(H4 >>> 8), (byte) H4,
587 (byte)(H5 >>> 56), (byte)(H5 >>> 48), (byte)(H5 >>> 40), (byte)(H5 >>> 32),
588 (byte)(H5 >>> 24), (byte)(H5 >>> 16), (byte)(H5 >>> 8), (byte) H5,
589 (byte)(H6 >>> 56), (byte)(H6 >>> 48), (byte)(H6 >>> 40), (byte)(H6 >>> 32),
590 (byte)(H6 >>> 24), (byte)(H6 >>> 16), (byte)(H6 >>> 8), (byte) H6,
591 (byte)(H7 >>> 56), (byte)(H7 >>> 48), (byte)(H7 >>> 40), (byte)(H7 >>> 32),
592 (byte)(H7 >>> 24), (byte)(H7 >>> 16), (byte)(H7 >>> 8), (byte) H7 };
596 protected void resetContext()
598 H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L;
601 public boolean selfTest()
605 String d = Util.toString(new Whirlpool().digest());
606 valid = Boolean.valueOf(DIGEST0.equals(d));
608 return valid.booleanValue();