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