1package org.bouncycastle.crypto.modes.gcm;
2
3import java.util.Vector;
4
5import org.bouncycastle.util.Arrays;
6
7public class Tables1kGCMExponentiator implements GCMExponentiator
8{
9    // A lookup table of the power-of-two powers of 'x'
10    // - lookupPowX2[i] = x^(2^i)
11    private Vector lookupPowX2;
12
13    public void init(byte[] x)
14    {
15        int[] y = GCMUtil.asInts(x);
16        if (lookupPowX2 != null && Arrays.areEqual(y, (int[])lookupPowX2.elementAt(0)))
17        {
18            return;
19        }
20
21        lookupPowX2 = new Vector(8);
22        lookupPowX2.addElement(y);
23    }
24
25    public void exponentiateX(long pow, byte[] output)
26    {
27        int[] y = GCMUtil.oneAsInts();
28        int bit = 0;
29        while (pow > 0)
30        {
31            if ((pow & 1L) != 0)
32            {
33                ensureAvailable(bit);
34                GCMUtil.multiply(y, (int[])lookupPowX2.elementAt(bit));
35            }
36            ++bit;
37            pow >>>= 1;
38        }
39
40        GCMUtil.asBytes(y, output);
41    }
42
43    private void ensureAvailable(int bit)
44    {
45        int count = lookupPowX2.size();
46        if (count <= bit)
47        {
48            int[] tmp = (int[])lookupPowX2.elementAt(count - 1);
49            do
50            {
51                tmp = Arrays.clone(tmp);
52                GCMUtil.multiply(tmp, tmp);
53                lookupPowX2.addElement(tmp);
54            }
55            while (++count <= bit);
56        }
57    }
58}
59