1 /* $Id: Twofish.java,v 1.4 2000/02/12 03:14:31 gelderen Exp $ 2 * 3 * Copyright (C) 1997-2000 The Cryptix Foundation Limited. 4 * All rights reserved. 5 * 6 * Use, modification, copying and distribution of this software is subject 7 * the terms and conditions of the Cryptix General Licence. You should have 8 * received a copy of the Cryptix General Licence along with this library; 9 * if not, you can download a copy from http://www.cryptix.org/ . 10 */ 11 package cryptix.jce.provider.cipher; 12 13 import java.security.InvalidKeyException; 14 import java.security.Key; 15 16 17 /** 18 * Twofish is an AES candidate algorithm. It is a balanced 128-bit Feistel 19 * cipher, consisting of 16 rounds. In each round, a 64-bit S-box value is 20 * computed from 64 bits of the block, and this value is xored into the other 21 * half of the block. The two half-blocks are then exchanged, and the next 22 * round begins. Before the first round, all input bits are xored with key- 23 * dependent "whitening" subkeys, and after the final round the output bits 24 * are xored with other key-dependent whitening subkeys; these subkeys are 25 * not used anywhere else in the algorithm.<p> 26 * 27 * Twofish was submitted by Bruce Schneier, Doug Whiting, John Kelsey, Chris 28 * Hall and David Wagner.<p> 29 * 30 * Reference:<ol> 31 * <li>TWOFISH2.C -- Optimized C API calls for TWOFISH AES submission, 32 * Version 1.00, April 1998, by Doug Whiting.</ol><p> 33 * 34 * @version $Revision: 1.4 $ 35 * @author Raif S. Naffah 36 * @author Jeroen C. van Gelderen (gelderen@cryptix.org) 37 */ 38 public final class Twofish extends BlockCipher 39 { 40 41 // Constants 42 //........................................................................... 43 44 private static final int 45 BLOCK_SIZE = 16, // bytes in a data-block 46 ROUNDS = 16; 47 48 private static final int 49 TOTAL_SUBKEYS = 4 + 4 + 2*ROUNDS; 50 51 private static final int 52 SK_BUMP = 0x01010101, 53 SK_ROTL = 9; 54 55 /** Fixed 8x8 permutation S-boxes */ 56 private static final byte[][] P = new byte[][] 57 { 58 { // p0 59 (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8, 60 (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76, 61 (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78, 62 (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38, 63 (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98, 64 (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C, 65 (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26, 66 (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48, 67 (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30, 68 (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23, 69 (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59, 70 (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82, 71 (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E, 72 (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C, 73 (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE, 74 (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61, 75 (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5, 76 (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B, 77 (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B, 78 (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1, 79 (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45, 80 (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66, 81 (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56, 82 (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7, 83 (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5, 84 (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA, 85 (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF, 86 (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71, 87 (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD, 88 (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8, 89 (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D, 90 (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7, 91 (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED, 92 (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2, 93 (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11, 94 (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90, 95 (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF, 96 (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB, 97 (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B, 98 (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF, 99 (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE, 100 (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B, 101 (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46, 102 (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64, 103 (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F, 104 (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A, 105 (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A, 106 (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A, 107 (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29, 108 (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02, 109 (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17, 110 (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D, 111 (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74, 112 (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72, 113 (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12, 114 (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34, 115 (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68, 116 (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8, 117 (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40, 118 (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4, 119 (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0, 120 (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00, 121 (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42, 122 (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 123 }, 124 { // p1 125 (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4, 126 (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8, 127 (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B, 128 (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B, 129 (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD, 130 (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1, 131 (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B, 132 (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F, 133 (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B, 134 (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D, 135 (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E, 136 (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5, 137 (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14, 138 (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3, 139 (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54, 140 (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51, 141 (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A, 142 (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96, 143 (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10, 144 (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C, 145 (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7, 146 (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70, 147 (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB, 148 (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8, 149 (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF, 150 (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC, 151 (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF, 152 (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2, 153 (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82, 154 (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9, 155 (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97, 156 (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17, 157 (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D, 158 (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3, 159 (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C, 160 (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E, 161 (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F, 162 (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49, 163 (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21, 164 (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9, 165 (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD, 166 (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01, 167 (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F, 168 (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48, 169 (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E, 170 (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19, 171 (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57, 172 (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64, 173 (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE, 174 (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5, 175 (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44, 176 (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69, 177 (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15, 178 (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E, 179 (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34, 180 (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC, 181 (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B, 182 (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB, 183 (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52, 184 (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9, 185 (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4, 186 (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2, 187 (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56, 188 (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91 189 } 190 }; 191 192 /** 193 * Define the fixed p0/p1 permutations used in keyed S-box lookup. 194 * By changing the following constant definitions, the S-boxes will 195 * automatically get changed in the Twofish engine. 196 */ 197 private static final int 198 P_00 = 1, 199 P_01 = 0, 200 P_02 = 0, 201 P_03 = P_01 ^ 1, 202 P_04 = 1, 203 P_10 = 0, 204 P_11 = 0, 205 P_12 = 1, 206 P_13 = P_11 ^ 1, 207 P_14 = 0, 208 P_20 = 1, 209 P_21 = 1, 210 P_22 = 0, 211 P_23 = P_21 ^ 1, 212 P_24 = 0, 213 P_30 = 0, 214 P_31 = 1, 215 P_32 = 1, 216 P_33 = P_31 ^ 1, 217 P_34 = 1; 218 219 /** Primitive polynomial for GF(256) */ 220 private static final int 221 GF256_FDBK = 0x169, 222 GF256_FDBK_2 = 0x169 / 2, 223 GF256_FDBK_4 = 0x169 / 4; 224 225 /** MDS matrix */ 226 private static final int[][] MDS = new int[4][256]; // blank final 227 228 private static final int RS_GF_FDBK = 0x14D; // field generator 229 230 231 // Static code - to intialise the MDS matrix 232 //........................................................................... 233 234 static 235 { 236 // precompute the MDS matrix 237 238 int[] m1 = new int[2]; 239 int[] mX = new int[2]; 240 int[] mY = new int[2]; 241 int i, j; 242 for (i = 0; i < 256; i++) 243 { 244 j = P[0][i] & 0xFF; // compute all the matrix elements 245 m1[0] = j; 246 mX[0] = Mx_X( j ) & 0xFF; 247 mY[0] = Mx_Y( j ) & 0xFF; 248 249 j = P[1][i] & 0xFF; 250 m1[1] = j; 251 mX[1] = Mx_X( j ) & 0xFF; 252 mY[1] = Mx_Y( j ) & 0xFF; 253 254 MDS[0][i] = m1[P_00] << 0 | // fill matrix w/ above elements 255 mX[P_00] << 8 | 256 mY[P_00] << 16 | 257 mY[P_00] << 24; 258 MDS[1][i] = mY[P_10] << 0 | 259 mY[P_10] << 8 | 260 mX[P_10] << 16 | 261 m1[P_10] << 24; 262 MDS[2][i] = mX[P_20] << 0 | 263 mY[P_20] << 8 | 264 m1[P_20] << 16 | 265 mY[P_20] << 24; 266 MDS[3][i] = mX[P_30] << 0 | 267 m1[P_30] << 8 | 268 mY[P_30] << 16 | 269 mX[P_30] << 24; 270 } 271 } 272 LFSR1( int x )273 private static final int LFSR1( int x ) 274 { 275 return (x >> 1) ^ 276 ((x & 0x01) != 0 ? GF256_FDBK_2 : 0); 277 } 278 LFSR2( int x )279 private static final int LFSR2( int x ) 280 { 281 return (x >> 2) ^ 282 ((x & 0x02) != 0 ? GF256_FDBK_2 : 0) ^ 283 ((x & 0x01) != 0 ? GF256_FDBK_4 : 0); 284 } 285 Mx_1( int x )286 private static final int Mx_1( int x ) { return x; } Mx_X( int x )287 private static final int Mx_X( int x ) { return x ^ LFSR2(x); } Mx_Y( int x )288 private static final int Mx_Y( int x ) { return x ^ LFSR1(x) ^ LFSR2(x); } 289 290 291 // Instance variables 292 //........................................................................... 293 294 /** Encrypt (false) or decrypt mode (true) */ 295 private boolean decrypt; 296 297 298 /** Key dependent S-box */ 299 private final int[] sBox = new int[4 * 256]; 300 301 302 /** Subkeys */ 303 private final int[] subKeys = new int[TOTAL_SUBKEYS]; 304 305 306 // Constructor 307 //........................................................................... 308 Twofish()309 public Twofish() 310 { 311 super(BLOCK_SIZE); 312 } 313 314 315 // BlockCipher abstract method implementation 316 //........................................................................... 317 coreInit(Key key, boolean decrypt)318 protected void coreInit(Key key, boolean decrypt) 319 throws InvalidKeyException 320 { 321 if( key==null ) 322 throw new InvalidKeyException("key: key is null"); 323 324 if( !key.getFormat().equalsIgnoreCase("RAW") ) 325 throw new InvalidKeyException("key: wrong format, RAW needed"); 326 327 byte[] userkey = key.getEncoded(); 328 if(userkey == null) 329 throw new InvalidKeyException("RAW bytes missing"); 330 331 int len = userkey.length ; 332 if( len != 16 && len != 24 && len!=32 ) 333 throw new InvalidKeyException("Invalid user key length"); 334 335 this.decrypt = decrypt; 336 makeSubKeys(userkey); 337 } 338 339 coreCrypt(byte[] in, int inOffset, byte[] out, int outOffset)340 protected void coreCrypt(byte[] in, int inOffset, byte[] out, int outOffset) 341 { 342 blockCrypt(in, inOffset, out, outOffset); 343 } 344 345 346 // Private methods 347 //........................................................................... 348 349 /** 350 * Expand a user-supplied key material into a session key. 351 * 352 * @param key The 64/128/192/256-bit user-key to use. 353 * @return This cipher's round keys. 354 * @exception InvalidKeyException If the key is invalid. 355 */ makeSubKeys(byte[] k)356 private final void makeSubKeys(byte[] k) 357 throws InvalidKeyException 358 { 359 int length = k.length; 360 int k64Cnt = length / 8; 361 int[] k32e = new int[4]; // even 32-bit entities 362 int[] k32o = new int[4]; // odd 32-bit entities 363 int[] sBoxKey = new int[4]; 364 365 // split user key material into even and odd 32-bit entities and 366 // compute S-box keys using (12, 8) Reed-Solomon code over GF(256) 367 int i, j, offset = 0; 368 for (i = 0, j = k64Cnt-1; i < 4 && offset < length; i++, j--) 369 { 370 k32e[i] = (k[offset++] & 0xFF) | 371 (k[offset++] & 0xFF) << 8 | 372 (k[offset++] & 0xFF) << 16 | 373 (k[offset++] & 0xFF) << 24; 374 k32o[i] = (k[offset++] & 0xFF) | 375 (k[offset++] & 0xFF) << 8 | 376 (k[offset++] & 0xFF) << 16 | 377 (k[offset++] & 0xFF) << 24; 378 sBoxKey[j] = RS_MDS_Encode( k32e[i], k32o[i] ); // reverse order 379 } 380 381 // compute the round decryption subkeys for PHT. these same subkeys 382 // will be used in encryption but will be applied in reverse order. 383 int A, B, q=0; 384 i=0; 385 while(i < TOTAL_SUBKEYS) 386 { 387 A = F32( k64Cnt, q, k32e ); // A uses even key entities 388 q += SK_BUMP; 389 390 B = F32( k64Cnt, q, k32o ); // B uses odd key entities 391 q += SK_BUMP; 392 393 B = B << 8 | B >>> 24; 394 395 A += B; 396 subKeys[i++] = A; // combine with a PHT 397 398 A += B; 399 subKeys[i++] = A << SK_ROTL | A >>> (32-SK_ROTL); 400 } 401 402 // fully expand the table for speed 403 int k0 = sBoxKey[0]; 404 int k1 = sBoxKey[1]; 405 int k2 = sBoxKey[2]; 406 int k3 = sBoxKey[3]; 407 int b0, b1, b2, b3; 408 for (i = 0; i < 256; i++) 409 { 410 b0 = b1 = b2 = b3 = i; 411 switch (k64Cnt & 3) 412 { 413 case 1: 414 sBox[ 2*i ] = MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)]; 415 sBox[ 2*i+1] = MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)]; 416 sBox[0x200+2*i ] = MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)]; 417 sBox[0x200+2*i+1] = MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)]; 418 break; 419 case 0: // same as 4 420 b0 = (P[P_04][b0] & 0xFF) ^ b0(k3); 421 b1 = (P[P_14][b1] & 0xFF) ^ b1(k3); 422 b2 = (P[P_24][b2] & 0xFF) ^ b2(k3); 423 b3 = (P[P_34][b3] & 0xFF) ^ b3(k3); 424 case 3: 425 b0 = (P[P_03][b0] & 0xFF) ^ b0(k2); 426 b1 = (P[P_13][b1] & 0xFF) ^ b1(k2); 427 b2 = (P[P_23][b2] & 0xFF) ^ b2(k2); 428 b3 = (P[P_33][b3] & 0xFF) ^ b3(k2); 429 case 2: // 128-bit keys 430 sBox[ 2*i ] = MDS[0][ 431 (P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF) ^ b0(k0)]; 432 433 sBox[ 2*i+1] = MDS[1][ 434 (P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF) ^ b1(k0)]; 435 436 sBox[0x200+2*i ] = MDS[2][ 437 (P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF) ^ b2(k0)]; 438 439 sBox[0x200+2*i+1] = MDS[3][ 440 (P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF) ^ b3(k0)]; 441 } 442 } 443 444 // swap input and output whitening keys when decrypting 445 if(decrypt) 446 for(i=0; i<4; i++) 447 { 448 int t = subKeys[i]; 449 subKeys[i] = subKeys[i+4]; 450 subKeys[i+4] = t; 451 } 452 } 453 454 455 /** 456 * Encrypt exactly one block of plaintext. Blocks may overlap. 457 * 458 * @param in The plaintext. 459 * @param inOffset Index of in from which to start considering data. 460 * @param sessionKey The session key to use for encryption. 461 * @return The ciphertext generated from a plaintext using the session key. 462 */ blockCrypt(byte[] in, int inOffset, byte[] out, int outOffset)463 private final void blockCrypt(byte[] in, int inOffset, 464 byte[] out, int outOffset) 465 { 466 int[] sBox = this.sBox; 467 int[] sKey = this.subKeys; 468 469 int x0 = (in[inOffset++] & 0xFF) | 470 (in[inOffset++] & 0xFF) << 8 | 471 (in[inOffset++] & 0xFF) << 16 | 472 (in[inOffset++] & 0xFF) << 24; 473 int x1 = (in[inOffset++] & 0xFF) | 474 (in[inOffset++] & 0xFF) << 8 | 475 (in[inOffset++] & 0xFF) << 16 | 476 (in[inOffset++] & 0xFF) << 24; 477 int x2 = (in[inOffset++] & 0xFF) | 478 (in[inOffset++] & 0xFF) << 8 | 479 (in[inOffset++] & 0xFF) << 16 | 480 (in[inOffset++] & 0xFF) << 24; 481 int x3 = (in[inOffset++] & 0xFF) | 482 (in[inOffset++] & 0xFF) << 8 | 483 (in[inOffset++] & 0xFF) << 16 | 484 (in[inOffset ] & 0xFF) << 24; 485 486 x0 ^= sKey[0]; 487 x1 ^= sKey[1]; 488 x2 ^= sKey[2]; 489 x3 ^= sKey[3]; 490 491 int k, t0, t1; 492 if(decrypt) 493 { 494 k = 39; 495 for (int R = 0; R < ROUNDS; R += 2) 496 { 497 t0 = Fe32( sBox, x0, 0 ); 498 t1 = Fe32( sBox, x1, 3 ); 499 x3 ^= t0 + 2*t1 + sKey[k--]; 500 x3 = x3 >>> 1 | x3 << 31; 501 x2 = x2 << 1 | x2 >>> 31; 502 x2 ^= t0 + t1 + sKey[k--]; 503 504 t0 = Fe32( sBox, x2, 0 ); 505 t1 = Fe32( sBox, x3, 3 ); 506 x1 ^= t0 + 2*t1 + sKey[k--]; 507 x1 = x1 >>> 1 | x1 << 31; 508 x0 = x0 << 1 | x0 >>> 31; 509 x0 ^= t0 + t1 + sKey[k--]; 510 } 511 } 512 else 513 { 514 k = 8; 515 for (int R = 0; R < ROUNDS; R += 2) 516 { 517 t0 = Fe32( sBox, x0, 0 ); 518 t1 = Fe32( sBox, x1, 3 ); 519 x2 ^= t0 + t1 + sKey[k++]; 520 x2 = x2 >>> 1 | x2 << 31; 521 x3 = x3 << 1 | x3 >>> 31; 522 x3 ^= t0 + 2*t1 + sKey[k++]; 523 524 t0 = Fe32( sBox, x2, 0 ); 525 t1 = Fe32( sBox, x3, 3 ); 526 x0 ^= t0 + t1 + sKey[k++]; 527 x0 = x0 >>> 1 | x0 << 31; 528 x1 = x1 << 1 | x1 >>> 31; 529 x1 ^= t0 + 2*t1 + sKey[k++]; 530 } 531 } 532 533 x2 ^= sKey[4]; 534 x3 ^= sKey[5]; 535 x0 ^= sKey[6]; 536 x1 ^= sKey[7]; 537 538 out[outOffset++] = (byte)(x2 ); 539 out[outOffset++] = (byte)(x2 >>> 8); 540 out[outOffset++] = (byte)(x2 >>> 16); 541 out[outOffset++] = (byte)(x2 >>> 24); 542 543 out[outOffset++] = (byte)(x3 ); 544 out[outOffset++] = (byte)(x3 >>> 8); 545 out[outOffset++] = (byte)(x3 >>> 16); 546 out[outOffset++] = (byte)(x3 >>> 24); 547 548 out[outOffset++] = (byte)(x0 ); 549 out[outOffset++] = (byte)(x0 >>> 8); 550 out[outOffset++] = (byte)(x0 >>> 16); 551 out[outOffset++] = (byte)(x0 >>> 24); 552 553 out[outOffset++] = (byte)(x1 ); 554 out[outOffset++] = (byte)(x1 >>> 8); 555 out[outOffset++] = (byte)(x1 >>> 16); 556 out[outOffset ] = (byte)(x1 >>> 24); 557 } 558 559 560 // own methods 561 //........................................................................... 562 b0( int x )563 private static final int b0( int x ) { return x & 0xFF; } b1( int x )564 private static final int b1( int x ) { return (x >>> 8) & 0xFF; } b2( int x )565 private static final int b2( int x ) { return (x >>> 16) & 0xFF; } b3( int x )566 private static final int b3( int x ) { return (x >>> 24) & 0xFF; } 567 568 /** 569 * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box 570 * 32-bit entity from two key material 32-bit entities. 571 * 572 * @param k0 1st 32-bit entity. 573 * @param k1 2nd 32-bit entity. 574 * @return Remainder polynomial generated using RS code 575 */ RS_MDS_Encode( int k0, int k1)576 private static final int RS_MDS_Encode( int k0, int k1) 577 { 578 int r = k1; 579 for (int i = 0; i < 4; i++) // shift 1 byte at a time 580 r = RS_rem( r ); 581 582 r ^= k0; 583 for (int i = 0; i < 4; i++) 584 r = RS_rem( r ); 585 586 return r; 587 } 588 589 /* 590 * Reed-Solomon code parameters: (12, 8) reversible code:<p> 591 * <pre> 592 * g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1 593 * </pre> 594 * where a = primitive root of field generator 0x14D 595 */ RS_rem( int x )596 private static final int RS_rem( int x ) 597 { 598 int b = (x >>> 24) & 0xFF; 599 int g2 = ((b << 1) ^ ( (b & 0x80)!=0 ? RS_GF_FDBK : 0 )) & 0xFF; 600 int g3 = (b >>> 1) ^ ( (b & 0x01)!=0 ? (RS_GF_FDBK >>> 1) : 0 ) ^ g2; 601 int result = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b; 602 return result; 603 } 604 F32( int k64Cnt, int x, int[] k32 )605 private static final int F32( int k64Cnt, int x, int[] k32 ) 606 { 607 int b0 = b0(x); 608 int b1 = b1(x); 609 int b2 = b2(x); 610 int b3 = b3(x); 611 int k0 = k32[0]; 612 int k1 = k32[1]; 613 int k2 = k32[2]; 614 int k3 = k32[3]; 615 616 int result = 0; 617 switch (k64Cnt & 3) 618 { 619 case 1: 620 result = 621 MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)] ^ 622 MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)] ^ 623 MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)] ^ 624 MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)]; 625 break; 626 case 0: // same as 4 627 b0 = (P[P_04][b0] & 0xFF) ^ b0(k3); 628 b1 = (P[P_14][b1] & 0xFF) ^ b1(k3); 629 b2 = (P[P_24][b2] & 0xFF) ^ b2(k3); 630 b3 = (P[P_34][b3] & 0xFF) ^ b3(k3); 631 case 3: 632 b0 = (P[P_03][b0] & 0xFF) ^ b0(k2); 633 b1 = (P[P_13][b1] & 0xFF) ^ b1(k2); 634 b2 = (P[P_23][b2] & 0xFF) ^ b2(k2); 635 b3 = (P[P_33][b3] & 0xFF) ^ b3(k2); 636 case 2: // 128-bit keys (optimize for this case) 637 result = 638 MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF) ^ b0(k0)] ^ 639 MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF) ^ b1(k0)] ^ 640 MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF) ^ b2(k0)] ^ 641 MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF) ^ b3(k0)]; 642 break; 643 } 644 return result; 645 } 646 647 Fe32( int[] sBox, int x, int R )648 private static final int Fe32( int[] sBox, int x, int R ) 649 { 650 return sBox[ 2*_b(x, R ) ] ^ 651 sBox[ 2*_b(x, R+1) + 1] ^ 652 sBox[0x200 + 2*_b(x, R+2) ] ^ 653 sBox[0x200 + 2*_b(x, R+3) + 1]; 654 } 655 _b( int x, int N )656 private static final int _b( int x, int N ) 657 { 658 int result = 0; 659 switch (N%4) 660 { 661 case 0: result = b0(x); break; 662 case 1: result = b1(x); break; 663 case 2: result = b2(x); break; 664 case 3: result = b3(x); break; 665 } 666 return result; 667 } 668 }