summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-12-16 16:53:50 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-12-16 16:53:50 +0700
commitdac04a9306c5721f92749eee0be203047fc57e50 (patch)
treeb789150541b1e31fac2dc1890b3eae3066b267c6
parentAdd ECDHE_ECDSA CCM ciphersuites from RFC 7251 (diff)
downloadBouncyCastle.NET-ed25519-dac04a9306c5721f92749eee0be203047fc57e50.tar.xz
Various updates to GCM from Java build
-rw-r--r--crypto/src/crypto/modes/gcm/BasicGcmExponentiator.cs58
-rw-r--r--crypto/src/crypto/modes/gcm/BasicGcmMultiplier.cs28
-rw-r--r--crypto/src/crypto/modes/gcm/GcmUtilities.cs292
-rw-r--r--crypto/src/crypto/modes/gcm/Tables1kGcmExponentiator.cs31
-rw-r--r--crypto/src/util/Arrays.cs5
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();