116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.crypto.modes.gcm;
216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giroimport org.bouncycastle.util.Pack;
416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giropublic abstract class GCMUtil
616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{
780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    private static final int E1 = 0xe1000000;
853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    private static final long E1L = (E1 & 0xFFFFFFFFL) << 32;
980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
1080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    private static int[] generateLookup()
1180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
1280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int[] lookup = new int[256];
1380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
1480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        for (int c = 0; c < 256; ++c)
1580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        {
1680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            int v = 0;
1780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            for (int i = 7; i >= 0; --i)
1880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            {
1980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro                if ((c & (1 << i)) != 0)
2080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro                {
2180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro                    v ^= (E1 >>> (7 - i));
2280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro                }
2380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            }
2480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            lookup[c] = v;
2580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        }
2680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
2780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return lookup;
2880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
2980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
3080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    private static final int[] LOOKUP = generateLookup();
3180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
3253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static byte[] oneAsBytes()
3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        byte[] tmp = new byte[16];
3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        tmp[0] = (byte)0x80;
3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return tmp;
3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
3953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static int[] oneAsInts()
4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        int[] tmp = new int[4];
4280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        tmp[0] = 1 << 31;
4380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return tmp;
4480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
4580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
4653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static long[] oneAsLongs()
4780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
4880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long[] tmp = new long[2];
4980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        tmp[0] = 1L << 63;
5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return tmp;
5116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
5353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static byte[] asBytes(int[] x)
5480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
5580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        byte[] z = new byte[16];
5680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.intToBigEndian(x, z, 0);
5780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return z;
5880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
5980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
6053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void asBytes(int[] x, byte[] z)
6180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
6280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.intToBigEndian(x, z, 0);
6380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
6480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
6553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static byte[] asBytes(long[] x)
6680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
6780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        byte[] z = new byte[16];
6880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.longToBigEndian(x, z, 0);
6980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return z;
7080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
7180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
7253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void asBytes(long[] x, byte[] z)
7380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
7480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.longToBigEndian(x, z, 0);
7580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
7680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
7753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static int[] asInts(byte[] x)
7880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
7980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int[] z = new int[4];
8080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.bigEndianToInt(x, 0, z);
8180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return z;
8280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
8380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
8453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void asInts(byte[] x, int[] z)
8516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
8680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.bigEndianToInt(x, 0, z);
8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
8953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static long[] asLongs(byte[] x)
9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
9180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long[] z = new long[2];
9280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.bigEndianToLong(x, 0, z);
9380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return z;
9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
9653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void asLongs(byte[] x, long[] z)
9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
9880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        Pack.bigEndianToLong(x, 0, z);
9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
10153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiply(byte[] x, byte[] y)
10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
10353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int[] t1 = GCMUtil.asInts(x);
10453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int[] t2 = GCMUtil.asInts(y);
10553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        GCMUtil.multiply(t1, t2);
10653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        GCMUtil.asBytes(t1, x);
10780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
10880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
10953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiply(int[] x, int[] y)
11080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
11153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3];
11253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int r10 = 0, r11 = 0, r12 = 0, r13 = 0;
11353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro
11480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        for (int i = 0; i < 4; ++i)
11580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        {
11680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            int bits = y[i];
11753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro            for (int j = 0; j < 32; ++j)
11880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            {
11953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                int m1 = bits >> 31; bits <<= 1;
12053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r10 ^= (r00 & m1);
12153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r11 ^= (r01 & m1);
12253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r12 ^= (r02 & m1);
12353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r13 ^= (r03 & m1);
12453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro
12553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                int m2 = (r03 << 31) >> 8;
126bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro                r03 = (r03 >>> 1) | (r02 << 31);
127bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro                r02 = (r02 >>> 1) | (r01 << 31);
128bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro                r01 = (r01 >>> 1) | (r00 << 31);
12953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r00 = (r00 >>> 1) ^ (m2 & E1);
13080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            }
13180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        }
13280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
13353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[0] = r10;
13453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[1] = r11;
13553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[2] = r12;
13653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[3] = r13;
13780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
13880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
13953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiply(long[] x, long[] y)
14080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
14153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        long r00 = x[0], r01 = x[1], r10 = 0, r11 = 0;
14280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
14380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        for (int i = 0; i < 2; ++i)
14480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        {
14580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            long bits = y[i];
14653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro            for (int j = 0; j < 64; ++j)
14780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            {
14853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                long m1 = bits >> 63; bits <<= 1;
14953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r10 ^= (r00 & m1);
15053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r11 ^= (r01 & m1);
15180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
15253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                long m2 = (r01 << 63) >> 8;
15353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r01 = (r01 >>> 1) | (r00 << 63);
15453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                r00 = (r00 >>> 1) ^ (m2 & E1L);
15580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            }
15680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        }
15780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
15853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[0] = r10;
15953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[1] = r11;
16016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
16116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
16216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    // P is the value with only bit i=1 set
16353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiplyP(int[] x)
16416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
16553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int m = shiftRight(x) >> 8;
16653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        x[0] ^= (m & E1);
16716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
16816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
16953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiplyP(int[] x, int[] z)
17016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
17153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        int m = shiftRight(x, z) >> 8;
17253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        z[0] ^= (m & E1);
17316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
17416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
17516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    // P is the value with only bit i=1 set
17653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiplyP8(int[] x)
17716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
17816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro//        for (int i = 8; i != 0; --i)
17916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro//        {
18016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro//            multiplyP(x);
18116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro//        }
18216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
18380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = shiftRightN(x, 8);
18480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] ^= LOOKUP[c >>> 24];
18516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
18616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
18753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void multiplyP8(int[] x, int[] y)
18816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
18980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = shiftRightN(x, 8, y);
19080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        y[0] ^= LOOKUP[c >>> 24];
19116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
19380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static int shiftRight(int[] x)
19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
19580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        int c = 0;
19680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        for (int i = 0; i < 4; ++i)
19780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        {
19880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            int b = x[i];
19980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            x[i] = (b >>> 1) | c;
20080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            c = b << 31;
20180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        }
20280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        return c;
20380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
20480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int b = x[0];
20580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] = b >>> 1;
20680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = b << 31;
20780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
20880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[1] = (b >>> 1) | c;
20980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << 31;
21080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[2];
21180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[2] = (b >>> 1) | c;
21280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << 31;
21380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[3];
21480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[3] = (b >>> 1) | c;
21580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << 31;
21616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
21716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
21880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static int shiftRight(int[] x, int[] z)
21916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
22080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//      int c = 0;
22180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//      for (int i = 0; i < 4; ++i)
22280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//      {
22380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//          int b = x[i];
22480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//          z[i] = (b >>> 1) | c;
22580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//          c = b << 31;
22680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//      }
22780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//      return c;
22880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
22980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int b = x[0];
23080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[0] = b >>> 1;
23180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = b << 31;
23280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
23380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[1] = (b >>> 1) | c;
23480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << 31;
23580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[2];
23680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[2] = (b >>> 1) | c;
23780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << 31;
23880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[3];
23980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[3] = (b >>> 1) | c;
24080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << 31;
24116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
24216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
24380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static long shiftRight(long[] x)
24416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
24580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long b = x[0];
24680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] = b >>> 1;
24780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long c = b << 63;
24880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
24980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[1] = (b >>> 1) | c;
25080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << 63;
25180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
25280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
25380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static long shiftRight(long[] x, long[] z)
25480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
25580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long b = x[0];
25680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[0] = b >>> 1;
25780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        long c = b << 63;
25880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
25980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[1] = (b >>> 1) | c;
26080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << 63;
26180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
26280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
26380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static int shiftRightN(int[] x, int n)
26480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
26580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        int c = 0, nInv = 32 - n;
26680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        for (int i = 0; i < 4; ++i)
26780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        {
26880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            int b = x[i];
26980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            x[i] = (b >>> n) | c;
27080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            c = b << nInv;
27180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        }
27280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        return c;
27380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
27480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int b = x[0], nInv = 32 - n;
27580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] = b >>> n;
27680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = b << nInv;
27780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
27880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[1] = (b >>> n) | c;
27980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << nInv;
28080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[2];
28180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[2] = (b >>> n) | c;
28280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << nInv;
28380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[3];
28480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[3] = (b >>> n) | c;
28580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << nInv;
28616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
28716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
28880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    static int shiftRightN(int[] x, int n, int[] z)
28980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
29080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        int c = 0, nInv = 32 - n;
29180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        for (int i = 0; i < 4; ++i)
29280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        {
29380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            int b = x[i];
29480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            z[i] = (b >>> n) | c;
29580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//            c = b << nInv;
29680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        }
29780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro//        return c;
29880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
29980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int b = x[0], nInv = 32 - n;
30080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[0] = b >>> n;
30180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int c = b << nInv;
30280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[1];
30380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[1] = (b >>> n) | c;
30480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << nInv;
30580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[2];
30680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[2] = (b >>> n) | c;
30780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        c = b << nInv;
30880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        b = x[3];
30980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[3] = (b >>> n) | c;
31080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        return b << nInv;
31180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
31280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
31353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(byte[] x, byte[] y)
31416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
31516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        int i = 0;
31680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        do
31716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
31880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            x[i] ^= y[i]; ++i;
31980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            x[i] ^= y[i]; ++i;
32080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            x[i] ^= y[i]; ++i;
32180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            x[i] ^= y[i]; ++i;
32216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
32380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        while (i < 16);
32416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
32516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
32653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(byte[] x, byte[] y, int yOff, int yLen)
32716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
32853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro        while (--yLen >= 0)
32916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
33080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            x[yLen] ^= y[yOff + yLen];
33116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
33216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
33316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
33453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(byte[] x, byte[] y, byte[] z)
33516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
33680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        int i = 0;
33780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        do
33816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
33980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            z[i] = (byte)(x[i] ^ y[i]); ++i;
34080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            z[i] = (byte)(x[i] ^ y[i]); ++i;
34180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            z[i] = (byte)(x[i] ^ y[i]); ++i;
34280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro            z[i] = (byte)(x[i] ^ y[i]); ++i;
34316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
34480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        while (i < 16);
34516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
34616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
34753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(int[] x, int[] y)
34816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
34980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] ^= y[0];
35080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[1] ^= y[1];
35180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[2] ^= y[2];
35280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[3] ^= y[3];
35316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
35416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
35553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(int[] x, int[] y, int[] z)
35616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
35780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[0] = x[0] ^ y[0];
35880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[1] = x[1] ^ y[1];
35980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[2] = x[2] ^ y[2];
36080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[3] = x[3] ^ y[3];
36116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
36216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
36353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(long[] x, long[] y)
36416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
36580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[0] ^= y[0];
36680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        x[1] ^= y[1];
36780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    }
36880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro
36953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    public static void xor(long[] x, long[] y, long[] z)
37080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro    {
37180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[0] = x[0] ^ y[0];
37280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro        z[1] = x[1] ^ y[1];
37316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
37416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro}
375