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 sb.toString()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 sb.toString()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 sb.toString()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 sb.toString()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 sb.toString()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 sb.toString()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 sb.toString()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 sb.toString()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. */ Whirlpool()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 */ Whirlpool(Whirlpool md)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 clone()291 public Object clone() 292 { 293 return (new Whirlpool(this)); 294 } 295 transform(byte[] in, int offset)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 padBuffer()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 getResult()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 resetContext()596 protected void resetContext() 597 { 598 H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L; 599 } 600 selfTest()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 } 611