GCMUtil.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.crypto.modes.gcm;
2
3import org.bouncycastle.crypto.util.Pack;
4import org.bouncycastle.util.Arrays;
5
6abstract class GCMUtil
7{
8    static byte[] oneAsBytes()
9    {
10        byte[] tmp = new byte[16];
11        tmp[0] = (byte)0x80;
12        return tmp;
13    }
14
15    static int[] oneAsInts()
16    {
17        int[] tmp = new int[4];
18        tmp[0] = 0x80000000;
19        return tmp;
20    }
21
22    static int[] asInts(byte[] bs)
23    {
24        int[] us = new int[4];
25        us[0] = Pack.bigEndianToInt(bs, 0);
26        us[1] = Pack.bigEndianToInt(bs, 4);
27        us[2] = Pack.bigEndianToInt(bs, 8);
28        us[3] = Pack.bigEndianToInt(bs, 12);
29        return us;
30    }
31
32    static void multiply(byte[] block, byte[] val)
33    {
34        byte[] tmp = Arrays.clone(block);
35        byte[] c = new byte[16];
36
37        for (int i = 0; i < 16; ++i)
38        {
39            byte bits = val[i];
40            for (int j = 7; j >= 0; --j)
41            {
42                if ((bits & (1 << j)) != 0)
43                {
44                    xor(c, tmp);
45                }
46
47                boolean lsb = (tmp[15] & 1) != 0;
48                shiftRight(tmp);
49                if (lsb)
50                {
51                    // R = new byte[]{ 0xe1, ... };
52//                    GCMUtil.xor(v, R);
53                    tmp[0] ^= (byte)0xe1;
54                }
55            }
56        }
57
58        System.arraycopy(c, 0, block, 0, 16);
59    }
60
61    // P is the value with only bit i=1 set
62    static void multiplyP(int[] x)
63    {
64        boolean lsb = (x[3] & 1) != 0;
65        shiftRight(x);
66        if (lsb)
67        {
68            // R = new int[]{ 0xe1000000, 0, 0, 0 };
69//            xor(v, R);
70            x[0] ^= 0xe1000000;
71        }
72    }
73
74    static void multiplyP8(int[] x)
75    {
76//        for (int i = 8; i != 0; --i)
77//        {
78//            multiplyP(x);
79//        }
80
81        int lsw = x[3];
82        shiftRightN(x, 8);
83        for (int i = 7; i >= 0; --i)
84        {
85            if ((lsw & (1 << i)) != 0)
86            {
87                x[0] ^= (0xe1000000 >>> (7 - i));
88            }
89        }
90    }
91
92    static void shiftRight(byte[] block)
93    {
94        int i = 0;
95        int bit = 0;
96        for (;;)
97        {
98            int b = block[i] & 0xff;
99            block[i] = (byte) ((b >>> 1) | bit);
100            if (++i == 16)
101            {
102                break;
103            }
104            bit = (b & 1) << 7;
105        }
106    }
107
108    static void shiftRight(int[] block)
109    {
110        int i = 0;
111        int bit = 0;
112        for (;;)
113        {
114            int b = block[i];
115            block[i] = (b >>> 1) | bit;
116            if (++i == 4)
117            {
118                break;
119            }
120            bit = b << 31;
121        }
122    }
123
124    static void shiftRightN(int[] block, int n)
125    {
126        int i = 0;
127        int bits = 0;
128        for (;;)
129        {
130            int b = block[i];
131            block[i] = (b >>> n) | bits;
132            if (++i == 4)
133            {
134                break;
135            }
136            bits = b << (32 - n);
137        }
138    }
139
140    static void xor(byte[] block, byte[] val)
141    {
142        for (int i = 15; i >= 0; --i)
143        {
144            block[i] ^= val[i];
145        }
146    }
147
148    static void xor(int[] block, int[] val)
149    {
150        for (int i = 3; i >= 0; --i)
151        {
152            block[i] ^= val[i];
153        }
154    }
155}
156