00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
package com.quadcap.crypto;
00040
00041
00042
00043
00044
00045
00046
import java.util.Random;
00047
00048
import java.nio.ByteBuffer;
00049
import java.nio.IntBuffer;
00050
00051
import com.quadcap.util.Debug;
00052
import com.quadcap.util.text.Text;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 public class Rijndael extends AbstractSymmetricKey implements
SymmetricKey {
00075 byte[]
keyBytes = null;
00076
00077
00078
00079
00080 public Rijndael() {}
00081
00082
00083
00084
00085 public void init(String s)
throws Exception {
00086 String[] v =
Text.extractN(s,
"*:*");
00087 byte[] k = v[1].getBytes();
00088 init(k);
00089 }
00090
00091
00092
00093
00094 final void init(byte[] k) {
00095
try {
00096
this.coreInit(k,
false);
00097
Rijndael decryptor =
new Rijndael();
00098 decryptor.
coreInit(k,
true);
00099 dkey =
new DecryptionKey(decryptor);
00100 }
catch (Exception e) {
00101
Debug.print(e);
00102
throw new RuntimeException(e.toString());
00103 }
00104 }
00105
00106
00107
00108
00109 public void init(Random r) {
00110 byte[] b =
new byte[
KEYSIZE];
00111 r.nextBytes(b);
00112 init(b);
00113 }
00114
00115
00116
00117
00118 public String
toString() {
00119
return "Rijndael:" +
new String(
keyBytes);
00120 }
00121
00122
00123
00124
00125 public void encrypt(ByteBuffer m, ByteBuffer c) {
00126
while (m.position() < m.limit()) {
00127
blockEncrypt(m, c);
00128 }
00129 }
00130
00131
00132
00133
00134 public void decrypt(ByteBuffer c, ByteBuffer m) {
00135
while (c.position() < c.limit()) {
00136
blockDecrypt(c, m);
00137 }
00138 }
00139
00140 static final int KEYSIZE = 16;
00141
00142
private boolean
00143 ROUNDS_12,
00144
ROUNDS_14;
00145
00146
00147 private boolean decrypt;
00148
00149
00150 private int[]
K;
00151
00152
00153 private int limit;
00154
00155
00156 protected void coreInit(byte[] userKey,
boolean decrypt)
00157
throws Exception
00158 {
00159
this.keyBytes = userKey;
00160
00161
int len = userKey.length;
00162
if (len != 16 && len != 24 && len != 32) {
00163
throw new Exception(
"Invalid user key length");
00164 }
00165
00166
this.decrypt = decrypt;
00167
this.K =
makeKey(userKey, decrypt);
00168
if (decrypt)
invertKey(
this.
K);
00169
00170
ROUNDS_12 = (len >= 24);
00171
ROUNDS_14 = (len == 32);
00172
00173
this.limit =
getRounds(len) * 4;
00174 }
00175
00176 public int getBlockSize() {
return BLOCK_SIZE; }
00177
00178 private static final int BLOCK_SIZE = 16;
00179
00180 private static final String
SS =
00181
"\u637C\u777B\uF26B\u6FC5\u3001\u672B\uFED7\uAB76" +
00182
"\uCA82\uC97D\uFA59\u47F0\uADD4\uA2AF\u9CA4\u72C0" +
00183
"\uB7FD\u9326\u363F\uF7CC\u34A5\uE5F1\u71D8\u3115" +
00184
"\u04C7\u23C3\u1896\u059A\u0712\u80E2\uEB27\uB275" +
00185
"\u0983\u2C1A\u1B6E\u5AA0\u523B\uD6B3\u29E3\u2F84" +
00186
"\u53D1\u00ED\u20FC\uB15B\u6ACB\uBE39\u4A4C\u58CF" +
00187
"\uD0EF\uAAFB\u434D\u3385\u45F9\u027F\u503C\u9FA8" +
00188
"\u51A3\u408F\u929D\u38F5\uBCB6\uDA21\u10FF\uF3D2" +
00189
"\uCD0C\u13EC\u5F97\u4417\uC4A7\u7E3D\u645D\u1973" +
00190
"\u6081\u4FDC\u222A\u9088\u46EE\uB814\uDE5E\u0BDB" +
00191
"\uE032\u3A0A\u4906\u245C\uC2D3\uAC62\u9195\uE479" +
00192
"\uE7C8\u376D\u8DD5\u4EA9\u6C56\uF4EA\u657A\uAE08" +
00193
"\uBA78\u252E\u1CA6\uB4C6\uE8DD\u741F\u4BBD\u8B8A" +
00194
"\u703E\uB566\u4803\uF60E\u6135\u57B9\u86C1\u1D9E" +
00195
"\uE1F8\u9811\u69D9\u8E94\u9B1E\u87E9\uCE55\u28DF" +
00196
"\u8CA1\u890D\uBFE6\u4268\u4199\u2D0F\uB054\uBB16";
00197
00198
private static final byte[]
00199 S =
new byte[256],
00200 Si =
new byte[256];
00201
00202
private static final int[]
00203 T1 =
new int[256],
00204 T2 =
new int[256],
00205 T3 =
new int[256],
00206 T4 =
new int[256],
00207 T5 =
new int[256],
00208 T6 =
new int[256],
00209 T7 =
new int[256],
00210 T8 =
new int[256];
00211
00212
private static final int[]
00213 U1 =
new int[256],
00214 U2 =
new int[256],
00215 U3 =
new int[256],
00216 U4 =
new int[256];
00217
00218 private static final byte[]
rcon =
new byte[30];
00219
00220
00221
00222
00223
00224
static {
00225
int ROOT = 0x11B;
00226
int i, j = 0;
00227
00228
for (i = 0; i < 256; i++) {
00229
int s, s2, s3, i2, i4, i8, i9, ib,
id, ie, t;
00230
char c =
SS.charAt(i >>> 1);
00231
S[i] = (byte)(((i & 1) == 0) ? c >>> 8 : c & 0xFF);
00232 s =
S[i] & 0xFF;
00233 Si[s] = (byte)i;
00234 s2 = s << 1;
00235
if (s2 >= 0x100) {
00236 s2 ^= ROOT;
00237 }
00238 s3 = s2 ^ s;
00239 i2 = i << 1;
00240
if (i2 >= 0x100) {
00241 i2 ^= ROOT;
00242 }
00243 i4 = i2 << 1;
00244
if (i4 >= 0x100) {
00245 i4 ^= ROOT;
00246 }
00247 i8 = i4 << 1;
00248
if (i8 >= 0x100) {
00249 i8 ^= ROOT;
00250 }
00251 i9 = i8 ^ i;
00252 ib = i9 ^ i2;
00253
id = i9 ^ i4;
00254 ie = i8 ^ i4 ^ i2;
00255
00256
T1[i] = t = (s2 << 24) | (s << 16) | (s << 8) | s3;
00257 T2[i] = (t >>> 8) | (t << 24);
00258 T3[i] = (t >>> 16) | (t << 16);
00259 T4[i] = (t >>> 24) | (t << 8);
00260
00261 T5[s] =
U1[i] = t = (ie << 24) | (i9 << 16) | (
id << 8) | ib;
00262 T6[s] = U2[i] = (t >>> 8) | (t << 24);
00263 T7[s] = U3[i] = (t >>> 16) | (t << 16);
00264 T8[s] = U4[i] = (t >>> 24) | (t << 8);
00265 }
00266
00267
00268
00269
int r = 1;
00270
rcon[0] = 1;
00271
for (i = 1; i < 30; i++) {
00272 r <<= 1;
00273
if (r >= 0x100) {
00274 r ^= ROOT;
00275 }
00276
rcon[i] = (byte)r;
00277 }
00278
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 private void blockEncrypt(ByteBuffer in, ByteBuffer out) {
00288
00289
int keyOffset = 0;
00290
int t0 = ((in.get() ) << 24 |
00291 (in.get() & 0xFF) << 16 |
00292 (in.get() & 0xFF) << 8 |
00293 (in.get() & 0xFF) ) ^
K[keyOffset++];
00294
int t1 = ((in.get() ) << 24 |
00295 (in.get() & 0xFF) << 16 |
00296 (in.get() & 0xFF) << 8 |
00297 (in.get() & 0xFF) ) ^
K[keyOffset++];
00298
int t2 = ((in.get() ) << 24 |
00299 (in.get() & 0xFF) << 16 |
00300 (in.get() & 0xFF) << 8 |
00301 (in.get() & 0xFF) ) ^
K[keyOffset++];
00302
int t3 = ((in.get() ) << 24 |
00303 (in.get() & 0xFF) << 16 |
00304 (in.get() & 0xFF) << 8 |
00305 (in.get() & 0xFF) ) ^
K[keyOffset++];
00306
00307
00308
while( keyOffset <
limit ) {
00309
int a0, a1, a2;
00310 a0 =
T1[(t0 >>> 24) ] ^
00311 T2[(t1 >>> 16) & 0xFF] ^
00312 T3[(t2 >>> 8) & 0xFF] ^
00313 T4[(t3 ) & 0xFF] ^
K[keyOffset++];
00314 a1 = T1[(t1 >>> 24) ] ^
00315 T2[(t2 >>> 16) & 0xFF] ^
00316 T3[(t3 >>> 8) & 0xFF] ^
00317 T4[(t0 ) & 0xFF] ^ K[keyOffset++];
00318 a2 = T1[(t2 >>> 24) ] ^
00319 T2[(t3 >>> 16) & 0xFF] ^
00320 T3[(t0 >>> 8) & 0xFF] ^
00321 T4[(t1 ) & 0xFF] ^ K[keyOffset++];
00322 t3 = T1[(t3 >>> 24) ] ^
00323 T2[(t0 >>> 16) & 0xFF] ^
00324 T3[(t1 >>> 8) & 0xFF] ^
00325 T4[(t2 ) & 0xFF] ^ K[keyOffset++];
00326 t0 = a0; t1 = a1; t2 = a2;
00327 }
00328
00329
00330
int tt =
K[keyOffset++];
00331 out.put((byte)(
S[(t0 >>> 24) ] ^ (tt >>> 24)));
00332 out.put((byte)(
S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16)));
00333 out.put((byte)(
S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8)));
00334 out.put((byte)(
S[(t3 ) & 0xFF] ^ (tt )));
00335 tt = K[keyOffset++];
00336 out.put((byte)(
S[(t1 >>> 24) ] ^ (tt >>> 24)));
00337 out.put((byte)(
S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16)));
00338 out.put((byte)(
S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8)));
00339 out.put((byte)(
S[(t0 ) & 0xFF] ^ (tt )));
00340 tt = K[keyOffset++];
00341 out.put((byte)(
S[(t2 >>> 24) ] ^ (tt >>> 24)));
00342 out.put((byte)(
S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16)));
00343 out.put((byte)(
S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8)));
00344 out.put((byte)(
S[(t1 ) & 0xFF] ^ (tt )));
00345 tt = K[keyOffset++];
00346 out.put((byte)(
S[(t3 >>> 24) ] ^ (tt >>> 24)));
00347 out.put((byte)(
S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16)));
00348 out.put((byte)(
S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8)));
00349 out.put((byte)(
S[(t2 ) & 0xFF] ^ (tt )));
00350 }
00351
00352
00353
00354
00355
00356 private void blockDecrypt(ByteBuffer in, ByteBuffer out) {
00357
int keyOffset = 8;
00358
int t0, t1, t2, t3, a0, a1, a2;
00359
00360 t0 = ((in.get() ) << 24 |
00361 (in.get() & 0xFF) << 16 |
00362 (in.get() & 0xFF) << 8 |
00363 (in.get() & 0xFF) ) ^
K[4];
00364 t1 = ((in.get() ) << 24 |
00365 (in.get() & 0xFF) << 16 |
00366 (in.get() & 0xFF) << 8 |
00367 (in.get() & 0xFF) ) ^
K[5];
00368 t2 = ((in.get() ) << 24 |
00369 (in.get() & 0xFF) << 16 |
00370 (in.get() & 0xFF) << 8 |
00371 (in.get() & 0xFF) ) ^
K[6];
00372 t3 = ((in.get() ) << 24 |
00373 (in.get() & 0xFF) << 16 |
00374 (in.get() & 0xFF) << 8 |
00375 (in.get() & 0xFF) ) ^
K[7];
00376
00377
if(
ROUNDS_12) {
00378 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00379 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^
K[keyOffset++];
00380 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00381 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00382 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00383 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00384 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00385 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00386 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00387 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00388 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00389 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00390 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00391 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00392 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00393 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00394
00395
if(
ROUNDS_14) {
00396 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00397 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
00398 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00399 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00400 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00401 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00402 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00403 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00404 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00405 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00406 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00407 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00408 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00409 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00410 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00411 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00412 }
00413 }
00414 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00415 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^
K[keyOffset++];
00416 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00417 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00418 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00419 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00420 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00421 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00422 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00423 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00424 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00425 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00426 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00427 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00428 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00429 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00430 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00431 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
00432 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00433 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00434 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00435 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00436 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00437 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00438 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00439 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00440 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00441 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00442 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00443 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00444 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00445 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00446 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00447 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
00448 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00449 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00450 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00451 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00452 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00453 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00454 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00455 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00456 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00457 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00458 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00459 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00460 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00461 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00462 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00463 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
00464 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00465 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00466 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00467 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00468 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00469 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00470 t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00471 T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
00472 t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^
00473 T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
00474 t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^
00475 T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00476 t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^
00477 T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
00478 a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^
00479 T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
00480 a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^
00481 T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
00482 a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^
00483 T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
00484 t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^
00485 T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
00486
00487 t1 = K[0];
00488 out.put((byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24)));
00489 out.put((byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16)));
00490 out.put((byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8)));
00491 out.put((byte)(Si[(a1 ) & 0xFF] ^ (t1 )));
00492 t1 = K[1];
00493 out.put((byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24)));
00494 out.put((byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16)));
00495 out.put((byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8)));
00496 out.put((byte)(Si[(a2 ) & 0xFF] ^ (t1 )));
00497 t1 = K[2];
00498 out.put((byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24)));
00499 out.put((byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16)));
00500 out.put((byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8)));
00501 out.put((byte)(Si[(t3 ) & 0xFF] ^ (t1 )));
00502 t1 = K[3];
00503 out.put((byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24)));
00504 out.put((byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16)));
00505 out.put((byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8)));
00506 out.put((byte)(Si[(a0 ) & 0xFF] ^ (t1 )));
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516 private static int[]
makeKey( byte[] keyBytes,
boolean decrypt )
00517
throws Exception
00518 {
00519
int ROUNDS =
getRounds(
keyBytes.length);
00520
int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;
00521
00522
int[] Ki =
new int[ROUND_KEY_COUNT];
00523
00524
int KC =
keyBytes.length / 4;
00525
int[] tk =
new int[KC];
00526
00527
int i, j;
00528
00529
00530
for (i = 0, j = 0; i < KC; )
00531 tk[i++] = (
keyBytes[j++] ) << 24 |
00532 (keyBytes[j++] & 0xFF) << 16 |
00533 (keyBytes[j++] & 0xFF) << 8 |
00534 (keyBytes[j++] & 0xFF);
00535
00536
00537
int t = 0;
00538
for ( ; t < KC; t++) Ki[t] = tk[t];
00539
00540
int tt, rconpointer = 0;
00541
while (t < ROUND_KEY_COUNT) {
00542
00543 tt = tk[KC - 1];
00544 tk[0] ^= (
S[(tt >>> 16) & 0xFF] ) << 24 ^
00545 (S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^
00546 (S[(tt ) & 0xFF] & 0xFF) << 8 ^
00547 (S[(tt >>> 24) ] & 0xFF) ^
00548 (
rcon[rconpointer++] ) << 24;
00549
if (KC != 8)
00550
for (i = 1, j = 0; i < KC; ) tk[i++] ^= tk[j++];
00551
else {
00552
for (i = 1, j = 0; i < KC / 2; ) tk[i++] ^= tk[j++];
00553 tt = tk[KC / 2 - 1];
00554 tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^
00555 (S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^
00556 (S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^
00557 (S[(tt >>> 24) ] ) << 24;
00558
for (j = KC / 2, i = j + 1; i < KC; ) tk[i++] ^= tk[j++];
00559 }
00560
00561
00562
for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++)
00563 Ki[t] = tk[j];
00564 }
00565
00566
return Ki;
00567 }
00568
00569
00570 private static void invertKey(
int[] K) {
00571
00572
for(
int i=0; i<K.length/2-4;i+=4) {
00573
int jj0 = K[i+0];
00574
int jj1 = K[i+1];
00575
int jj2 = K[i+2];
00576
int jj3 = K[i+3];
00577 K[i+0] = K[K.length-i-4+0];
00578 K[i+1] = K[K.length-i-4+1];
00579 K[i+2] = K[K.length-i-4+2];
00580 K[i+3] = K[K.length-i-4+3];
00581 K[K.length-i-4+0] = jj0;
00582 K[K.length-i-4+1] = jj1;
00583 K[K.length-i-4+2] = jj2;
00584 K[K.length-i-4+3] = jj3;
00585 }
00586
00587
for (
int r = 4; r < K.length-4; r++) {
00588
int tt = K[r];
00589 K[r] =
U1[(tt >>> 24) & 0xFF] ^
00590 U2[(tt >>> 16) & 0xFF] ^
00591 U3[(tt >>> 8) & 0xFF] ^
00592 U4[ tt & 0xFF];
00593 }
00594
00595
int j0 = K[K.length-4];
00596
int j1 = K[K.length-3];
00597
int j2 = K[K.length-2];
00598
int j3 = K[K.length-1];
00599
for(
int i=K.length-1; i>3; i-- ) K[i] = K[i-4];
00600 K[0] = j0;
00601 K[1] = j1;
00602 K[2] = j2;
00603 K[3] = j3;
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 private final static int getRounds(
int keySize ) {
00615
return (keySize >> 2) + 6;
00616 }
00617 }