1 /* $Id: MARS.java,v 1.3 2000/02/10 21:14:50 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 14 import java.security.InvalidKeyException; 15 import java.security.Key; 16 17 18 /** 19 * MARS is an AES candidate submitted by IBM. 20 * <p> 21 * MARS was designed by Carolynn Burwick, Don Coppersmith, Edward D'Avignon, 22 * Rosario Gennaro, Shai Halevi, Charanjit Jutla, Stephen M. Matyas Jr., 23 * Luke O'Connor, Mohammad Peyravian, David Safford, and Nevenko Zunic. 24 * <p> 25 * Please note that this is the 'amended' 2nd round version. 26 * 27 * @version $Revision: 1.3 $ 28 * @author Jeroen C. van Gelderen (gelderen@cryptix.org) 29 * @author Raif S. Naffah 30 */ 31 public final class MARS extends BlockCipher 32 { 33 34 // Constants 35 //........................................................................... 36 37 static final int 38 BLOCK_SIZE = 16, // bytes in a data-block 39 ROUNDS = 32; // rounds of a MARS cipher 40 41 42 /** MARS S-box */ 43 private static final int[] S = { 44 0x09D0C479, 0x28C8FFE0, 0x84AA6C39, 0x9DAD7287, 45 0x7DFF9BE3, 0xD4268361, 0xC96DA1D4, 0x7974CC93, 46 0x85D0582E, 0x2A4B5705, 0x1CA16A62, 0xC3BD279D, 47 0x0F1F25E5, 0x5160372F, 0xC695C1FB, 0x4D7FF1E4, 48 0xAE5F6BF4, 0x0D72EE46, 0xFF23DE8A, 0xB1CF8E83, 49 0xF14902E2, 0x3E981E42, 0x8BF53EB6, 0x7F4BF8AC, 50 0x83631F83, 0x25970205, 0x76AFE784, 0x3A7931D4, 51 0x4F846450, 0x5C64C3F6, 0x210A5F18, 0xC6986A26, 52 0x28F4E826, 0x3A60A81C, 0xD340A664, 0x7EA820C4, 53 0x526687C5, 0x7EDDD12B, 0x32A11D1D, 0x9C9EF086, 54 0x80F6E831, 0xAB6F04AD, 0x56FB9B53, 0x8B2E095C, 55 0xB68556AE, 0xD2250B0D, 0x294A7721, 0xE21FB253, 56 0xAE136749, 0xE82AAE86, 0x93365104, 0x99404A66, 57 0x78A784DC, 0xB69BA84B, 0x04046793, 0x23DB5C1E, 58 0x46CAE1D6, 0x2FE28134, 0x5A223942, 0x1863CD5B, 59 0xC190C6E3, 0x07DFB846, 0x6EB88816, 0x2D0DCC4A, 60 0xA4CCAE59, 0x3798670D, 0xCBFA9493, 0x4F481D45, 61 0xEAFC8CA8, 0xDB1129D6, 0xB0449E20, 0x0F5407FB, 62 0x6167D9A8, 0xD1F45763, 0x4DAA96C3, 0x3BEC5958, 63 0xABABA014, 0xB6CCD201, 0x38D6279F, 0x02682215, 64 0x8F376CD5, 0x092C237E, 0xBFC56593, 0x32889D2C, 65 0x854B3E95, 0x05BB9B43, 0x7DCD5DCD, 0xA02E926C, 66 0xFAE527E5, 0x36A1C330, 0x3412E1AE, 0xF257F462, 67 0x3C4F1D71, 0x30A2E809, 0x68E5F551, 0x9C61BA44, 68 0x5DED0AB8, 0x75CE09C8, 0x9654F93E, 0x698C0CCA, 69 0x243CB3E4, 0x2B062B97, 0x0F3B8D9E, 0x00E050DF, 70 0xFC5D6166, 0xE35F9288, 0xC079550D, 0x0591AEE8, 71 0x8E531E74, 0x75FE3578, 0x2F6D829A, 0xF60B21AE, 72 0x95E8EB8D, 0x6699486B, 0x901D7D9B, 0xFD6D6E31, 73 0x1090ACEF, 0xE0670DD8, 0xDAB2E692, 0xCD6D4365, 74 0xE5393514, 0x3AF345F0, 0x6241FC4D, 0x460DA3A3, 75 0x7BCF3729, 0x8BF1D1E0, 0x14AAC070, 0x1587ED55, 76 0x3AFD7D3E, 0xD2F29E01, 0x29A9D1F6, 0xEFB10C53, 77 0xCF3B870F, 0xB414935C, 0x664465ED, 0x024ACAC7, 78 0x59A744C1, 0x1D2936A7, 0xDC580AA6, 0xCF574CA8, 79 0x040A7A10, 0x6CD81807, 0x8A98BE4C, 0xACCEA063, 80 0xC33E92B5, 0xD1E0E03D, 0xB322517E, 0x2092BD13, 81 0x386B2C4A, 0x52E8DD58, 0x58656DFB, 0x50820371, 82 0x41811896, 0xE337EF7E, 0xD39FB119, 0xC97F0DF6, 83 0x68FEA01B, 0xA150A6E5, 0x55258962, 0xEB6FF41B, 84 0xD7C9CD7A, 0xA619CD9E, 0xBCF09576, 0x2672C073, 85 0xF003FB3C, 0x4AB7A50B, 0x1484126A, 0x487BA9B1, 86 0xA64FC9C6, 0xF6957D49, 0x38B06A75, 0xDD805FCD, 87 0x63D094CF, 0xF51C999E, 0x1AA4D343, 0xB8495294, 88 0xCE9F8E99, 0xBFFCD770, 0xC7C275CC, 0x378453A7, 89 0x7B21BE33, 0x397F41BD, 0x4E94D131, 0x92CC1F98, 90 0x5915EA51, 0x99F861B7, 0xC9980A88, 0x1D74FD5F, 91 0xB0A495F8, 0x614DEED0, 0xB5778EEA, 0x5941792D, 92 0xFA90C1F8, 0x33F824B4, 0xC4965372, 0x3FF6D550, 93 0x4CA5FEC0, 0x8630E964, 0x5B3FBBD6, 0x7DA26A48, 94 0xB203231A, 0x04297514, 0x2D639306, 0x2EB13149, 95 0x16A45272, 0x532459A0, 0x8E5F4872, 0xF966C7D9, 96 0x07128DC0, 0x0D44DB62, 0xAFC8D52D, 0x06316131, 97 0xD838E7CE, 0x1BC41D00, 0x3A2E8C0F, 0xEA83837E, 98 0xB984737D, 0x13BA4891, 0xC4F8B949, 0xA6D6ACB3, 99 0xA215CDCE, 0x8359838B, 0x6BD1AA31, 0xF579DD52, 100 0x21B93F93, 0xF5176781, 0x187DFDDE, 0xE94AEB76, 101 0x2B38FD54, 0x431DE1DA, 0xAB394825, 0x9AD3048F, 102 0xDFEA32AA, 0x659473E3, 0x623F7863, 0xF3346C59, 103 0xAB3AB685, 0x3346A90B, 0x6B56443E, 0xC6DE01F8, 104 0x8D421FC0, 0x9B0ED10C, 0x88F1A1E9, 0x54C1F029, 105 0x7DEAD57B, 0x8D7BA426, 0x4CF5178A, 0x551A7CCA, 106 0x1A9A5F08, 0xFCD651B9, 0x25605182, 0xE11FC6C3, 107 0xB6FD9676, 0x337B3027, 0xB7C8EB14, 0x9E5FD030, 108 0x6B57E354, 0xAD913CF7, 0x7E16688D, 0x58872A69, 109 0x2C2FC7DF, 0xE389CCC6, 0x30738DF1, 0x0824A734, 110 0xE1797A8B, 0xA4A8D57B, 0x5B5D193B, 0xC8A8309B, 111 0x73F9A978, 0x73398D32, 0x0F59573E, 0xE9DF2B03, 112 0xE8A5B6C8, 0x848D0704, 0x98DF93C2, 0x720A1DC3, 113 0x684F259A, 0x943BA848, 0xA6370152, 0x863B5EA3, 114 0xD17B978B, 0x6D9B58EF, 0x0A700DD4, 0xA73D36BF, 115 0x8E6A0829, 0x8695BC14, 0xE35B3447, 0x933AC568, 116 0x8894B022, 0x2F511C27, 0xDDFBCC3C, 0x006662B6, 117 0x117C83FE, 0x4E12B414, 0xC2BCA766, 0x3A2FEC10, 118 0xF4562420, 0x55792E2A, 0x46F5D857, 0xCEDA25CE, 119 0xC3601D3B, 0x6C00AB46, 0xEFAC9C28, 0xB3C35047, 120 0x611DFEE3, 0x257C3207, 0xFDD58482, 0x3B14D84F, 121 0x23BECB64, 0xA075F3A3, 0x088F8EAD, 0x07ADF158, 122 0x7796943C, 0xFACABF3D, 0xC09730CD, 0xF7679969, 123 0xDA44E9ED, 0x2C854C12, 0x35935FA3, 0x2F057D9F, 124 0x690624F8, 0x1CB0BAFD, 0x7B0DBDC6, 0x810F23BB, 125 0xFA929A1A, 0x6D969A17, 0x6742979B, 0x74AC7D05, 126 0x010E65C4, 0x86A3D963, 0xF907B5A0, 0xD0042BD3, 127 0x158D7D03, 0x287A8255, 0xBBA8366F, 0x096EDC33, 128 0x21916A7B, 0x77B56B86, 0x951622F9, 0xA6C5E650, 129 0x8CEA17D1, 0xCD8C62BC, 0xA3D63433, 0x358A68FD, 130 0x0F9B9D3C, 0xD6AA295B, 0xFE33384A, 0xC000738E, 131 0xCD67EB2F, 0xE2EB6DC2, 0x97338B02, 0x06C9F246, 132 0x419CF1AD, 0x2B83C045, 0x3723F18A, 0xCB5B3089, 133 0x160BEAD7, 0x5D494656, 0x35F8A74B, 0x1E4E6C9E, 134 0x000399BD, 0x67466880, 0xB4174831, 0xACF423B2, 135 0xCA815AB3, 0x5A6395E7, 0x302A67C5, 0x8BDB446B, 136 0x108F8FA4, 0x10223EDA, 0x92B8B48B, 0x7F38D0EE, 137 0xAB2701D4, 0x0262D415, 0xAF224A30, 0xB3D88ABA, 138 0xF8B2C3AF, 0xDAF7EF70, 0xCC97D3B7, 0xE9614B6C, 139 0x2BAEBFF4, 0x70F687CF, 0x386C9156, 0xCE092EE5, 140 0x01E87DA6, 0x6CE91E6A, 0xBB7BCC84, 0xC7922C20, 141 0x9D3B71FD, 0x060E41C6, 0xD7590F15, 0x4E03BB47, 142 0x183C198E, 0x63EEB240, 0x2DDBF49A, 0x6D5CBA54, 143 0x923750AF, 0xF9E14236, 0x7838162B, 0x59726C72, 144 0x81B66760, 0xBB2926C1, 0x48A0CE0D, 0xA6C0496D, 145 0xAD43507B, 0x718D496A, 0x9DF057AF, 0x44B1BDE6, 146 0x054356DC, 0xDE7CED35, 0xD51A138B, 0x62088CC9, 147 0x35830311, 0xC96EFCA2, 0x686F86EC, 0x8E77CB68, 148 0x63E1D6B8, 0xC80F9778, 0x79C491FD, 0x1B4C67F2, 149 0x72698D7D, 0x5E368C31, 0xF7D95E2E, 0xA1D3493F, 150 0xDCD9433E, 0x896F1552, 0x4BC4CA7A, 0xA6D1BAF4, 151 0xA5A96DCC, 0x0BEF8B46, 0xA169FDA7, 0x74DF40B7, 152 0x4E208804, 0x9A756607, 0x038E87C8, 0x20211E44, 153 0x8B7AD4BF, 0xC6403F35, 0x1848E36D, 0x80BDB038, 154 0x1E62891C, 0x643D2107, 0xBF04D6F8, 0x21092C8C, 155 0xF644F389, 0x0778404E, 0x7B78ADB8, 0xA2C52D53, 156 0x42157ABE, 0xA2253E2E, 0x7BF3F4AE, 0x80F594F9, 157 0x953194E7, 0x77EB92ED, 0xB3816930, 0xDA8D9336, 158 0xBF447469, 0xF26D9483, 0xEE6FAED5, 0x71371235, 159 0xDE425F73, 0xB4E59F43, 0x7DBE2D4E, 0x2D37B185, 160 0x49DC9A63, 0x98C39D98, 0x1301C9A2, 0x389B1BBF, 161 0x0C18588D, 0xA421C1BA, 0x7AA3865C, 0x71E08558, 162 0x3C5CFCAA, 0x7D239CA4, 0x0297D9DD, 0xD7DC2830, 163 0x4B37802B, 0x7428AB54, 0xAEEE0347, 0x4B3FBB85, 164 0x692F2F08, 0x134E578E, 0x36D9E0BF, 0xAE8B5FCF, 165 0xEDB93ECF, 0x2B27248E, 0x170EB1EF, 0x7DC57FD6, 166 0x1E760F16, 0xB1136601, 0x864E1B9B, 0xD7EA7319, 167 0x3AB871BD, 0xCFA4D76F, 0xE31BD782, 0x0DBEB469, 168 0xABB96061, 0x5370F85D, 0xFFB07E37, 0xDA30D0FB, 169 0xEBC977B6, 0x0B98B40F, 0x3A4D0FE6, 0xDF4FC26B, 170 0x159CF22A, 0xC298D6E2, 0x2B78EF6A, 0x61A94AC0, 171 0xAB561187, 0x14EEA0F0, 0xDF0D4164, 0x19AF70EE }; 172 173 174 // Instance variables 175 //........................................................................... 176 177 /** Encrypt (false) or decrypt mode (true) */ 178 private boolean decrypt; 179 180 /** Subkeys (40). */ 181 private final int[] K = new int[40]; 182 183 184 // Constructor 185 //........................................................................... 186 MARS()187 public MARS() 188 { 189 super(BLOCK_SIZE); 190 } 191 192 193 // BlockCipher abstract method implementation 194 //........................................................................... 195 coreInit(Key key, boolean decrypt)196 protected void coreInit(Key key, boolean decrypt) 197 throws InvalidKeyException 198 { 199 if( key==null ) 200 throw new InvalidKeyException("key: key is null"); 201 202 if( !key.getFormat().equalsIgnoreCase("RAW") ) 203 throw new InvalidKeyException("key: wrong format, RAW needed"); 204 205 byte[] userkey = key.getEncoded(); 206 if(userkey == null) 207 throw new InvalidKeyException("RAW bytes missing"); 208 209 int len = userkey.length ; 210 if( len != 16 && len != 24 && len!=32 ) 211 throw new InvalidKeyException("Invalid user key length"); 212 213 generateSubKeys(userkey); 214 this.decrypt = decrypt; 215 } 216 217 coreCrypt(byte[] in, int inOffset, byte[] out, int outOffset)218 protected void coreCrypt(byte[] in, int inOffset, byte[] out, int outOffset) 219 { 220 if( decrypt ) 221 blockDecrypt(in, inOffset, out, outOffset); 222 else 223 blockEncrypt(in, inOffset, out, outOffset); 224 } 225 226 227 // Helper methods 228 //........................................................................... 229 230 /** Expand a session key into 40 MARS subkeys in int[] this.K . */ generateSubKeys(byte[] key)231 private final void generateSubKeys(byte[] key) 232 { 233 int keyLen = key.length; 234 int n = keyLen / 4; 235 236 int[] K = this.K; 237 int[] T = new int[15]; // (3) 238 int[] B = { 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, 0x73f9a978 }; // (4,5,6) 239 240 int i; 241 for(i = 0; i < keyLen; i++) 242 T[i/4] |= (key[i] & 0xFF) << (i*8); 243 244 T[i/4] = i/4; 245 246 int j, ii; 247 for(j=0; j<4; j++) 248 { 249 // Do linear transformation 250 for(i=0; i<15; i++) 251 T[i] ^= rotl(T[(i+8) % 15] ^ T[(i+13) % 15], 3) ^ (4*i+j); 252 253 // Do four rounds of stirring 254 for(ii=0; ii<4; ii++) 255 for(i=0; i<15; i++) 256 T[i] = rotl(T[i] + S[ T[(i+14) % 15] & 0x1FF], 9); 257 258 // Store next 10 key words into K[] 259 for(i=0; i<10; i++) 260 K[10*j+i] = T[(4*i) % 15]; 261 } 262 263 // Modify multiplication key-words 264 int m, p, r, w; 265 for(i=5; i<=35; i+=2) 266 { 267 j = K[i] & 0x3; 268 w = K[i] | 0x3; 269 270 m = maskFrom(w); 271 r = K[i-1] & 0x1F; 272 p = rotl(B[j], r); 273 274 K[i] = w ^ (p & m); 275 } 276 } 277 278 279 /** 280 * Generate a bit-mask M from x. 281 * 282 * Bit M{i}=1 iff x{i} belongs to a sequence of 10 consecutive 0's 283 * or 1's in x, and also 2 <= i <= 30 and x{i-1} = w{i} = w{i+1}. 284 * 285 * Code taken from the MARS implementation in C/C++ by 286 * Dr. B. R. Gladman (brian.gladman@btinternet.com). 287 * 288 * This is used during key expansion. 289 */ maskFrom(int x)290 private static int maskFrom(int x) 291 { 292 int m; 293 294 // Set m{bn} = 1 if x{bn} == x{bn+1} for 0 <= bn <= 30. 295 // That is, set a bit in m if the corresponding bit and the 296 // next higher bit in x are equal in value (set m{31} = 0). 297 m = (~x ^ (x >>> 1)) & 0x7fffffff; 298 299 // Sequences of 9 '1' bits in m now correspond to sequences 300 // of 10 '0's or 10 '1' bits in x. Shift and 'and' bits in 301 // m to find sequences of 9 or more '1' bits. As a result 302 // bits in m are set if they are at the bottom of sequences 303 // of 10 adjacent '0's or 10 adjacent '1's in x. 304 m &= (m >>> 1) & (m >>> 2); 305 m &= (m >>> 3) & (m >>> 6); 306 307 // We need the internal bits in each continuous sequence of 308 // matching bits (that is the bits less the two endpoints). 309 // We thus propagate each set bit into the 8 internal bits 310 // that it represents, starting 1 left and finsihing 8 left 311 // of its position. 312 m <<= 1; 313 m |= (m << 1); 314 m |= (m << 2); 315 m |= (m << 4); 316 317 return m & 0xfffffffc; 318 } 319 320 321 /** Rotate left an int by the specified amount. */ rotl(int arg, int amount)322 private static int rotl(int arg, int amount) 323 { 324 return (arg << amount) | (arg >>> (32-amount)); 325 } 326 327 328 /** Encrypt exactly one block of plaintext. */ blockEncrypt(byte[] in, int inOffset, byte[] out, int outOffset)329 private final void blockEncrypt(byte[] in, int inOffset, 330 byte[] out, int outOffset) 331 { 332 int D0 = (in[inOffset++] & 0xFF) | 333 (in[inOffset++] & 0xFF) << 8 | 334 (in[inOffset++] & 0xFF) << 16 | 335 (in[inOffset++] & 0xFF) << 24; 336 int D1 = (in[inOffset++] & 0xFF) | 337 (in[inOffset++] & 0xFF) << 8 | 338 (in[inOffset++] & 0xFF) << 16 | 339 (in[inOffset++] & 0xFF) << 24; 340 int D2 = (in[inOffset++] & 0xFF) | 341 (in[inOffset++] & 0xFF) << 8 | 342 (in[inOffset++] & 0xFF) << 16 | 343 (in[inOffset++] & 0xFF) << 24; 344 int D3 = (in[inOffset++] & 0xFF) | 345 (in[inOffset++] & 0xFF) << 8 | 346 (in[inOffset++] & 0xFF) << 16 | 347 (in[inOffset ] & 0xFF) << 24; 348 349 // 1. key addition // (1) 350 D0 += K[0]; 351 D1 += K[1]; 352 D2 += K[2]; 353 D3 += K[3]; 354 355 // 2. forward mixing 356 int i, t; 357 for (i = 0; i < 8; i++) // (5) 358 { 359 D1 ^= S[ D0 & 0xFF ]; // (7) 360 D1 += S[256 + ((D0 >>> 8) & 0xFF)]; // (8) 361 D2 += S[ (D0 >>> 16) & 0xFF ]; // (9) 362 D3 ^= S[256 + ((D0 >>> 24) & 0xFF)]; // (10) 363 D0 = D0 >>> 24 | D0 << 8; // (12) 364 365 switch (i) 366 { 367 case 0: 368 case 4: D0 += D3; break; // (15) 369 case 1: 370 case 5: D0 += D1; break; // (17) 371 } 372 373 t = D0; D0 = D1; D1 = D2; D2 = D3; D3 = t; // (19) 374 } // (20) 375 376 // 3. Keyed transformation 377 int[] ia; 378 for (i = 0; i < 16; i++) // (22) 379 { 380 ia = E(D0, K[2*i + 4], K[2*i + 5]); // (23) 381 D0 = D0 << 13 | D0 >>> 19; // (24) 382 D2 += ia[1]; // (25) 383 if (i < 8) 384 { 385 D1 += ia[0]; // (27) 386 D3 ^= ia[2]; // (28) 387 } 388 else 389 { 390 D3 += ia[0]; // (30) 391 D1 ^= ia[2]; // (31) 392 } 393 t = D0; D0 = D1; D1 = D2; D2 = D3; D3 = t; // (34) 394 } // (35) 395 396 // 4. Backward mixing 397 for (i = 0; i < 8; i++) // (37) 398 { 399 switch (i) 400 { 401 case 2: 402 case 6: D0 -= D3; break; // (40) 403 case 3: 404 case 7: D0 -= D1; break; // (42) 405 } 406 D1 ^= S[256 + (D0 & 0xFF)]; // (44) 407 D2 -= S[ (D0 >>> 24) & 0xFF ]; // (45) 408 D3 -= S[256 + ((D0 >>> 16) & 0xFF)]; // (46) 409 D3 ^= S[ (D0 >>> 8) & 0xFF ]; // (47) 410 D0 = D0 << 24 | D0 >>> 8; // (49) 411 t = D0; D0 = D1; D1 = D2; D2 = D3; D3 = t; // (51) 412 } // (52) 413 414 D0 -= K[36]; 415 D1 -= K[37]; 416 D2 -= K[38]; 417 D3 -= K[39]; 418 419 out[outOffset++] = (byte)(D0 ); 420 out[outOffset++] = (byte)(D0 >>> 8); 421 out[outOffset++] = (byte)(D0 >>> 16); 422 out[outOffset++] = (byte)(D0 >>> 24); 423 424 out[outOffset++] = (byte)(D1 ); 425 out[outOffset++] = (byte)(D1 >>> 8); 426 out[outOffset++] = (byte)(D1 >>> 16); 427 out[outOffset++] = (byte)(D1 >>> 24); 428 429 out[outOffset++] = (byte)(D2 ); 430 out[outOffset++] = (byte)(D2 >>> 8); 431 out[outOffset++] = (byte)(D2 >>> 16); 432 out[outOffset++] = (byte)(D2 >>> 24); 433 434 out[outOffset++] = (byte)(D3 ); 435 out[outOffset++] = (byte)(D3 >>> 8); 436 out[outOffset++] = (byte)(D3 >>> 16); 437 out[outOffset ] = (byte)(D3 >>> 24); 438 } 439 440 441 /** Decrypt exactly one block of ciphertext. */ blockDecrypt(byte[] in, int inOffset, byte[] out, int outOffset)442 private final void blockDecrypt(byte[] in, int inOffset, 443 byte[] out, int outOffset) 444 { 445 int D0 = (in[inOffset++] & 0xFF) | 446 (in[inOffset++] & 0xFF) << 8 | 447 (in[inOffset++] & 0xFF) << 16 | 448 (in[inOffset++] & 0xFF) << 24; 449 int D1 = (in[inOffset++] & 0xFF) | 450 (in[inOffset++] & 0xFF) << 8 | 451 (in[inOffset++] & 0xFF) << 16 | 452 (in[inOffset++] & 0xFF) << 24; 453 int D2 = (in[inOffset++] & 0xFF) | 454 (in[inOffset++] & 0xFF) << 8 | 455 (in[inOffset++] & 0xFF) << 16 | 456 (in[inOffset++] & 0xFF) << 24; 457 int D3 = (in[inOffset++] & 0xFF) | 458 (in[inOffset++] & 0xFF) << 8 | 459 (in[inOffset++] & 0xFF) << 16 | 460 (in[inOffset ] & 0xFF) << 24; 461 462 // 1. key addition 463 D0 += K[36]; 464 D1 += K[37]; 465 D2 += K[38]; 466 D3 += K[39]; 467 468 // 2. forward mixing // (1) 469 int i, t; 470 for (i = 7; i >= 0; i--) // (5) 471 { 472 t = D3; D3 = D2; D2 = D1; D1 = D0; D0 = t; // (7) 473 D0 = D0 >>> 24 | D0 << 8; // (9) 474 D3 ^= S[ (D0 >>> 8) & 0xFF ]; // (11) 475 D3 += S[256 + ((D0 >>> 16) & 0xFF)]; // (12) 476 D2 += S[ (D0 >>> 24) & 0xFF ]; // (13) 477 D1 ^= S[256 + (D0 & 0xFF)]; // (14) 478 switch (i) 479 { 480 case 2: 481 case 6: D0 += D3; break; // (17) 482 case 3: 483 case 7: D0 += D1; break; // (19) 484 } 485 } // (20) 486 487 // 3. Keyed transformation 488 int[] ia; 489 for (i = 15; i >= 0; i--) // (22) 490 { 491 t = D3; D3 = D2; D2 = D1; D1 = D0; D0 = t; // (24) 492 D0 = D0 >>> 13 | D0 << 19; // (25) 493 ia = E(D0, K[2*i + 4], K[2*i + 5]); // (26) 494 D2 -= ia[1]; // (27) 495 if (i < 8) 496 { 497 D1 -= ia[0]; // (29) 498 D3 ^= ia[2]; // (30) 499 } 500 else 501 { 502 D3 -= ia[0]; // (32) 503 D1 ^= ia[2]; // (33) 504 } 505 } // (35) 506 507 // 4. Backward mixing 508 for (i = 7; i >= 0; i--) // (37) 509 { 510 t = D3; D3 = D2; D2 = D1; D1 = D0; D0 = t; // (39) 511 switch (i) 512 { 513 case 0: 514 case 4: D0 -= D3; break; // (42) 515 case 1: 516 case 5: D0 -= D1; break; // (44) 517 } 518 D0 = D0 << 24 | D0 >>> 8; // (46) 519 D3 ^= S[256 + ((D0 >>> 24) & 0xFF)]; // (48) 520 D2 -= S[ (D0 >>> 16) & 0xFF ]; // (49) 521 D1 -= S[256 + ((D0 >>> 8) & 0xFF)]; // (50) 522 D1 ^= S[ D0 & 0xFF ]; // (51) 523 } // (52) 524 525 D0 -= K[0]; 526 D1 -= K[1]; 527 D2 -= K[2]; 528 D3 -= K[3]; 529 530 out[outOffset++] = (byte)(D0 ); 531 out[outOffset++] = (byte)(D0 >>> 8); 532 out[outOffset++] = (byte)(D0 >>> 16); 533 out[outOffset++] = (byte)(D0 >>> 24); 534 535 out[outOffset++] = (byte)(D1 ); 536 out[outOffset++] = (byte)(D1 >>> 8); 537 out[outOffset++] = (byte)(D1 >>> 16); 538 out[outOffset++] = (byte)(D1 >>> 24); 539 540 out[outOffset++] = (byte)(D2 ); 541 out[outOffset++] = (byte)(D2 >>> 8); 542 out[outOffset++] = (byte)(D2 >>> 16); 543 out[outOffset++] = (byte)(D2 >>> 24); 544 545 out[outOffset++] = (byte)(D3 ); 546 out[outOffset++] = (byte)(D3 >>> 8); 547 out[outOffset++] = (byte)(D3 >>> 16); 548 out[outOffset ] = (byte)(D3 >>> 24); 549 } 550 551 E(int in, int key1, int key2)552 private static int[] E(int in, int key1, int key2) 553 { 554 int M = in + key1; // (2) 555 int R = (in << 13 | in >>> 19) * key2; // (3) 556 int i = M & 0x1FF; // (4) 557 int L = S[i]; // (5) 558 R = R << 5 | R >>> 27; // (6) 559 int r = R & 0x1F; // (7) 560 M = M << r | M >>> (32-r); // (8) 561 L ^= R; // (9) 562 R = R << 5 | R >>> 27; // (10) 563 L ^= R; // (11) 564 r = R & 0x1F; // (12) 565 L = L << r | L >>> (32-r); // (13) 566 return new int[] { L, M, R }; // (14) 567 } 568 }