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