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 }