Home | History | Annotate | Download | only in gcm
      1 package org.bouncycastle.crypto.modes.gcm;
      2 
      3 import org.bouncycastle.crypto.util.Pack;
      4 import org.bouncycastle.util.Arrays;
      5 
      6 public class Tables8kGCMMultiplier  implements GCMMultiplier
      7 {
      8     private byte[] H;
      9     private int[][][] M;
     10 
     11     public void init(byte[] H)
     12     {
     13         if (M == null)
     14         {
     15             M = new int[32][16][4];
     16         }
     17         else if (Arrays.areEqual(this.H, H))
     18         {
     19             return;
     20         }
     21 
     22         this.H = Arrays.clone(H);
     23 
     24         // M[0][0] is ZEROES;
     25         // M[1][0] is ZEROES;
     26         GCMUtil.asInts(H, M[1][8]);
     27 
     28         for (int j = 4; j >= 1; j >>= 1)
     29         {
     30             GCMUtil.multiplyP(M[1][j + j], M[1][j]);
     31         }
     32 
     33         GCMUtil.multiplyP(M[1][1], M[0][8]);
     34 
     35         for (int j = 4; j >= 1; j >>= 1)
     36         {
     37             GCMUtil.multiplyP(M[0][j + j], M[0][j]);
     38         }
     39 
     40         int i = 0;
     41         for (;;)
     42         {
     43             for (int j = 2; j < 16; j += j)
     44             {
     45                 for (int k = 1; k < j; ++k)
     46                 {
     47                     GCMUtil.xor(M[i][j], M[i][k], M[i][j + k]);
     48                 }
     49             }
     50 
     51             if (++i == 32)
     52             {
     53                 return;
     54             }
     55 
     56             if (i > 1)
     57             {
     58                 // M[i][0] is ZEROES;
     59                 for(int j = 8; j > 0; j >>= 1)
     60                 {
     61                     GCMUtil.multiplyP8(M[i - 2][j], M[i][j]);
     62                 }
     63             }
     64         }
     65     }
     66 
     67     public void multiplyH(byte[] x)
     68     {
     69 //      assert x.Length == 16;
     70 
     71         int[] z = new int[4];
     72         for (int i = 15; i >= 0; --i)
     73         {
     74 //            GCMUtil.xor(z, M[i + i][x[i] & 0x0f]);
     75             int[] m = M[i + i][x[i] & 0x0f];
     76             z[0] ^= m[0];
     77             z[1] ^= m[1];
     78             z[2] ^= m[2];
     79             z[3] ^= m[3];
     80 //            GCMUtil.xor(z, M[i + i + 1][(x[i] & 0xf0) >>> 4]);
     81             m = M[i + i + 1][(x[i] & 0xf0) >>> 4];
     82             z[0] ^= m[0];
     83             z[1] ^= m[1];
     84             z[2] ^= m[2];
     85             z[3] ^= m[3];
     86         }
     87 
     88         Pack.intToBigEndian(z, x, 0);
     89     }
     90 }