| 1 |
769 |
jeremybenn |
/* Whirlpool.java --
|
| 2 |
|
|
Copyright (C) 2001, 2002, 2006 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 = Logger.getLogger(Whirlpool.class.getName());
|
| 71 |
|
|
private static final int BLOCK_SIZE = 64; // inner block size in bytes
|
| 72 |
|
|
|
| 73 |
|
|
/** The digest of the 0-bit long message. */
|
| 74 |
|
|
private static final String DIGEST0 =
|
| 75 |
|
|
"19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A7"
|
| 76 |
|
|
+ "3E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3";
|
| 77 |
|
|
|
| 78 |
|
|
/** Default number of rounds. */
|
| 79 |
|
|
private static final int R = 10;
|
| 80 |
|
|
|
| 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";
|
| 99 |
|
|
|
| 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];
|
| 109 |
|
|
|
| 110 |
|
|
/** The round constants. */
|
| 111 |
|
|
private static final long[] rc = new long[R];
|
| 112 |
|
|
|
| 113 |
|
|
/** caches the result of the correctness test, once executed. */
|
| 114 |
|
|
private static Boolean valid;
|
| 115 |
|
|
|
| 116 |
|
|
/** The 512-bit context as 8 longs. */
|
| 117 |
|
|
private long H0, H1, H2, H3, H4, H5, H6, H7;
|
| 118 |
|
|
|
| 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;
|
| 122 |
|
|
|
| 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;
|
| 126 |
|
|
|
| 127 |
|
|
/** work area for holding block cipher's intermediate values. */
|
| 128 |
|
|
private long w0, w1, w2, w3, w4, w5, w6, w7;
|
| 129 |
|
|
|
| 130 |
|
|
static
|
| 131 |
|
|
{
|
| 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++)
|
| 139 |
|
|
{
|
| 140 |
|
|
c = S_box.charAt(i >>> 1);
|
| 141 |
|
|
|
| 142 |
|
|
s1 = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL;
|
| 143 |
|
|
s2 = s1 << 1;
|
| 144 |
|
|
if (s2 > 0xFFL)
|
| 145 |
|
|
s2 ^= ROOT;
|
| 146 |
|
|
|
| 147 |
|
|
s4 = s2 << 1;
|
| 148 |
|
|
if (s4 > 0xFFL)
|
| 149 |
|
|
s4 ^= ROOT;
|
| 150 |
|
|
|
| 151 |
|
|
s5 = s4 ^ s1;
|
| 152 |
|
|
s8 = s4 << 1;
|
| 153 |
|
|
if (s8 > 0xFFL)
|
| 154 |
|
|
s8 ^= ROOT;
|
| 155 |
|
|
|
| 156 |
|
|
s9 = s8 ^ s1;
|
| 157 |
|
|
|
| 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;
|
| 167 |
|
|
}
|
| 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)
|
| 179 |
|
|
{
|
| 180 |
|
|
log.fine("Static data");
|
| 181 |
|
|
log.fine("T0[]:");
|
| 182 |
|
|
CPStringBuilder sb;
|
| 183 |
|
|
for (i = 0; i < 64; i++)
|
| 184 |
|
|
{
|
| 185 |
|
|
sb = new CPStringBuilder();
|
| 186 |
|
|
for (j = 0; j < 4; j++)
|
| 187 |
|
|
sb.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
|
| 188 |
|
|
|
| 189 |
|
|
log.fine(sb.toString());
|
| 190 |
|
|
}
|
| 191 |
|
|
log.fine("T1[]:");
|
| 192 |
|
|
for (i = 0; i < 64; i++)
|
| 193 |
|
|
{
|
| 194 |
|
|
sb = new CPStringBuilder();
|
| 195 |
|
|
for (j = 0; j < 4; j++)
|
| 196 |
|
|
sb.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
|
| 197 |
|
|
|
| 198 |
|
|
log.fine(sb.toString());
|
| 199 |
|
|
}
|
| 200 |
|
|
log.fine("T2[]:");
|
| 201 |
|
|
for (i = 0; i < 64; i++)
|
| 202 |
|
|
{
|
| 203 |
|
|
sb = new CPStringBuilder();
|
| 204 |
|
|
for (j = 0; j < 4; j++)
|
| 205 |
|
|
sb.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
|
| 206 |
|
|
|
| 207 |
|
|
log.fine(sb.toString());
|
| 208 |
|
|
}
|
| 209 |
|
|
log.fine("T3[]:");
|
| 210 |
|
|
for (i = 0; i < 64; i++)
|
| 211 |
|
|
{
|
| 212 |
|
|
sb = new CPStringBuilder();
|
| 213 |
|
|
for (j = 0; j < 4; j++)
|
| 214 |
|
|
sb.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
|
| 215 |
|
|
|
| 216 |
|
|
log.fine(sb.toString());
|
| 217 |
|
|
}
|
| 218 |
|
|
log.fine("\nT4[]:");
|
| 219 |
|
|
for (i = 0; i < 64; i++)
|
| 220 |
|
|
{
|
| 221 |
|
|
sb = new CPStringBuilder();
|
| 222 |
|
|
for (j = 0; j < 4; j++)
|
| 223 |
|
|
sb.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
|
| 224 |
|
|
|
| 225 |
|
|
log.fine(sb.toString());
|
| 226 |
|
|
}
|
| 227 |
|
|
log.fine("T5[]:");
|
| 228 |
|
|
for (i = 0; i < 64; i++)
|
| 229 |
|
|
{
|
| 230 |
|
|
sb = new CPStringBuilder();
|
| 231 |
|
|
for (j = 0; j < 4; j++)
|
| 232 |
|
|
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
|
| 233 |
|
|
|
| 234 |
|
|
log.fine(sb.toString());
|
| 235 |
|
|
}
|
| 236 |
|
|
log.fine("T6[]:");
|
| 237 |
|
|
for (i = 0; i < 64; i++)
|
| 238 |
|
|
{
|
| 239 |
|
|
sb = new CPStringBuilder();
|
| 240 |
|
|
for (j = 0; j < 4; j++)
|
| 241 |
|
|
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
|
| 242 |
|
|
|
| 243 |
|
|
log.fine(sb.toString());
|
| 244 |
|
|
}
|
| 245 |
|
|
log.fine("T7[]:");
|
| 246 |
|
|
for (i = 0; i < 64; i++)
|
| 247 |
|
|
{
|
| 248 |
|
|
sb = new CPStringBuilder();
|
| 249 |
|
|
for (j = 0; j < 4; j++)
|
| 250 |
|
|
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
|
| 251 |
|
|
|
| 252 |
|
|
log.fine(sb.toString());
|
| 253 |
|
|
}
|
| 254 |
|
|
log.fine("rc[]:");
|
| 255 |
|
|
for (i = 0; i < R; i++)
|
| 256 |
|
|
log.fine("0x" + Util.toString(rc[i]));
|
| 257 |
|
|
|
| 258 |
|
|
log.fine("Total initialization time: " + time + " ms.");
|
| 259 |
|
|
}
|
| 260 |
|
|
}
|
| 261 |
|
|
|
| 262 |
|
|
/** Trivial 0-arguments constructor. */
|
| 263 |
|
|
public Whirlpool()
|
| 264 |
|
|
{
|
| 265 |
|
|
super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE);
|
| 266 |
|
|
}
|
| 267 |
|
|
|
| 268 |
|
|
/**
|
| 269 |
|
|
* Private constructor for cloning purposes.
|
| 270 |
|
|
*
|
| 271 |
|
|
* @param md the instance to clone.
|
| 272 |
|
|
*/
|
| 273 |
|
|
private Whirlpool(Whirlpool md)
|
| 274 |
|
|
{
|
| 275 |
|
|
this();
|
| 276 |
|
|
|
| 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();
|
| 287 |
|
|
}
|
| 288 |
|
|
|
| 289 |
|
|
public Object clone()
|
| 290 |
|
|
{
|
| 291 |
|
|
return (new Whirlpool(this));
|
| 292 |
|
|
}
|
| 293 |
|
|
|
| 294 |
|
|
protected void transform(byte[] in, int offset)
|
| 295 |
|
|
{
|
| 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++)
|
| 381 |
|
|
{
|
| 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;
|
| 529 |
|
|
}
|
| 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;
|
| 539 |
|
|
}
|
| 540 |
|
|
|
| 541 |
|
|
protected byte[] padBuffer()
|
| 542 |
|
|
{
|
| 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;
|
| 569 |
|
|
}
|
| 570 |
|
|
|
| 571 |
|
|
protected byte[] getResult()
|
| 572 |
|
|
{
|
| 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 };
|
| 591 |
|
|
|
| 592 |
|
|
}
|
| 593 |
|
|
|
| 594 |
|
|
protected void resetContext()
|
| 595 |
|
|
{
|
| 596 |
|
|
H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L;
|
| 597 |
|
|
}
|
| 598 |
|
|
|
| 599 |
|
|
public boolean selfTest()
|
| 600 |
|
|
{
|
| 601 |
|
|
if (valid == null)
|
| 602 |
|
|
{
|
| 603 |
|
|
String d = Util.toString(new Whirlpool().digest());
|
| 604 |
|
|
valid = Boolean.valueOf(DIGEST0.equals(d));
|
| 605 |
|
|
}
|
| 606 |
|
|
return valid.booleanValue();
|
| 607 |
|
|
}
|
| 608 |
|
|
}
|