Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libjava / classpath / gnu / java / security / hash / Whirlpool.java
1 /* Whirlpool.java --
2    Copyright (C) 2001, 2002, 2006, 2010 Free Software Foundation, Inc.
3
4 This file is a part of GNU Classpath.
5
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.
10
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.
15
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
20
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.
25
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.  */
37
38
39 package gnu.java.security.hash;
40
41 import gnu.java.lang.CPStringBuilder;
42
43 import gnu.java.security.Configuration;
44 import gnu.java.security.Registry;
45 import gnu.java.security.util.Util;
46
47 import java.util.logging.Logger;
48
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>
66  */
67 public final class Whirlpool
68     extends BaseHash
69 {
70   private static final Logger log = Configuration.DEBUG ?
71                         Logger.getLogger(Whirlpool.class.getName()) : null;
72
73   private static final int BLOCK_SIZE = 64; // inner block size in bytes
74
75   /** The digest of the 0-bit long message. */
76   private static final String DIGEST0 =
77       "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A7"
78     + "3E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3";
79
80   /** Default number of rounds. */
81   private static final int R = 10;
82
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";
101
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];
111
112   /** The round constants. */
113   private static final long[] rc = new long[R];
114
115   /** caches the result of the correctness test, once executed. */
116   private static Boolean valid;
117
118   /** The 512-bit context as 8 longs. */
119   private long H0, H1, H2, H3, H4, H5, H6, H7;
120
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;
124
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;
128
129   /** work area for holding block cipher's intermediate values. */
130   private long w0, w1, w2, w3, w4, w5, w6, w7;
131
132   static
133     {
134       long time = System.currentTimeMillis();
135       int ROOT = 0x11D; // para. 2.1 [WHIRLPOOL]
136       int i, r, j;
137       long s1, s2, s4, s5, s8, s9, t;
138       char c;
139       final byte[] S = new byte[256];
140       for (i = 0; i < 256; i++)
141         {
142           c = S_box.charAt(i >>> 1);
143
144           s1 = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL;
145           s2 = s1 << 1;
146           if (s2 > 0xFFL)
147             s2 ^= ROOT;
148
149           s4 = s2 << 1;
150           if (s4 > 0xFFL)
151             s4 ^= ROOT;
152
153           s5 = s4 ^ s1;
154           s8 = s4 << 1;
155           if (s8 > 0xFFL)
156             s8 ^= ROOT;
157
158           s9 = s8 ^ s1;
159
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;
169         }
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)
181         {
182           log.fine("Static data");
183           log.fine("T0[]:");
184           CPStringBuilder sb;
185           for (i = 0; i < 64; i++)
186             {
187               sb = new CPStringBuilder();
188               for (j = 0; j < 4; j++)
189                 sb.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
190
191               log.fine(sb.toString());
192             }
193           log.fine("T1[]:");
194           for (i = 0; i < 64; i++)
195             {
196               sb = new CPStringBuilder();
197               for (j = 0; j < 4; j++)
198                 sb.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
199
200               log.fine(sb.toString());
201             }
202           log.fine("T2[]:");
203           for (i = 0; i < 64; i++)
204             {
205               sb = new CPStringBuilder();
206               for (j = 0; j < 4; j++)
207                 sb.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
208
209               log.fine(sb.toString());
210             }
211           log.fine("T3[]:");
212           for (i = 0; i < 64; i++)
213             {
214               sb = new CPStringBuilder();
215               for (j = 0; j < 4; j++)
216                 sb.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
217
218               log.fine(sb.toString());
219             }
220           log.fine("\nT4[]:");
221           for (i = 0; i < 64; i++)
222             {
223               sb = new CPStringBuilder();
224               for (j = 0; j < 4; j++)
225                 sb.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
226
227               log.fine(sb.toString());
228             }
229           log.fine("T5[]:");
230           for (i = 0; i < 64; i++)
231             {
232               sb = new CPStringBuilder();
233               for (j = 0; j < 4; j++)
234                 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
235
236               log.fine(sb.toString());
237             }
238           log.fine("T6[]:");
239           for (i = 0; i < 64; i++)
240             {
241               sb = new CPStringBuilder();
242               for (j = 0; j < 4; j++)
243                 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
244
245               log.fine(sb.toString());
246             }
247           log.fine("T7[]:");
248           for (i = 0; i < 64; i++)
249             {
250               sb = new CPStringBuilder();
251               for (j = 0; j < 4; j++)
252                 sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
253
254               log.fine(sb.toString());
255             }
256           log.fine("rc[]:");
257           for (i = 0; i < R; i++)
258             log.fine("0x" + Util.toString(rc[i]));
259
260           log.fine("Total initialization time: " + time + " ms.");
261         }
262     }
263
264   /** Trivial 0-arguments constructor. */
265   public Whirlpool()
266   {
267     super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE);
268   }
269
270   /**
271    * Private constructor for cloning purposes.
272    *
273    * @param md the instance to clone.
274    */
275   private Whirlpool(Whirlpool md)
276   {
277     this();
278
279     this.H0 = md.H0;
280     this.H1 = md.H1;
281     this.H2 = md.H2;
282     this.H3 = md.H3;
283     this.H4 = md.H4;
284     this.H5 = md.H5;
285     this.H6 = md.H6;
286     this.H7 = md.H7;
287     this.count = md.count;
288     this.buffer = (byte[]) md.buffer.clone();
289   }
290
291   public Object clone()
292   {
293     return (new Whirlpool(this));
294   }
295
296   protected void transform(byte[] in, int offset)
297   {
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
364     k00 = H0;
365     k01 = H1;
366     k02 = H2;
367     k03 = H3;
368     k04 = H4;
369     k05 = H5;
370     k06 = H6;
371     k07 = H7;
372     nn0 = n0 ^ k00;
373     nn1 = n1 ^ k01;
374     nn2 = n2 ^ k02;
375     nn3 = n3 ^ k03;
376     nn4 = n4 ^ k04;
377     nn5 = n5 ^ k05;
378     nn6 = n6 ^ k06;
379     nn7 = n7 ^ k07;
380     // intermediate cipher output
381     w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0L;
382     for (int r = 0; r < R; r++)
383       {
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)];
450         k00 = Kr0;
451         k01 = Kr1;
452         k02 = Kr2;
453         k03 = Kr3;
454         k04 = Kr4;
455         k05 = Kr5;
456         k06 = Kr6;
457         k07 = Kr7;
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;
523         nn0 = w0;
524         nn1 = w1;
525         nn2 = w2;
526         nn3 = w3;
527         nn4 = w4;
528         nn5 = w5;
529         nn6 = w6;
530         nn7 = w7;
531       }
532     // apply the Miyaguchi-Preneel hash scheme
533     H0 ^= w0 ^ n0;
534     H1 ^= w1 ^ n1;
535     H2 ^= w2 ^ n2;
536     H3 ^= w3 ^ n3;
537     H4 ^= w4 ^ n4;
538     H5 ^= w5 ^ n5;
539     H6 ^= w6 ^ n6;
540     H7 ^= w7 ^ n7;
541   }
542
543   protected byte[] padBuffer()
544   {
545     // [WHIRLPOOL] p. 6:
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;
561     int i = padding - 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;
570     return result;
571   }
572
573   protected byte[] getResult()
574   {
575     // apply inverse mu to the context
576     return new byte[] {
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 };
593
594   }
595
596   protected void resetContext()
597   {
598     H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L;
599   }
600
601   public boolean selfTest()
602   {
603     if (valid == null)
604       {
605         String d = Util.toString(new Whirlpool().digest());
606         valid = Boolean.valueOf(DIGEST0.equals(d));
607       }
608     return valid.booleanValue();
609   }
610 }