diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-12-16 16:53:50 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-12-16 16:53:50 +0700 |
commit | dac04a9306c5721f92749eee0be203047fc57e50 (patch) | |
tree | b789150541b1e31fac2dc1890b3eae3066b267c6 | |
parent | Add ECDHE_ECDSA CCM ciphersuites from RFC 7251 (diff) | |
download | BouncyCastle.NET-ed25519-dac04a9306c5721f92749eee0be203047fc57e50.tar.xz |
Various updates to GCM from Java build
-rw-r--r-- | crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs | 58 | ||||
-rw-r--r-- | crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs | 28 | ||||
-rw-r--r-- | crypto/src/crypto/modes/gcm/GcmUtilities.cs | 292 | ||||
-rw-r--r-- | crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs | 31 | ||||
-rw-r--r-- | crypto/src/util/Arrays.cs | 5 |
5 files changed, 217 insertions, 197 deletions
diff --git a/crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs b/crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs index 98049e1db..5660a1f84 100644 --- a/crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs +++ b/crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs @@ -4,37 +4,37 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Modes.Gcm { - public class BasicGcmExponentiator - : IGcmExponentiator - { - private byte[] x; + public class BasicGcmExponentiator + : IGcmExponentiator + { + private uint[] x; - public void Init(byte[] x) - { - this.x = Arrays.Clone(x); - } + public void Init(byte[] x) + { + this.x = GcmUtilities.AsUints(x); + } - public void ExponentiateX(long pow, byte[] output) - { - // Initial value is little-endian 1 - byte[] y = GcmUtilities.OneAsBytes(); + public void ExponentiateX(long pow, byte[] output) + { + // Initial value is little-endian 1 + uint[] y = GcmUtilities.OneAsUints(); - if (pow > 0) - { - byte[] powX = Arrays.Clone(x); - do - { - if ((pow & 1L) != 0) - { - GcmUtilities.Multiply(y, powX); - } - GcmUtilities.Multiply(powX, powX); - pow >>= 1; - } - while (pow > 0); - } + if (pow > 0) + { + uint[] powX = Arrays.Clone(x); + do + { + if ((pow & 1L) != 0) + { + GcmUtilities.Multiply(y, powX); + } + GcmUtilities.Multiply(powX, powX); + pow >>= 1; + } + while (pow > 0); + } - Array.Copy(y, 0, output, 0, 16); - } - } + GcmUtilities.AsBytes(y, output); + } + } } diff --git a/crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs b/crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs index 85e3ac9b1..eb89383fb 100644 --- a/crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs +++ b/crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs @@ -1,22 +1,22 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Crypto.Modes.Gcm { - public class BasicGcmMultiplier - : IGcmMultiplier - { - private byte[] H; + public class BasicGcmMultiplier + : IGcmMultiplier + { + private uint[] H; - public void Init(byte[] H) - { - this.H = Arrays.Clone(H); - } + public void Init(byte[] H) + { + this.H = GcmUtilities.AsUints(H); + } public void MultiplyH(byte[] x) - { - GcmUtilities.Multiply(x, H); - } - } + { + uint[] t = GcmUtilities.AsUints(x); + GcmUtilities.Multiply(t, H); + GcmUtilities.AsBytes(t, x); + } + } } diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index 71e63c8fd..0f241035f 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -7,6 +7,31 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm { internal abstract class GcmUtilities { + private const uint E1 = 0xe1000000; + private const ulong E1L = (ulong)E1 << 32; + + private static uint[] GenerateLookup() + { + uint[] lookup = new uint[256]; + + for (int c = 0; c < 256; ++c) + { + uint v = 0; + for (int i = 7; i >= 0; --i) + { + if ((c & (1 << i)) != 0) + { + v ^= (E1 >> (7 - i)); + } + } + lookup[c] = v; + } + + return lookup; + } + + private static readonly uint[] LOOKUP = GenerateLookup(); + internal static byte[] OneAsBytes() { byte[] tmp = new byte[16]; @@ -21,6 +46,16 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm return tmp; } + internal static byte[] AsBytes(uint[] x) + { + return Pack.UInt32_To_BE(x); + } + + internal static void AsBytes(uint[] x, byte[] z) + { + Pack.UInt32_To_BE(x, z, 0); + } + internal static uint[] AsUints(byte[] bs) { uint[] output = new uint[4]; @@ -33,56 +68,55 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm Pack.BE_To_UInt32(bs, 0, output); } - internal static void Multiply(byte[] block, byte[] val) + internal static void Multiply(byte[] x, byte[] y) { - byte[] tmp = Arrays.Clone(block); - byte[] c = new byte[16]; + uint[] t1 = GcmUtilities.AsUints(x); + uint[] t2 = GcmUtilities.AsUints(y); + GcmUtilities.Multiply(t1, t2); + GcmUtilities.AsBytes(t1, x); + } - for (int i = 0; i < 16; ++i) + internal static void Multiply(uint[] x, uint[] y) + { + uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3]; + uint r10 = 0, r11 = 0, r12 = 0, r13 = 0; + + for (int i = 0; i < 4; ++i) { - byte bits = val[i]; - for (int j = 7; j >= 0; --j) + int bits = (int)y[i]; + for (int j = 0; j < 32; ++j) { - if ((bits & (1 << j)) != 0) - { - Xor(c, tmp); - } - - bool lsb = (tmp[15] & 1) != 0; - ShiftRight(tmp); - if (lsb) - { - // R = new byte[]{ 0xe1, ... }; - //GCMUtilities.Xor(tmp, R); - tmp[0] ^= (byte)0xe1; - } + uint m1 = (uint)(bits >> 31); bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); + r12 ^= (r02 & m1); + r13 ^= (r03 & m1); + + uint m2 = (uint)((int)(r03 << 31) >> 8); + r03 = (r03 >> 1) | (r02 << 63); + r02 = (r02 >> 1) | (r01 << 63); + r01 = (r01 >> 1) | (r00 << 63); + r00 = (r00 >> 1) ^ (m2 & E1); } } - Array.Copy(c, 0, block, 0, 16); + x[0] = r10; + x[1] = r11; + x[2] = r12; + x[3] = r13; } // P is the value with only bit i=1 set internal static void MultiplyP(uint[] x) { - bool lsb = (x[3] & 1) != 0; - ShiftRight(x); - if (lsb) - { - // R = new uint[]{ 0xe1000000, 0, 0, 0 }; - //Xor(v, R); - x[0] ^= 0xe1000000; - } + uint m = (uint)((int)ShiftRight(x) >> 8); + x[0] ^= (m & E1); } - internal static void MultiplyP(uint[] x, uint[] output) + internal static void MultiplyP(uint[] x, uint[] z) { - bool lsb = (x[3] & 1) != 0; - ShiftRight(x, output); - if (lsb) - { - output[0] ^= 0xe1000000; - } + uint m = (uint)((int)ShiftRight(x, z) >> 8); + z[0] ^= (m & E1); } internal static void MultiplyP8(uint[] x) @@ -92,146 +126,128 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm // MultiplyP(x); // } - uint lsw = x[3]; - ShiftRightN(x, 8); - for (int i = 7; i >= 0; --i) - { - if ((lsw & (1 << i)) != 0) - { - x[0] ^= (0xe1000000 >> (7 - i)); - } - } - } - - internal static void MultiplyP8(uint[] x, uint[] output) - { - uint lsw = x[3]; - ShiftRightN(x, 8, output); - for (int i = 7; i >= 0; --i) - { - if ((lsw & (1 << i)) != 0) - { - output[0] ^= (0xe1000000 >> (7 - i)); - } - } + uint c = ShiftRightN(x, 8); + x[0] ^= LOOKUP[c >> 24]; } - internal static void ShiftRight(byte[] block) + internal static void MultiplyP8(uint[] x, uint[] y) { - int i = 0; - byte bit = 0; - for (; ; ) - { - byte b = block[i]; - block[i] = (byte)((b >> 1) | bit); - if (++i == 16) break; - bit = (byte)(b << 7); - } + uint c = ShiftRightN(x, 8, y); + y[0] ^= LOOKUP[c >> 24]; } - static void ShiftRight(byte[] block, byte[] output) + internal static uint ShiftRight(uint[] x) { - int i = 0; - byte bit = 0; - for (;;) - { - byte b = block[i]; - output[i] = (byte)((b >> 1) | bit); - if (++i == 16) break; - bit = (byte)(b << 7); - } + uint b = x[0]; + x[0] = b >> 1; + uint 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; } - internal static void ShiftRight(uint[] block) + internal static uint ShiftRight(uint[] x, uint[] z) { - int i = 0; - uint bit = 0; - for (; ; ) - { - uint b = block[i]; - block[i] = (b >> 1) | bit; - if (++i == 4) break; - bit = b << 31; - } + uint b = x[0]; + z[0] = b >> 1; + uint 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; } - internal static void ShiftRight(uint[] block, uint[] output) + internal static uint ShiftRightN(uint[] x, int n) { - int i = 0; - uint bit = 0; - for (; ; ) - { - uint b = block[i]; - output[i] = (b >> 1) | bit; - if (++i == 4) break; - bit = b << 31; - } + uint b = x[0]; int nInv = 32 - n; + x[0] = b >> n; + uint 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; } - internal static void ShiftRightN(uint[] block, int n) + internal static uint ShiftRightN(uint[] x, int n, uint[] z) { - int i = 0; - uint bit = 0; - for (; ; ) - { - uint b = block[i]; - block[i] = (b >> n) | bit; - if (++i == 4) break; - bit = b << (32 - n); - } + uint b = x[0]; int nInv = 32 - n; + z[0] = b >> n; + uint 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; } - internal static void ShiftRightN(uint[] block, int n, uint[] output) + internal static void Xor(byte[] x, byte[] y) { int i = 0; - uint bit = 0; - for (; ; ) - { - uint b = block[i]; - output[i] = (b >> n) | bit; - if (++i == 4) break; - bit = b << (32 - n); - } - } - - internal static void Xor(byte[] block, byte[] val) - { - for (int i = 15; i >= 0; --i) + do { - block[i] ^= val[i]; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; + x[i] ^= y[i]; ++i; } + while (i < 16); } - internal static void Xor(byte[] block, byte[] val, int off, int len) + internal static void Xor(byte[] x, byte[] y, int yOff, int yLen) { - while (--len >= 0) + while (--yLen >= 0) { - block[len] ^= val[off + len]; + x[yLen] ^= y[yOff + yLen]; } } - internal static void Xor(byte[] block, byte[] val, byte[] output) + internal static void Xor(byte[] x, byte[] y, byte[] z) { - for (int i = 15; i >= 0; --i) + int i = 0; + do { - output[i] = (byte)(block[i] ^ val[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; + z[i] = (byte)(x[i] ^ y[i]); ++i; } + while (i < 16); } - internal static void Xor(uint[] block, uint[] val) + internal static void Xor(uint[] x, uint[] y) { - for (int i = 3; i >= 0; --i) - { - block[i] ^= val[i]; - } + x[0] ^= y[0]; + x[1] ^= y[1]; + x[2] ^= y[2]; + x[3] ^= y[3]; } - internal static void Xor(uint[] block, uint[] val, uint[] output) + internal static void Xor(uint[] x, uint[] y, uint[] z) { - for (int i = 3; i >= 0; --i) - { - output[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]; } } } diff --git a/crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs b/crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs index 44933bba7..e649d6770 100644 --- a/crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs +++ b/crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs @@ -5,48 +5,47 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Modes.Gcm { - public class Tables1kGcmExponentiator - : IGcmExponentiator - { + public class Tables1kGcmExponentiator + : IGcmExponentiator + { // A lookup table of the power-of-two powers of 'x' // - lookupPowX2[i] = x^(2^i) private IList lookupPowX2; public void Init(byte[] x) - { - if (lookupPowX2 != null && Arrays.AreEqual(x, (byte[])lookupPowX2[0])) - { + { + uint[] y = GcmUtilities.AsUints(x); + if (lookupPowX2 != null && Arrays.AreEqual(y, (uint[])lookupPowX2[0])) return; - } lookupPowX2 = Platform.CreateArrayList(8); - lookupPowX2.Add(Arrays.Clone(x)); - } + lookupPowX2.Add(y); + } - public void ExponentiateX(long pow, byte[] output) - { - byte[] y = GcmUtilities.OneAsBytes(); + public void ExponentiateX(long pow, byte[] output) + { + uint[] y = GcmUtilities.OneAsUints(); int bit = 0; while (pow > 0) { if ((pow & 1L) != 0) { EnsureAvailable(bit); - GcmUtilities.Multiply(y, (byte[])lookupPowX2[bit]); + GcmUtilities.Multiply(y, (uint[])lookupPowX2[bit]); } ++bit; pow >>= 1; } - Array.Copy(y, 0, output, 0, 16); - } + GcmUtilities.AsBytes(y, output); + } private void EnsureAvailable(int bit) { int count = lookupPowX2.Count; if (count <= bit) { - byte[] tmp = (byte[])lookupPowX2[count - 1]; + uint[] tmp = (uint[])lookupPowX2[count - 1]; do { tmp = Arrays.Clone(tmp); diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index 27fd18d6d..8614baead 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -339,6 +339,11 @@ namespace Org.BouncyCastle.Utilities return data == null ? null : (int[])data.Clone(); } + internal static uint[] Clone(uint[] data) + { + return data == null ? null : (uint[])data.Clone(); + } + public static long[] Clone(long[] data) { return data == null ? null : (long[])data.Clone(); |