libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / gnu / java / security / hash / Whirlpool.java
blobaebe1acb699bf45f3e5b4f3f6c92927921e1ad13
1 /* Whirlpool.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.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;
49 /**
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.
53 * <p>
54 * This implementation is of Whirlpool Version 3, described in [1] last revised
55 * on May 24th, 2003.
56 * <p>
57 * <b>IMPORTANT</b>: This implementation is not thread-safe.
58 * <p>
59 * References:
60 * <ol>
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>
65 * </ol>
67 public final class Whirlpool
68 extends BaseHash
70 private static final Logger log = Logger.getLogger(Whirlpool.class.getName());
71 private static final int BLOCK_SIZE = 64; // inner block size in bytes
73 /** The digest of the 0-bit long message. */
74 private static final String DIGEST0 =
75 "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A7"
76 + "3E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3";
78 /** Default number of rounds. */
79 private static final int R = 10;
81 /** Whirlpool S-box; p. 19. */
82 private static final String S_box = // p. 19 [WHIRLPOOL]
83 "\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152"
84 + "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57"
85 + "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85"
86 + "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8"
87 + "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333"
88 + "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0"
89 + "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE"
90 + "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d"
91 + "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF"
92 + "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A"
93 + "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c"
94 + "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04"
95 + "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB"
96 + "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9"
97 + "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1"
98 + "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886";
100 /** The 64-bit lookup tables; section 7.1 p. 13. */
101 private static final long[] T0 = new long[256];
102 private static final long[] T1 = new long[256];
103 private static final long[] T2 = new long[256];
104 private static final long[] T3 = new long[256];
105 private static final long[] T4 = new long[256];
106 private static final long[] T5 = new long[256];
107 private static final long[] T6 = new long[256];
108 private static final long[] T7 = new long[256];
110 /** The round constants. */
111 private static final long[] rc = new long[R];
113 /** caches the result of the correctness test, once executed. */
114 private static Boolean valid;
116 /** The 512-bit context as 8 longs. */
117 private long H0, H1, H2, H3, H4, H5, H6, H7;
119 /** Work area for computing the round key schedule. */
120 private long k00, k01, k02, k03, k04, k05, k06, k07;
121 private long Kr0, Kr1, Kr2, Kr3, Kr4, Kr5, Kr6, Kr7;
123 /** work area for transforming the 512-bit buffer. */
124 private long n0, n1, n2, n3, n4, n5, n6, n7;
125 private long nn0, nn1, nn2, nn3, nn4, nn5, nn6, nn7;
127 /** work area for holding block cipher's intermediate values. */
128 private long w0, w1, w2, w3, w4, w5, w6, w7;
130 static
132 long time = System.currentTimeMillis();
133 int ROOT = 0x11D; // para. 2.1 [WHIRLPOOL]
134 int i, r, j;
135 long s1, s2, s4, s5, s8, s9, t;
136 char c;
137 final byte[] S = new byte[256];
138 for (i = 0; i < 256; i++)
140 c = S_box.charAt(i >>> 1);
142 s1 = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL;
143 s2 = s1 << 1;
144 if (s2 > 0xFFL)
145 s2 ^= ROOT;
147 s4 = s2 << 1;
148 if (s4 > 0xFFL)
149 s4 ^= ROOT;
151 s5 = s4 ^ s1;
152 s8 = s4 << 1;
153 if (s8 > 0xFFL)
154 s8 ^= ROOT;
156 s9 = s8 ^ s1;
158 T0[i] = t = s1 << 56 | s1 << 48 | s4 << 40 | s1 << 32
159 | s8 << 24 | s5 << 16 | s2 << 8 | s9;
160 T1[i] = t >>> 8 | t << 56;
161 T2[i] = t >>> 16 | t << 48;
162 T3[i] = t >>> 24 | t << 40;
163 T4[i] = t >>> 32 | t << 32;
164 T5[i] = t >>> 40 | t << 24;
165 T6[i] = t >>> 48 | t << 16;
166 T7[i] = t >>> 56 | t << 8;
168 for (r = 0, i = 0; r < R; )
169 rc[r++] = (T0[i++] & 0xFF00000000000000L)
170 ^ (T1[i++] & 0x00FF000000000000L)
171 ^ (T2[i++] & 0x0000FF0000000000L)
172 ^ (T3[i++] & 0x000000FF00000000L)
173 ^ (T4[i++] & 0x00000000FF000000L)
174 ^ (T5[i++] & 0x0000000000FF0000L)
175 ^ (T6[i++] & 0x000000000000FF00L)
176 ^ (T7[i++] & 0x00000000000000FFL);
177 time = System.currentTimeMillis() - time;
178 if (Configuration.DEBUG)
180 log.fine("Static data");
181 log.fine("T0[]:");
182 CPStringBuilder sb;
183 for (i = 0; i < 64; i++)
185 sb = new CPStringBuilder();
186 for (j = 0; j < 4; j++)
187 sb.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
189 log.fine(sb.toString());
191 log.fine("T1[]:");
192 for (i = 0; i < 64; i++)
194 sb = new CPStringBuilder();
195 for (j = 0; j < 4; j++)
196 sb.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
198 log.fine(sb.toString());
200 log.fine("T2[]:");
201 for (i = 0; i < 64; i++)
203 sb = new CPStringBuilder();
204 for (j = 0; j < 4; j++)
205 sb.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
207 log.fine(sb.toString());
209 log.fine("T3[]:");
210 for (i = 0; i < 64; i++)
212 sb = new CPStringBuilder();
213 for (j = 0; j < 4; j++)
214 sb.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
216 log.fine(sb.toString());
218 log.fine("\nT4[]:");
219 for (i = 0; i < 64; i++)
221 sb = new CPStringBuilder();
222 for (j = 0; j < 4; j++)
223 sb.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
225 log.fine(sb.toString());
227 log.fine("T5[]:");
228 for (i = 0; i < 64; i++)
230 sb = new CPStringBuilder();
231 for (j = 0; j < 4; j++)
232 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
234 log.fine(sb.toString());
236 log.fine("T6[]:");
237 for (i = 0; i < 64; i++)
239 sb = new CPStringBuilder();
240 for (j = 0; j < 4; j++)
241 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
243 log.fine(sb.toString());
245 log.fine("T7[]:");
246 for (i = 0; i < 64; i++)
248 sb = new CPStringBuilder();
249 for (j = 0; j < 4; j++)
250 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
252 log.fine(sb.toString());
254 log.fine("rc[]:");
255 for (i = 0; i < R; i++)
256 log.fine("0x" + Util.toString(rc[i]));
258 log.fine("Total initialization time: " + time + " ms.");
262 /** Trivial 0-arguments constructor. */
263 public Whirlpool()
265 super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE);
269 * Private constructor for cloning purposes.
271 * @param md the instance to clone.
273 private Whirlpool(Whirlpool md)
275 this();
277 this.H0 = md.H0;
278 this.H1 = md.H1;
279 this.H2 = md.H2;
280 this.H3 = md.H3;
281 this.H4 = md.H4;
282 this.H5 = md.H5;
283 this.H6 = md.H6;
284 this.H7 = md.H7;
285 this.count = md.count;
286 this.buffer = (byte[]) md.buffer.clone();
289 public Object clone()
291 return (new Whirlpool(this));
294 protected void transform(byte[] in, int offset)
296 // apply mu to the input
297 n0 = (in[offset++] & 0xFFL) << 56
298 | (in[offset++] & 0xFFL) << 48
299 | (in[offset++] & 0xFFL) << 40
300 | (in[offset++] & 0xFFL) << 32
301 | (in[offset++] & 0xFFL) << 24
302 | (in[offset++] & 0xFFL) << 16
303 | (in[offset++] & 0xFFL) << 8
304 | (in[offset++] & 0xFFL);
305 n1 = (in[offset++] & 0xFFL) << 56
306 | (in[offset++] & 0xFFL) << 48
307 | (in[offset++] & 0xFFL) << 40
308 | (in[offset++] & 0xFFL) << 32
309 | (in[offset++] & 0xFFL) << 24
310 | (in[offset++] & 0xFFL) << 16
311 | (in[offset++] & 0xFFL) << 8
312 | (in[offset++] & 0xFFL);
313 n2 = (in[offset++] & 0xFFL) << 56
314 | (in[offset++] & 0xFFL) << 48
315 | (in[offset++] & 0xFFL) << 40
316 | (in[offset++] & 0xFFL) << 32
317 | (in[offset++] & 0xFFL) << 24
318 | (in[offset++] & 0xFFL) << 16
319 | (in[offset++] & 0xFFL) << 8
320 | (in[offset++] & 0xFFL);
321 n3 = (in[offset++] & 0xFFL) << 56
322 | (in[offset++] & 0xFFL) << 48
323 | (in[offset++] & 0xFFL) << 40
324 | (in[offset++] & 0xFFL) << 32
325 | (in[offset++] & 0xFFL) << 24
326 | (in[offset++] & 0xFFL) << 16
327 | (in[offset++] & 0xFFL) << 8
328 | (in[offset++] & 0xFFL);
329 n4 = (in[offset++] & 0xFFL) << 56
330 | (in[offset++] & 0xFFL) << 48
331 | (in[offset++] & 0xFFL) << 40
332 | (in[offset++] & 0xFFL) << 32
333 | (in[offset++] & 0xFFL) << 24
334 | (in[offset++] & 0xFFL) << 16
335 | (in[offset++] & 0xFFL) << 8
336 | (in[offset++] & 0xFFL);
337 n5 = (in[offset++] & 0xFFL) << 56
338 | (in[offset++] & 0xFFL) << 48
339 | (in[offset++] & 0xFFL) << 40
340 | (in[offset++] & 0xFFL) << 32
341 | (in[offset++] & 0xFFL) << 24
342 | (in[offset++] & 0xFFL) << 16
343 | (in[offset++] & 0xFFL) << 8
344 | (in[offset++] & 0xFFL);
345 n6 = (in[offset++] & 0xFFL) << 56
346 | (in[offset++] & 0xFFL) << 48
347 | (in[offset++] & 0xFFL) << 40
348 | (in[offset++] & 0xFFL) << 32
349 | (in[offset++] & 0xFFL) << 24
350 | (in[offset++] & 0xFFL) << 16
351 | (in[offset++] & 0xFFL) << 8
352 | (in[offset++] & 0xFFL);
353 n7 = (in[offset++] & 0xFFL) << 56
354 | (in[offset++] & 0xFFL) << 48
355 | (in[offset++] & 0xFFL) << 40
356 | (in[offset++] & 0xFFL) << 32
357 | (in[offset++] & 0xFFL) << 24
358 | (in[offset++] & 0xFFL) << 16
359 | (in[offset++] & 0xFFL) << 8
360 | (in[offset++] & 0xFFL);
361 // transform K into the key schedule Kr; 0 <= r <= R
362 k00 = H0;
363 k01 = H1;
364 k02 = H2;
365 k03 = H3;
366 k04 = H4;
367 k05 = H5;
368 k06 = H6;
369 k07 = H7;
370 nn0 = n0 ^ k00;
371 nn1 = n1 ^ k01;
372 nn2 = n2 ^ k02;
373 nn3 = n3 ^ k03;
374 nn4 = n4 ^ k04;
375 nn5 = n5 ^ k05;
376 nn6 = n6 ^ k06;
377 nn7 = n7 ^ k07;
378 // intermediate cipher output
379 w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0L;
380 for (int r = 0; r < R; r++)
382 // 1. compute intermediate round key schedule by applying ro[rc]
383 // to the previous round key schedule --rc being the round constant
384 Kr0 = T0[(int)((k00 >> 56) & 0xFFL)]
385 ^ T1[(int)((k07 >> 48) & 0xFFL)]
386 ^ T2[(int)((k06 >> 40) & 0xFFL)]
387 ^ T3[(int)((k05 >> 32) & 0xFFL)]
388 ^ T4[(int)((k04 >> 24) & 0xFFL)]
389 ^ T5[(int)((k03 >> 16) & 0xFFL)]
390 ^ T6[(int)((k02 >> 8) & 0xFFL)]
391 ^ T7[(int)( k01 & 0xFFL)] ^ rc[r];
392 Kr1 = T0[(int)((k01 >> 56) & 0xFFL)]
393 ^ T1[(int)((k00 >> 48) & 0xFFL)]
394 ^ T2[(int)((k07 >> 40) & 0xFFL)]
395 ^ T3[(int)((k06 >> 32) & 0xFFL)]
396 ^ T4[(int)((k05 >> 24) & 0xFFL)]
397 ^ T5[(int)((k04 >> 16) & 0xFFL)]
398 ^ T6[(int)((k03 >> 8) & 0xFFL)]
399 ^ T7[(int)( k02 & 0xFFL)];
400 Kr2 = T0[(int)((k02 >> 56) & 0xFFL)]
401 ^ T1[(int)((k01 >> 48) & 0xFFL)]
402 ^ T2[(int)((k00 >> 40) & 0xFFL)]
403 ^ T3[(int)((k07 >> 32) & 0xFFL)]
404 ^ T4[(int)((k06 >> 24) & 0xFFL)]
405 ^ T5[(int)((k05 >> 16) & 0xFFL)]
406 ^ T6[(int)((k04 >> 8) & 0xFFL)]
407 ^ T7[(int)( k03 & 0xFFL)];
408 Kr3 = T0[(int)((k03 >> 56) & 0xFFL)]
409 ^ T1[(int)((k02 >> 48) & 0xFFL)]
410 ^ T2[(int)((k01 >> 40) & 0xFFL)]
411 ^ T3[(int)((k00 >> 32) & 0xFFL)]
412 ^ T4[(int)((k07 >> 24) & 0xFFL)]
413 ^ T5[(int)((k06 >> 16) & 0xFFL)]
414 ^ T6[(int)((k05 >> 8) & 0xFFL)]
415 ^ T7[(int)( k04 & 0xFFL)];
416 Kr4 = T0[(int)((k04 >> 56) & 0xFFL)]
417 ^ T1[(int)((k03 >> 48) & 0xFFL)]
418 ^ T2[(int)((k02 >> 40) & 0xFFL)]
419 ^ T3[(int)((k01 >> 32) & 0xFFL)]
420 ^ T4[(int)((k00 >> 24) & 0xFFL)]
421 ^ T5[(int)((k07 >> 16) & 0xFFL)]
422 ^ T6[(int)((k06 >> 8) & 0xFFL)]
423 ^ T7[(int)( k05 & 0xFFL)];
424 Kr5 = T0[(int)((k05 >> 56) & 0xFFL)]
425 ^ T1[(int)((k04 >> 48) & 0xFFL)]
426 ^ T2[(int)((k03 >> 40) & 0xFFL)]
427 ^ T3[(int)((k02 >> 32) & 0xFFL)]
428 ^ T4[(int)((k01 >> 24) & 0xFFL)]
429 ^ T5[(int)((k00 >> 16) & 0xFFL)]
430 ^ T6[(int)((k07 >> 8) & 0xFFL)]
431 ^ T7[(int)( k06 & 0xFFL)];
432 Kr6 = T0[(int)((k06 >> 56) & 0xFFL)]
433 ^ T1[(int)((k05 >> 48) & 0xFFL)]
434 ^ T2[(int)((k04 >> 40) & 0xFFL)]
435 ^ T3[(int)((k03 >> 32) & 0xFFL)]
436 ^ T4[(int)((k02 >> 24) & 0xFFL)]
437 ^ T5[(int)((k01 >> 16) & 0xFFL)]
438 ^ T6[(int)((k00 >> 8) & 0xFFL)]
439 ^ T7[(int)( k07 & 0xFFL)];
440 Kr7 = T0[(int)((k07 >> 56) & 0xFFL)]
441 ^ T1[(int)((k06 >> 48) & 0xFFL)]
442 ^ T2[(int)((k05 >> 40) & 0xFFL)]
443 ^ T3[(int)((k04 >> 32) & 0xFFL)]
444 ^ T4[(int)((k03 >> 24) & 0xFFL)]
445 ^ T5[(int)((k02 >> 16) & 0xFFL)]
446 ^ T6[(int)((k01 >> 8) & 0xFFL)]
447 ^ T7[(int)( k00 & 0xFFL)];
448 k00 = Kr0;
449 k01 = Kr1;
450 k02 = Kr2;
451 k03 = Kr3;
452 k04 = Kr4;
453 k05 = Kr5;
454 k06 = Kr6;
455 k07 = Kr7;
456 // 2. incrementally compute the cipher output
457 w0 = T0[(int)((nn0 >> 56) & 0xFFL)]
458 ^ T1[(int)((nn7 >> 48) & 0xFFL)]
459 ^ T2[(int)((nn6 >> 40) & 0xFFL)]
460 ^ T3[(int)((nn5 >> 32) & 0xFFL)]
461 ^ T4[(int)((nn4 >> 24) & 0xFFL)]
462 ^ T5[(int)((nn3 >> 16) & 0xFFL)]
463 ^ T6[(int)((nn2 >> 8) & 0xFFL)]
464 ^ T7[(int)( nn1 & 0xFFL)] ^ Kr0;
465 w1 = T0[(int)((nn1 >> 56) & 0xFFL)]
466 ^ T1[(int)((nn0 >> 48) & 0xFFL)]
467 ^ T2[(int)((nn7 >> 40) & 0xFFL)]
468 ^ T3[(int)((nn6 >> 32) & 0xFFL)]
469 ^ T4[(int)((nn5 >> 24) & 0xFFL)]
470 ^ T5[(int)((nn4 >> 16) & 0xFFL)]
471 ^ T6[(int)((nn3 >> 8) & 0xFFL)]
472 ^ T7[(int)( nn2 & 0xFFL)] ^ Kr1;
473 w2 = T0[(int)((nn2 >> 56) & 0xFFL)]
474 ^ T1[(int)((nn1 >> 48) & 0xFFL)]
475 ^ T2[(int)((nn0 >> 40) & 0xFFL)]
476 ^ T3[(int)((nn7 >> 32) & 0xFFL)]
477 ^ T4[(int)((nn6 >> 24) & 0xFFL)]
478 ^ T5[(int)((nn5 >> 16) & 0xFFL)]
479 ^ T6[(int)((nn4 >> 8) & 0xFFL)]
480 ^ T7[(int)( nn3 & 0xFFL)] ^ Kr2;
481 w3 = T0[(int)((nn3 >> 56) & 0xFFL)]
482 ^ T1[(int)((nn2 >> 48) & 0xFFL)]
483 ^ T2[(int)((nn1 >> 40) & 0xFFL)]
484 ^ T3[(int)((nn0 >> 32) & 0xFFL)]
485 ^ T4[(int)((nn7 >> 24) & 0xFFL)]
486 ^ T5[(int)((nn6 >> 16) & 0xFFL)]
487 ^ T6[(int)((nn5 >> 8) & 0xFFL)]
488 ^ T7[(int)( nn4 & 0xFFL)] ^ Kr3;
489 w4 = T0[(int)((nn4 >> 56) & 0xFFL)]
490 ^ T1[(int)((nn3 >> 48) & 0xFFL)]
491 ^ T2[(int)((nn2 >> 40) & 0xFFL)]
492 ^ T3[(int)((nn1 >> 32) & 0xFFL)]
493 ^ T4[(int)((nn0 >> 24) & 0xFFL)]
494 ^ T5[(int)((nn7 >> 16) & 0xFFL)]
495 ^ T6[(int)((nn6 >> 8) & 0xFFL)]
496 ^ T7[(int)( nn5 & 0xFFL)] ^ Kr4;
497 w5 = T0[(int)((nn5 >> 56) & 0xFFL)]
498 ^ T1[(int)((nn4 >> 48) & 0xFFL)]
499 ^ T2[(int)((nn3 >> 40) & 0xFFL)]
500 ^ T3[(int)((nn2 >> 32) & 0xFFL)]
501 ^ T4[(int)((nn1 >> 24) & 0xFFL)]
502 ^ T5[(int)((nn0 >> 16) & 0xFFL)]
503 ^ T6[(int)((nn7 >> 8) & 0xFFL)]
504 ^ T7[(int)( nn6 & 0xFFL)] ^ Kr5;
505 w6 = T0[(int)((nn6 >> 56) & 0xFFL)]
506 ^ T1[(int)((nn5 >> 48) & 0xFFL)]
507 ^ T2[(int)((nn4 >> 40) & 0xFFL)]
508 ^ T3[(int)((nn3 >> 32) & 0xFFL)]
509 ^ T4[(int)((nn2 >> 24) & 0xFFL)]
510 ^ T5[(int)((nn1 >> 16) & 0xFFL)]
511 ^ T6[(int)((nn0 >> 8) & 0xFFL)]
512 ^ T7[(int)( nn7 & 0xFFL)] ^ Kr6;
513 w7 = T0[(int)((nn7 >> 56) & 0xFFL)]
514 ^ T1[(int)((nn6 >> 48) & 0xFFL)]
515 ^ T2[(int)((nn5 >> 40) & 0xFFL)]
516 ^ T3[(int)((nn4 >> 32) & 0xFFL)]
517 ^ T4[(int)((nn3 >> 24) & 0xFFL)]
518 ^ T5[(int)((nn2 >> 16) & 0xFFL)]
519 ^ T6[(int)((nn1 >> 8) & 0xFFL)]
520 ^ T7[(int)( nn0 & 0xFFL)] ^ Kr7;
521 nn0 = w0;
522 nn1 = w1;
523 nn2 = w2;
524 nn3 = w3;
525 nn4 = w4;
526 nn5 = w5;
527 nn6 = w6;
528 nn7 = w7;
530 // apply the Miyaguchi-Preneel hash scheme
531 H0 ^= w0 ^ n0;
532 H1 ^= w1 ^ n1;
533 H2 ^= w2 ^ n2;
534 H3 ^= w3 ^ n3;
535 H4 ^= w4 ^ n4;
536 H5 ^= w5 ^ n5;
537 H6 ^= w6 ^ n6;
538 H7 ^= w7 ^ n7;
541 protected byte[] padBuffer()
543 // [WHIRLPOOL] p. 6:
544 // "...padded with a 1-bit, then with as few 0-bits as necessary to
545 // obtain a bit string whose length is an odd multiple of 256, and
546 // finally with the 256-bit right-justified binary representation of L."
547 // in this implementation we use 'count' as the number of bytes hashed
548 // so far. hence the minimal number of bytes added to the message proper
549 // are 33 (1 for the 1-bit followed by the 0-bits and the encoding of
550 // the count framed in a 256-bit block). our formula is then:
551 // count + 33 + padding = 0 (mod BLOCK_SIZE)
552 int n = (int)((count + 33) % BLOCK_SIZE);
553 int padding = n == 0 ? 33 : BLOCK_SIZE - n + 33;
554 byte[] result = new byte[padding];
555 // padding is always binary 1 followed by binary 0s
556 result[0] = (byte) 0x80;
557 // save (right justified) the number of bits hashed
558 long bits = count * 8;
559 int i = padding - 8;
560 result[i++] = (byte)(bits >>> 56);
561 result[i++] = (byte)(bits >>> 48);
562 result[i++] = (byte)(bits >>> 40);
563 result[i++] = (byte)(bits >>> 32);
564 result[i++] = (byte)(bits >>> 24);
565 result[i++] = (byte)(bits >>> 16);
566 result[i++] = (byte)(bits >>> 8);
567 result[i ] = (byte) bits;
568 return result;
571 protected byte[] getResult()
573 // apply inverse mu to the context
574 return new byte[] {
575 (byte)(H0 >>> 56), (byte)(H0 >>> 48), (byte)(H0 >>> 40), (byte)(H0 >>> 32),
576 (byte)(H0 >>> 24), (byte)(H0 >>> 16), (byte)(H0 >>> 8), (byte) H0,
577 (byte)(H1 >>> 56), (byte)(H1 >>> 48), (byte)(H1 >>> 40), (byte)(H1 >>> 32),
578 (byte)(H1 >>> 24), (byte)(H1 >>> 16), (byte)(H1 >>> 8), (byte) H1,
579 (byte)(H2 >>> 56), (byte)(H2 >>> 48), (byte)(H2 >>> 40), (byte)(H2 >>> 32),
580 (byte)(H2 >>> 24), (byte)(H2 >>> 16), (byte)(H2 >>> 8), (byte) H2,
581 (byte)(H3 >>> 56), (byte)(H3 >>> 48), (byte)(H3 >>> 40), (byte)(H3 >>> 32),
582 (byte)(H3 >>> 24), (byte)(H3 >>> 16), (byte)(H3 >>> 8), (byte) H3,
583 (byte)(H4 >>> 56), (byte)(H4 >>> 48), (byte)(H4 >>> 40), (byte)(H4 >>> 32),
584 (byte)(H4 >>> 24), (byte)(H4 >>> 16), (byte)(H4 >>> 8), (byte) H4,
585 (byte)(H5 >>> 56), (byte)(H5 >>> 48), (byte)(H5 >>> 40), (byte)(H5 >>> 32),
586 (byte)(H5 >>> 24), (byte)(H5 >>> 16), (byte)(H5 >>> 8), (byte) H5,
587 (byte)(H6 >>> 56), (byte)(H6 >>> 48), (byte)(H6 >>> 40), (byte)(H6 >>> 32),
588 (byte)(H6 >>> 24), (byte)(H6 >>> 16), (byte)(H6 >>> 8), (byte) H6,
589 (byte)(H7 >>> 56), (byte)(H7 >>> 48), (byte)(H7 >>> 40), (byte)(H7 >>> 32),
590 (byte)(H7 >>> 24), (byte)(H7 >>> 16), (byte)(H7 >>> 8), (byte) H7 };
594 protected void resetContext()
596 H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L;
599 public boolean selfTest()
601 if (valid == null)
603 String d = Util.toString(new Whirlpool().digest());
604 valid = Boolean.valueOf(DIGEST0.equals(d));
606 return valid.booleanValue();