diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-10-01 16:15:56 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-10-01 16:15:56 +0400 |
commit | 3f14ee7574c470800c01a0b799c870bfbee0c91a (patch) | |
tree | e18337ae9087e63062fd1929158baf1051ea30e5 /core | |
parent | 64c0d16f8c09bc83313702557194769a6e24acc3 (diff) |
Renaming and refactoring, loop unrolling
Return carries from shift methods and use instead of explicit read
Add methods using longs
Diffstat (limited to 'core')
-rw-r--r-- | core/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java | 449 |
1 files changed, 317 insertions, 132 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/core/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java index e9ce75b1..3031a444 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java @@ -6,22 +6,24 @@ import org.bouncycastle.util.Arrays; abstract class GCMUtil { private static final int E1 = 0xe1000000; + private static final byte E1B = (byte)0xe1; + private static final long E1L = (E1 & 0xFFFFFFFFL) << 24; private static int[] generateLookup() { int[] lookup = new int[256]; - for (int lsw = 0; lsw < 256; ++lsw) + for (int c = 0; c < 256; ++c) { int v = 0; for (int i = 7; i >= 0; --i) { - if ((lsw & (1 << i)) != 0) + if ((c & (1 << i)) != 0) { v ^= (E1 >>> (7 - i)); } } - lookup[lsw] = v; + lookup[c] = v; } return lookup; @@ -39,76 +41,153 @@ abstract class GCMUtil static int[] oneAsInts() { int[] tmp = new int[4]; - tmp[0] = 0x80000000; + tmp[0] = 1 << 31; return tmp; } - static byte[] asBytes(int[] ns) + static long[] oneAsLongs() { - byte[] output = new byte[16]; - Pack.intToBigEndian(ns, output, 0); - return output; + long[] tmp = new long[2]; + tmp[0] = 1L << 63; + return tmp; + } + + static byte[] asBytes(int[] x) + { + byte[] z = new byte[16]; + Pack.intToBigEndian(x, z, 0); + return z; + } + + static void asBytes(int[] x, byte[] z) + { + Pack.intToBigEndian(x, z, 0); } - static int[] asInts(byte[] bs) + static byte[] asBytes(long[] x) { - int[] output = new int[4]; - Pack.bigEndianToInt(bs, 0, output); - return output; + byte[] z = new byte[16]; + Pack.longToBigEndian(x, z, 0); + return z; } - static void asInts(byte[] bs, int[] output) + static void asBytes(long[] x, byte[] z) { - Pack.bigEndianToInt(bs, 0, output); + Pack.longToBigEndian(x, z, 0); } - static void multiply(byte[] block, byte[] val) + static int[] asInts(byte[] x) { - byte[] tmp = Arrays.clone(block); - byte[] c = new byte[16]; + int[] z = new int[4]; + Pack.bigEndianToInt(x, 0, z); + return z; + } + + static void asInts(byte[] x, int[] z) + { + Pack.bigEndianToInt(x, 0, z); + } + + static long[] asLongs(byte[] x) + { + long[] z = new long[2]; + Pack.bigEndianToLong(x, 0, z); + return z; + } + + static void asLongs(byte[] x, long[] z) + { + Pack.bigEndianToLong(x, 0, z); + } + + static void multiply(byte[] x, byte[] y) + { + byte[] r0 = Arrays.clone(x); + byte[] r1 = new byte[16]; for (int i = 0; i < 16; ++i) { - byte bits = val[i]; + byte bits = y[i]; for (int j = 7; j >= 0; --j) { if ((bits & (1 << j)) != 0) { - xor(c, tmp); + xor(r1, r0); } - boolean lsb = (tmp[15] & 1) != 0; - shiftRight(tmp); - if (lsb) + if (shiftRight(r0) != 0) { - // R = new byte[]{ 0xe1, ... }; -// GCMUtil.xor(v, R); - tmp[0] ^= (byte)0xe1; + r0[0] ^= E1B; } } } - System.arraycopy(c, 0, block, 0, 16); + System.arraycopy(r1, 0, x, 0, 16); + } + + static void multiply(int[] x, int[] y) + { + int[] r0 = Arrays.clone(x); + int[] r1 = new int[4]; + + for (int i = 0; i < 4; ++i) + { + int bits = y[i]; + for (int j = 31; j >= 0; --j) + { + if ((bits & (1 << j)) != 0) + { + xor(r1, r0); + } + + if (shiftRight(r0) != 0) + { + r0[0] ^= E1; + } + } + } + + System.arraycopy(r1, 0, x, 0, 4); + } + + static void multiply(long[] x, long[] y) + { + long[] r0 = new long[]{ x[0], x[1] }; + long[] r1 = new long[2]; + + for (int i = 0; i < 2; ++i) + { + long bits = y[i]; + for (int j = 63; j >= 0; --j) + { + if ((bits & (1L << j)) != 0) + { + xor(r1, r0); + } + + if (shiftRight(r0) != 0) + { + r0[0] ^= E1L; + } + } + } + + x[0] = r1[0]; + x[1] = r1[1]; } // P is the value with only bit i=1 set static void multiplyP(int[] x) { - boolean lsb = (x[3] & 1) != 0; - shiftRight(x); - if (lsb) + if (shiftRight(x) != 0) { - // R = new int[]{ 0xe1000000, 0, 0, 0 }; -// xor(v, R); x[0] ^= E1; } } static void multiplyP(int[] x, int[] y) { - boolean lsb = (x[3] & 1) != 0; - shiftRight(x, y); - if (lsb) + if (shiftRight(x, y) != 0) { y[0] ^= E1; } @@ -122,151 +201,257 @@ abstract class GCMUtil // multiplyP(x); // } - int lsw = x[3] & 0xFF; - shiftRightN(x, 8); - x[0] ^= LOOKUP[lsw]; + int c = shiftRightN(x, 8); + x[0] ^= LOOKUP[c >>> 24]; } static void multiplyP8(int[] x, int[] y) { - int lsw = x[3] & 0xFF; - shiftRightN(x, 8, y); - y[0] ^= LOOKUP[lsw]; + int c = shiftRightN(x, 8, y); + y[0] ^= LOOKUP[c >>> 24]; } - static void shiftRight(byte[] block) + static byte shiftRight(byte[] x) { - int i = 0; - int bit = 0; - for (;;) +// int c = 0; +// for (int i = 0; i < 16; ++i) +// { +// int b = x[i] & 0xff; +// x[i] = (byte)((b >>> 1) | c); +// c = (b & 1) << 7; +// } +// return (byte)c; + + int i = 0, c = 0; + do { - int b = block[i] & 0xff; - block[i] = (byte) ((b >>> 1) | bit); - if (++i == 16) - { - break; - } - bit = (b & 1) << 7; + int b = x[i] & 0xff; + x[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + x[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + x[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + x[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; } + while (i < 16); + return (byte)c; } - static void shiftRight(byte[] block, byte[] output) + static byte shiftRight(byte[] x, byte[] z) { - int i = 0; - int bit = 0; - for (;;) +// int c = 0; +// for (int i = 0; i < 16; ++i) +// { +// int b = x[i] & 0xff; +// z[i] = (byte) ((b >>> 1) | c); +// c = (b & 1) << 7; +// } +// return (byte) c; + + int i = 0, c = 0; + do { - int b = block[i] & 0xff; - output[i] = (byte) ((b >>> 1) | bit); - if (++i == 16) - { - break; - } - bit = (b & 1) << 7; + int b = x[i] & 0xff; + z[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + z[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + z[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; + b = x[i] & 0xff; + z[i++] = (byte)((b >>> 1) | c); + c = (b & 1) << 7; } + while (i < 16); + return (byte)c; } - static void shiftRight(int[] block) + static int shiftRight(int[] x) { - int i = 0; - int bit = 0; - for (;;) - { - int b = block[i]; - block[i] = (b >>> 1) | bit; - if (++i == 4) - { - break; - } - bit = b << 31; - } +// int c = 0; +// for (int i = 0; i < 4; ++i) +// { +// int b = x[i]; +// x[i] = (b >>> 1) | c; +// c = b << 31; +// } +// return c; + + int b = x[0]; + x[0] = b >>> 1; + int c = b << 31; + b = x[1]; + x[1] = (b >>> 1) | c; + c = b << 31; + b = x[2]; + x[2] = (b >>> 1) | c; + c = b << 31; + b = x[3]; + x[3] = (b >>> 1) | c; + return b << 31; } - static void shiftRight(int[] block, int[] output) + static int shiftRight(int[] x, int[] z) { - int i = 0; - int bit = 0; - for (;;) - { - int b = block[i]; - output[i] = (b >>> 1) | bit; - if (++i == 4) - { - break; - } - bit = b << 31; - } +// int c = 0; +// for (int i = 0; i < 4; ++i) +// { +// int b = x[i]; +// z[i] = (b >>> 1) | c; +// c = b << 31; +// } +// return c; + + int b = x[0]; + z[0] = b >>> 1; + int c = b << 31; + b = x[1]; + z[1] = (b >>> 1) | c; + c = b << 31; + b = x[2]; + z[2] = (b >>> 1) | c; + c = b << 31; + b = x[3]; + z[3] = (b >>> 1) | c; + return b << 31; } - static void shiftRightN(int[] block, int n) + static long shiftRight(long[] x) { - int i = 0; - int bits = 0; - for (;;) - { - int b = block[i]; - block[i] = (b >>> n) | bits; - if (++i == 4) - { - break; - } - bits = b << (32 - n); - } + long b = x[0]; + x[0] = b >>> 1; + long c = b << 63; + b = x[1]; + x[1] = (b >>> 1) | c; + return b << 63; } - static void shiftRightN(int[] block, int n, int[] output) + static long shiftRight(long[] x, long[] z) + { + long b = x[0]; + z[0] = b >>> 1; + long c = b << 63; + b = x[1]; + z[1] = (b >>> 1) | c; + return b << 63; + } + + static int shiftRightN(int[] x, int n) + { +// int c = 0, nInv = 32 - n; +// for (int i = 0; i < 4; ++i) +// { +// int b = x[i]; +// x[i] = (b >>> n) | c; +// c = b << nInv; +// } +// return c; + + int b = x[0], nInv = 32 - n; + x[0] = b >>> n; + int c = b << nInv; + b = x[1]; + x[1] = (b >>> n) | c; + c = b << nInv; + b = x[2]; + x[2] = (b >>> n) | c; + c = b << nInv; + b = x[3]; + x[3] = (b >>> n) | c; + return b << nInv; + } + + static int shiftRightN(int[] x, int n, int[] z) + { +// int c = 0, nInv = 32 - n; +// for (int i = 0; i < 4; ++i) +// { +// int b = x[i]; +// z[i] = (b >>> n) | c; +// c = b << nInv; +// } +// return c; + + int b = x[0], nInv = 32 - n; + z[0] = b >>> n; + int c = b << nInv; + b = x[1]; + z[1] = (b >>> n) | c; + c = b << nInv; + b = x[2]; + z[2] = (b >>> n) | c; + c = b << nInv; + b = x[3]; + z[3] = (b >>> n) | c; + return b << nInv; + } + + static void xor(byte[] x, byte[] y) { int i = 0; - int bits = 0; - for (;;) + do { - int b = block[i]; - output[i] = (b >>> n) | bits; - if (++i == 4) - { - break; - } - bits = b << (32 - n); + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; } + while (i < 16); } - static void xor(byte[] block, byte[] val) + static void xor(byte[] x, byte[] y, int yOff, int yLen) { - for (int i = 15; i >= 0; --i) + while (yLen-- > 0) { - block[i] ^= val[i]; + x[yLen] ^= y[yOff + yLen]; } } - static void xor(byte[] block, byte[] val, int off, int len) + static void xor(byte[] x, byte[] y, byte[] z) { - while (len-- > 0) + int i = 0; + do { - block[len] ^= val[off + len]; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; + z[i] = (byte)(x[i] ^ y[i]); ++i; } + while (i < 16); } - static void xor(byte[] block, byte[] val, byte[] output) + static void xor(int[] x, int[] y) { - for (int i = 15; i >= 0; --i) - { - output[i] = (byte)(block[i] ^ val[i]); - } + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; } - static void xor(int[] block, int[] val) + static void xor(int[] x, int[] y, int[] z) { - for (int i = 3; i >= 0; --i) - { - block[i] ^= val[i]; - } + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; + z[2] = x[2] ^ y[2]; + z[3] = x[3] ^ y[3]; } - static void xor(int[] block, int[] val, int[] output) + static void xor(long[] x, long[] y) { - for (int i = 3; i >= 0; --i) - { - output[i] = block[i] ^ val[i]; - } + x[0] ^= y[0]; + x[1] ^= y[1]; + } + + static void xor(long[] x, long[] y, long[] z) + { + z[0] = x[0] ^ y[0]; + z[1] = x[1] ^ y[1]; } } |