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        if (lookupPowX2 != null && Arrays.areEqual(x, (byte[])lookupPowX2.elementAt(0)))
16        {
17            return;
18        }
19
20        lookupPowX2 = new Vector(8);
21        lookupPowX2.addElement(Arrays.clone(x));
22    }
23
24    public void exponentiateX(long pow, byte[] output)
25    {
26        byte[] y = GCMUtil.oneAsBytes();
27        int bit = 0;
28        while (pow > 0)
29        {
30            if ((pow & 1L) != 0)
31            {
32                ensureAvailable(bit);
33                GCMUtil.multiply(y, (byte[])lookupPowX2.elementAt(bit));
34            }
35            ++bit;
36            pow >>>= 1;
37        }
38
39        System.arraycopy(y, 0, output, 0, 16);
40    }
41
42    private void ensureAvailable(int bit)
43    {
44        int count = lookupPowX2.size();
45        if (count <= bit)
46        {
47            byte[] tmp = (byte[])lookupPowX2.elementAt(count - 1);
48            do
49            {
50                tmp = Arrays.clone(tmp);
51                GCMUtil.multiply(tmp, tmp);
52                lookupPowX2.addElement(tmp);
53            }
54            while (++count <= bit);
55        }
56    }
57}
58