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 }