TwofishEngine.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
1package org.bouncycastle.crypto.engines;
2
3import org.bouncycastle.crypto.BlockCipher;
4import org.bouncycastle.crypto.CipherParameters;
5import org.bouncycastle.crypto.DataLengthException;
6import org.bouncycastle.crypto.OutputLengthException;
7import org.bouncycastle.crypto.params.KeyParameter;
8
9/**
10 * A class that provides Twofish encryption operations.
11 *
12 * This Java implementation is based on the Java reference
13 * implementation provided by Bruce Schneier and developed
14 * by Raif S. Naffah.
15 */
16public final class TwofishEngine
17    implements BlockCipher
18{
19    private static final byte[][] P =  {
20    {  // p0
21        (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
22        (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
23        (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
24        (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38,
25        (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98,
26        (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C,
27        (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26,
28        (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48,
29        (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30,
30        (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23,
31        (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59,
32        (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82,
33        (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E,
34        (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C,
35        (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE,
36        (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61,
37        (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5,
38        (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B,
39        (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B,
40        (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1,
41        (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45,
42        (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66,
43        (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56,
44        (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7,
45        (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5,
46        (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA,
47        (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF,
48        (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71,
49        (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD,
50        (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8,
51        (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D,
52        (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7,
53        (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED,
54        (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2,
55        (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11,
56        (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90,
57        (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF,
58        (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB,
59        (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B,
60        (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF,
61        (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE,
62        (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B,
63        (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46,
64        (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64,
65        (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F,
66        (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A,
67        (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A,
68        (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A,
69        (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29,
70        (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02,
71        (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17,
72        (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D,
73        (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74,
74        (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72,
75        (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12,
76        (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34,
77        (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68,
78        (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8,
79        (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40,
80        (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4,
81        (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
82        (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
83        (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
84        (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 },
85    {  // p1
86        (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
87        (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
88        (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
89        (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B,
90        (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD,
91        (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1,
92        (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B,
93        (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F,
94        (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B,
95        (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D,
96        (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E,
97        (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5,
98        (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14,
99        (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3,
100        (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54,
101        (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51,
102        (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A,
103        (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96,
104        (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10,
105        (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C,
106        (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7,
107        (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70,
108        (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB,
109        (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8,
110        (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF,
111        (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC,
112        (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF,
113        (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2,
114        (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82,
115        (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9,
116        (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97,
117        (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17,
118        (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D,
119        (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3,
120        (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C,
121        (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E,
122        (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F,
123        (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49,
124        (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21,
125        (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9,
126        (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD,
127        (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01,
128        (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F,
129        (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48,
130        (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E,
131        (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19,
132        (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57,
133        (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64,
134        (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE,
135        (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5,
136        (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44,
137        (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69,
138        (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15,
139        (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E,
140        (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34,
141        (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC,
142        (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B,
143        (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB,
144        (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52,
145        (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9,
146        (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
147        (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
148        (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
149        (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91  }
150    };
151
152    /**
153    * Define the fixed p0/p1 permutations used in keyed S-box lookup.
154    * By changing the following constant definitions, the S-boxes will
155    * automatically get changed in the Twofish engine.
156    */
157    private static final int P_00 = 1;
158    private static final int P_01 = 0;
159    private static final int P_02 = 0;
160    private static final int P_03 = P_01 ^ 1;
161    private static final int P_04 = 1;
162
163    private static final int P_10 = 0;
164    private static final int P_11 = 0;
165    private static final int P_12 = 1;
166    private static final int P_13 = P_11 ^ 1;
167    private static final int P_14 = 0;
168
169    private static final int P_20 = 1;
170    private static final int P_21 = 1;
171    private static final int P_22 = 0;
172    private static final int P_23 = P_21 ^ 1;
173    private static final int P_24 = 0;
174
175    private static final int P_30 = 0;
176    private static final int P_31 = 1;
177    private static final int P_32 = 1;
178    private static final int P_33 = P_31 ^ 1;
179    private static final int P_34 = 1;
180
181    /* Primitive polynomial for GF(256) */
182    private static final int GF256_FDBK =   0x169;
183    private static final int GF256_FDBK_2 = GF256_FDBK / 2;
184    private static final int GF256_FDBK_4 = GF256_FDBK / 4;
185
186    private static final int RS_GF_FDBK = 0x14D; // field generator
187
188    //====================================
189    // Useful constants
190    //====================================
191
192    private static final int    ROUNDS = 16;
193    private static final int    MAX_ROUNDS = 16;  // bytes = 128 bits
194    private static final int    BLOCK_SIZE = 16;  // bytes = 128 bits
195    private static final int    MAX_KEY_BITS = 256;
196
197    private static final int    INPUT_WHITEN=0;
198    private static final int    OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4
199    private static final int    ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8
200
201    private static final int    TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40
202
203    private static final int    SK_STEP = 0x02020202;
204    private static final int    SK_BUMP = 0x01010101;
205    private static final int    SK_ROTL = 9;
206
207    private boolean encrypting = false;
208
209    private int[] gMDS0 = new int[MAX_KEY_BITS];
210    private int[] gMDS1 = new int[MAX_KEY_BITS];
211    private int[] gMDS2 = new int[MAX_KEY_BITS];
212    private int[] gMDS3 = new int[MAX_KEY_BITS];
213
214    /**
215     * gSubKeys[] and gSBox[] are eventually used in the
216     * encryption and decryption methods.
217     */
218    private int[] gSubKeys;
219    private int[] gSBox;
220
221    private int k64Cnt = 0;
222
223    private byte[] workingKey = null;
224
225    public TwofishEngine()
226    {
227        // calculate the MDS matrix
228        int[] m1 = new int[2];
229        int[] mX = new int[2];
230        int[] mY = new int[2];
231        int j;
232
233        for (int i=0; i< MAX_KEY_BITS ; i++)
234        {
235            j = P[0][i] & 0xff;
236            m1[0] = j;
237            mX[0] = Mx_X(j) & 0xff;
238            mY[0] = Mx_Y(j) & 0xff;
239
240            j = P[1][i] & 0xff;
241            m1[1] = j;
242            mX[1] = Mx_X(j) & 0xff;
243            mY[1] = Mx_Y(j) & 0xff;
244
245            gMDS0[i] = m1[P_00]       | mX[P_00] <<  8 |
246                         mY[P_00] << 16 | mY[P_00] << 24;
247
248            gMDS1[i] = mY[P_10]       | mY[P_10] <<  8 |
249                         mX[P_10] << 16 | m1[P_10] << 24;
250
251            gMDS2[i] = mX[P_20]       | mY[P_20] <<  8 |
252                         m1[P_20] << 16 | mY[P_20] << 24;
253
254            gMDS3[i] = mX[P_30]       | m1[P_30] <<  8 |
255                         mY[P_30] << 16 | mX[P_30] << 24;
256        }
257    }
258
259    /**
260     * initialise a Twofish cipher.
261     *
262     * @param encrypting whether or not we are for encryption.
263     * @param params the parameters required to set up the cipher.
264     * @exception IllegalArgumentException if the params argument is
265     * inappropriate.
266     */
267    public void init(
268        boolean             encrypting,
269        CipherParameters    params)
270    {
271        if (params instanceof KeyParameter)
272        {
273            this.encrypting = encrypting;
274            this.workingKey = ((KeyParameter)params).getKey();
275            this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
276            setKey(this.workingKey);
277
278            return;
279        }
280
281        throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName());
282    }
283
284    public String getAlgorithmName()
285    {
286        return "Twofish";
287    }
288
289    public int processBlock(
290        byte[] in,
291        int inOff,
292        byte[] out,
293        int outOff)
294    {
295        if (workingKey == null)
296        {
297            throw new IllegalStateException("Twofish not initialised");
298        }
299
300        if ((inOff + BLOCK_SIZE) > in.length)
301        {
302            throw new DataLengthException("input buffer too short");
303        }
304
305        if ((outOff + BLOCK_SIZE) > out.length)
306        {
307            throw new OutputLengthException("output buffer too short");
308        }
309
310        if (encrypting)
311        {
312            encryptBlock(in, inOff, out, outOff);
313        }
314        else
315        {
316            decryptBlock(in, inOff, out, outOff);
317        }
318
319        return BLOCK_SIZE;
320    }
321
322    public void reset()
323    {
324        if (this.workingKey != null)
325        {
326            setKey(this.workingKey);
327        }
328    }
329
330    public int getBlockSize()
331    {
332        return BLOCK_SIZE;
333    }
334
335    //==================================
336    // Private Implementation
337    //==================================
338
339    private void setKey(byte[] key)
340    {
341        int[] k32e = new int[MAX_KEY_BITS/64]; // 4
342        int[] k32o = new int[MAX_KEY_BITS/64]; // 4
343
344        int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
345        gSubKeys = new int[TOTAL_SUBKEYS];
346
347        if (k64Cnt < 1)
348        {
349            throw new IllegalArgumentException("Key size less than 64 bits");
350        }
351
352        if (k64Cnt > 4)
353        {
354            throw new IllegalArgumentException("Key size larger than 256 bits");
355        }
356
357        /*
358         * k64Cnt is the number of 8 byte blocks (64 chunks)
359         * that are in the input key.  The input key is a
360         * maximum of 32 bytes (256 bits), so the range
361         * for k64Cnt is 1..4
362         */
363        for (int i=0; i<k64Cnt ; i++)
364        {
365            int p = i* 8;
366
367            k32e[i] = BytesTo32Bits(key, p);
368            k32o[i] = BytesTo32Bits(key, p+4);
369
370            sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
371        }
372
373        int q,A,B;
374        for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++)
375        {
376            q = i*SK_STEP;
377            A = F32(q,         k32e);
378            B = F32(q+SK_BUMP, k32o);
379            B = B << 8 | B >>> 24;
380            A += B;
381            gSubKeys[i*2] = A;
382            A += B;
383            gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL);
384        }
385
386        /*
387         * fully expand the table for speed
388         */
389        int k0 = sBoxKeys[0];
390        int k1 = sBoxKeys[1];
391        int k2 = sBoxKeys[2];
392        int k3 = sBoxKeys[3];
393        int b0, b1, b2, b3;
394        gSBox = new int[4*MAX_KEY_BITS];
395        for (int i=0; i<MAX_KEY_BITS; i++)
396        {
397            b0 = b1 = b2 = b3 = i;
398            switch (k64Cnt & 3)
399            {
400                case 1:
401                    gSBox[i*2]       = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)];
402                    gSBox[i*2+1]     = gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)];
403                    gSBox[i*2+0x200] = gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)];
404                    gSBox[i*2+0x201] = gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
405                break;
406                case 0: // 256 bits of key
407                    b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
408                    b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
409                    b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
410                    b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
411                    // fall through, having pre-processed b[0]..b[3] with k32[3]
412                case 3: // 192 bits of key
413                    b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
414                    b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
415                    b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
416                    b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
417                    // fall through, having pre-processed b[0]..b[3] with k32[2]
418                case 2: // 128 bits of key
419                    gSBox[i*2]   = gMDS0[(P[P_01]
420                        [(P[P_02][b0] & 0xff) ^ b0(k1)] & 0xff) ^ b0(k0)];
421                    gSBox[i*2+1] = gMDS1[(P[P_11]
422                        [(P[P_12][b1] & 0xff) ^ b1(k1)] & 0xff) ^ b1(k0)];
423                    gSBox[i*2+0x200] = gMDS2[(P[P_21]
424                        [(P[P_22][b2] & 0xff) ^ b2(k1)] & 0xff) ^ b2(k0)];
425                    gSBox[i*2+0x201] = gMDS3[(P[P_31]
426                        [(P[P_32][b3] & 0xff) ^ b3(k1)] & 0xff) ^ b3(k0)];
427                break;
428            }
429        }
430
431        /*
432         * the function exits having setup the gSBox with the
433         * input key material.
434         */
435    }
436
437    /**
438     * Encrypt the given input starting at the given offset and place
439     * the result in the provided buffer starting at the given offset.
440     * The input will be an exact multiple of our blocksize.
441     *
442     * encryptBlock uses the pre-calculated gSBox[] and subKey[]
443     * arrays.
444     */
445    private void encryptBlock(
446        byte[] src,
447        int srcIndex,
448        byte[] dst,
449        int dstIndex)
450    {
451        int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
452        int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
453        int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
454        int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
455
456        int k = ROUND_SUBKEYS;
457        int t0, t1;
458        for (int r = 0; r < ROUNDS; r +=2)
459        {
460            t0 = Fe32_0(x0);
461            t1 = Fe32_3(x1);
462            x2 ^= t0 + t1 + gSubKeys[k++];
463            x2 = x2 >>>1 | x2 << 31;
464            x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
465
466            t0 = Fe32_0(x2);
467            t1 = Fe32_3(x3);
468            x0 ^= t0 + t1 + gSubKeys[k++];
469            x0 = x0 >>>1 | x0 << 31;
470            x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
471        }
472
473        Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
474        Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
475        Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
476        Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
477    }
478
479    /**
480     * Decrypt the given input starting at the given offset and place
481     * the result in the provided buffer starting at the given offset.
482     * The input will be an exact multiple of our blocksize.
483     */
484    private void decryptBlock(
485        byte[] src,
486        int srcIndex,
487        byte[] dst,
488        int dstIndex)
489    {
490        int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
491        int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
492        int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
493        int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
494
495        int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
496        int t0, t1;
497        for (int r = 0; r< ROUNDS ; r +=2)
498        {
499            t0 = Fe32_0(x2);
500            t1 = Fe32_3(x3);
501            x1 ^= t0 + 2*t1 + gSubKeys[k--];
502            x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
503            x1 = x1 >>>1 | x1 << 31;
504
505            t0 = Fe32_0(x0);
506            t1 = Fe32_3(x1);
507            x3 ^= t0 + 2*t1 + gSubKeys[k--];
508            x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
509            x3 = x3 >>>1 | x3 << 31;
510        }
511
512        Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
513        Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
514        Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
515        Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
516    }
517
518    /*
519     * TODO:  This can be optimised and made cleaner by combining
520     * the functionality in this function and applying it appropriately
521     * to the creation of the subkeys during key setup.
522     */
523    private int F32(int x, int[] k32)
524    {
525        int b0 = b0(x);
526        int b1 = b1(x);
527        int b2 = b2(x);
528        int b3 = b3(x);
529        int k0 = k32[0];
530        int k1 = k32[1];
531        int k2 = k32[2];
532        int k3 = k32[3];
533
534        int result = 0;
535        switch (k64Cnt & 3)
536        {
537            case 1:
538                result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^
539                         gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^
540                         gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^
541                         gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
542                break;
543            case 0: /* 256 bits of key */
544                b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
545                b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
546                b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
547                b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
548            case 3:
549                b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
550                b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
551                b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
552                b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
553            case 2:
554                result =
555                gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^
556                gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^
557                gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^
558                gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)];
559            break;
560        }
561        return result;
562    }
563
564    /**
565     * Use (12, 8) Reed-Solomon code over GF(256) to produce
566     * a key S-box 32-bit entity from 2 key material 32-bit
567     * entities.
568     *
569     * @param    k0 first 32-bit entity
570     * @param    k1 second 32-bit entity
571     * @return     Remainder polynomial generated using RS code
572     */
573    private int RS_MDS_Encode(int k0, int k1)
574    {
575        int r = k1;
576        for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time
577        {
578            r = RS_rem(r);
579        }
580        r ^= k0;
581        for (int i=0 ; i < 4 ; i++)
582        {
583            r = RS_rem(r);
584        }
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 + ax^2 + (a+1/a)x + 1
593     * </pre>
594     * where a = primitive root of field generator 0x14D
595     */
596    private int RS_rem(int x)
597    {
598        int b = (x >>> 24) & 0xff;
599        int g2 = ((b << 1) ^
600                 ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff;
601        int g3 = ((b >>> 1) ^
602                 ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ;
603        return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b);
604    }
605
606    private int LFSR1(int x)
607    {
608        return (x >> 1) ^
609                (((x & 0x01) != 0) ? GF256_FDBK_2 : 0);
610    }
611
612    private int LFSR2(int x)
613    {
614        return (x >> 2) ^
615                (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^
616                (((x & 0x01) != 0) ? GF256_FDBK_4 : 0);
617    }
618
619    private int Mx_X(int x)
620    {
621        return x ^ LFSR2(x);
622    } // 5B
623
624    private int Mx_Y(int x)
625    {
626        return x ^ LFSR1(x) ^ LFSR2(x);
627    } // EF
628
629    private int b0(int x)
630    {
631        return x & 0xff;
632    }
633
634    private int b1(int x)
635    {
636        return (x >>> 8) & 0xff;
637    }
638
639    private int b2(int x)
640    {
641        return (x >>> 16) & 0xff;
642    }
643
644    private int b3(int x)
645    {
646        return (x >>> 24) & 0xff;
647    }
648
649    private int Fe32_0(int x)
650    {
651        return gSBox[ 0x000 + 2*(x & 0xff) ] ^
652               gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^
653               gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^
654               gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ];
655    }
656
657    private int Fe32_3(int x)
658    {
659        return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^
660               gSBox[ 0x001 + 2*(x & 0xff) ] ^
661               gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
662               gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
663    }
664
665    private int BytesTo32Bits(byte[] b, int p)
666    {
667        return ((b[p] & 0xff)) |
668             ((b[p+1] & 0xff) << 8) |
669             ((b[p+2] & 0xff) << 16) |
670             ((b[p+3] & 0xff) << 24);
671    }
672
673    private void Bits32ToBytes(int in,  byte[] b, int offset)
674    {
675        b[offset] = (byte)in;
676        b[offset + 1] = (byte)(in >> 8);
677        b[offset + 2] = (byte)(in >> 16);
678        b[offset + 3] = (byte)(in >> 24);
679    }
680}
681