Home | History | Annotate | Download | only in engines
      1 package org.bouncycastle.crypto.engines;
      2 
      3 import org.bouncycastle.crypto.BlockCipher;
      4 import org.bouncycastle.crypto.CipherParameters;
      5 import org.bouncycastle.crypto.DataLengthException;
      6 import org.bouncycastle.crypto.OutputLengthException;
      7 import 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  */
     16 public 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