summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-27 20:48:58 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-27 20:48:58 +0700
commit24a0aa84a2dfe82f7cabe89d3ab98437e8d027ef (patch)
tree2d720ef01e744e6ead9c3848eab8ec4755db9993
parentUpdate comments (diff)
downloadBouncyCastle.NET-ed25519-24a0aa84a2dfe82f7cabe89d3ab98437e8d027ef.tar.xz
Refactoring in Math.EC.Rfc8032
-rw-r--r--crypto/src/math/ec/rfc7748/X25519Field.cs7
-rw-r--r--crypto/src/math/ec/rfc7748/X448Field.cs12
-rw-r--r--crypto/src/math/ec/rfc8032/Ed25519.cs115
-rw-r--r--crypto/src/math/ec/rfc8032/Ed448.cs118
-rw-r--r--crypto/src/math/ec/rfc8032/Scalar448.cs2
-rw-r--r--crypto/src/math/ec/rfc8032/ScalarUtilities.cs7
-rw-r--r--crypto/src/math/raw/Nat448.cs2
7 files changed, 140 insertions, 123 deletions
diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs
index 1c0b928f7..079e673a8 100644
--- a/crypto/src/math/ec/rfc7748/X25519Field.cs
+++ b/crypto/src/math/ec/rfc7748/X25519Field.cs
@@ -333,6 +333,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
             z[9] &= M24;
         }
 
+        public static void Decode(byte[] x, int xOff, int[] z, int zOff)
+        {
+            Decode128(x, xOff, z, zOff);
+            Decode128(x, xOff + 16, z, zOff + 5);
+            z[zOff + 9] &= M24;
+        }
+
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         public static void Decode(ReadOnlySpan<byte> x, Span<int> z)
         {
diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs
index d812172bb..f3fe71114 100644
--- a/crypto/src/math/ec/rfc7748/X448Field.cs
+++ b/crypto/src/math/ec/rfc7748/X448Field.cs
@@ -265,6 +265,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
             Decode56(x, xOff + 49, z, 14);
         }
 
+        public static void Decode(byte[] x, int xOff, uint[] z, int zOff)
+        {
+            Decode56(x, xOff, z, zOff);
+            Decode56(x, xOff + 7, z, zOff + 2);
+            Decode56(x, xOff + 14, z, zOff + 4);
+            Decode56(x, xOff + 21, z, zOff + 6);
+            Decode56(x, xOff + 28, z, zOff + 8);
+            Decode56(x, xOff + 35, z, zOff + 10);
+            Decode56(x, xOff + 42, z, zOff + 12);
+            Decode56(x, xOff + 49, z, zOff + 14);
+        }
+
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         public static void Decode(ReadOnlySpan<byte> x, Span<uint> z)
         {
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index baacc75fa..cde61b621 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -62,10 +62,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         private static readonly uint[] P = { 0xFFFFFFEDU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU,
             0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU };
 
-        private static readonly uint[] Order8_y1 = { 0x706A17C7, 0x4FD84D3D, 0x760B3CBA, 0x0F67100D, 0xFA53202A,
-            0xC6CC392C, 0x77FDC74E, 0x7A03AC92 };
-        private static readonly uint[] Order8_y2 = { 0x8F95E826, 0xB027B2C2, 0x89F4C345, 0xF098EFF2, 0x05ACDFD5,
-            0x3933C6D3, 0x880238B1, 0x05FC536D };
+        private static readonly uint[] Order8_y1 = { 0x706A17C7U, 0x4FD84D3DU, 0x760B3CBAU, 0x0F67100DU, 0xFA53202AU,
+            0xC6CC392CU, 0x77FDC74EU, 0x7A03AC92U };
+        private static readonly uint[] Order8_y2 = { 0x8F95E826U, 0xB027B2C2U, 0x89F4C345U, 0xF098EFF2U, 0x05ACDFD5U,
+            0x3933C6D3U, 0x880238B1U, 0x05FC536DU };
 
         private static readonly int[] B_x = { 0x0325D51A, 0x018B5823, 0x007B2C95, 0x0304A92D, 0x00D2598E, 0x01D6DC5C,
             0x01388C7F, 0x013FEC0A, 0x029E6B72, 0x0042D26D };
@@ -148,10 +148,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Nat256.MulAddTo(u, v, t);
 
             byte[] result = new byte[ScalarBytes * 2];
-            for (int i = 0; i < t.Length; ++i)
-            {
-                Codec.Encode32(t[i], result, i * 4);
-            }
+            Codec.Encode32(t, 0, t.Length, result, 0);
             return Scalar25519.Reduce(result);
         }
 
@@ -179,16 +176,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return F.IsZero(t);
         }
 
-        private static int CheckPoint(int[] x, int[] y, int[] z)
+        private static int CheckPoint(PointAccum p)
         {
             int[] t = F.Create();
             int[] u = F.Create();
             int[] v = F.Create();
             int[] w = F.Create();
 
-            F.Sqr(x, u);
-            F.Sqr(y, v);
-            F.Sqr(z, w);
+            F.Sqr(p.x, u);
+            F.Sqr(p.y, v);
+            F.Sqr(p.z, w);
             F.Mul(u, v, t);
             F.Sub(v, u, v);
             F.Mul(v, w, v);
@@ -201,39 +198,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return F.IsZero(t);
         }
 
-        private static bool CheckPointOrderVar(ref PointAffine p)
-        {
-            Init(out PointAccum r);
-            ScalarMultOrderVar(ref p, ref r);
-            return NormalizeToNeutralElementVar(ref r);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static bool CheckPointVar(ReadOnlySpan<byte> p)
-        {
-            if ((Codec.Decode32(p[28..]) & 0x7FFFFFFFU) < P[7])
-                return true;
-            for (int i = CoordUints - 2; i >= 0; --i)
-            {
-                if (Codec.Decode32(p[(i * 4)..]) < P[i])
-                    return true;
-            }
-            return false;
-        }
-#else
-        private static bool CheckPointVar(byte[] p)
-        {
-            if ((Codec.Decode32(p, 28) & 0x7FFFFFFFU) < P[7])
-                return true;
-            for (int i = CoordUints - 2; i >= 0; --i)
-            {
-                if (Codec.Decode32(p, i * 4) < P[i])
-                    return true;
-            }
-            return false;
-        }
-#endif
-
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static bool CheckPointFullVar(ReadOnlySpan<byte> p)
         {
@@ -308,6 +272,39 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         }
 #endif
 
+        private static bool CheckPointOrderVar(ref PointAffine p)
+        {
+            Init(out PointAccum r);
+            ScalarMultOrderVar(ref p, ref r);
+            return NormalizeToNeutralElementVar(ref r);
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        private static bool CheckPointVar(ReadOnlySpan<byte> p)
+        {
+            if ((Codec.Decode32(p[28..]) & 0x7FFFFFFFU) < P[7])
+                return true;
+            for (int i = CoordUints - 2; i >= 0; --i)
+            {
+                if (Codec.Decode32(p[(i * 4)..]) < P[i])
+                    return true;
+            }
+            return false;
+        }
+#else
+        private static bool CheckPointVar(byte[] p)
+        {
+            if ((Codec.Decode32(p, 28) & 0x7FFFFFFFU) < P[7])
+                return true;
+            for (int i = CoordUints - 2; i >= 0; --i)
+            {
+                if (Codec.Decode32(p, i * 4) < P[i])
+                    return true;
+            }
+            return false;
+        }
+#endif
+
         private static byte[] Copy(byte[] buf, int off, int len)
         {
             byte[] result = new byte[len];
@@ -938,10 +935,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             F.Copy(u, 0, points[0].z, 0);
         }
 
-        private static bool IsNeutralElementVar(int[] x, int[] y)
-        {
-            return F.IsZeroVar(x) && F.IsOneVar(y);
-        }
+        //private static bool IsNeutralElementVar(int[] x, int[] y)
+        //{
+        //    return F.IsZeroVar(x) && F.IsOneVar(y);
+        //}
 
         private static bool IsNeutralElementVar(int[] x, int[] y, int[] z)
         {
@@ -1325,17 +1322,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 PointExtended[] points = new PointExtended[totalPoints];
                 Init(out PointTemp t);
 
-                Init(out PointAffine b);
-                F.Copy(B_x, 0, b.x, 0);
-                F.Copy(B_y, 0, b.y, 0);
+                Init(out PointAffine B);
+                F.Copy(B_x, 0, B.x, 0);
+                F.Copy(B_y, 0, B.y, 0);
 
-                PointPrecompute(ref b, points, 0, wnafPoints, ref t);
+                PointPrecompute(ref B, points, 0, wnafPoints, ref t);
 
-                Init(out PointAffine b128);
-                F.Copy(B128_x, 0, b128.x, 0);
-                F.Copy(B128_y, 0, b128.y, 0);
+                Init(out PointAffine B128);
+                F.Copy(B128_x, 0, B128.x, 0);
+                F.Copy(B128_y, 0, B128.y, 0);
 
-                PointPrecompute(ref b128, points, wnafPoints, wnafPoints, ref t);
+                PointPrecompute(ref B128, points, wnafPoints, wnafPoints, ref t);
 
                 Init(out PointAccum p);
                 F.Copy(B_x, 0, p.x, 0);
@@ -1627,7 +1624,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Init(out PointAccum p);
             ScalarMultBase(n, ref p);
 
-            if (0 == CheckPoint(p.x, p.y, p.z))
+            if (0 == CheckPoint(p))
                 throw new InvalidOperationException();
 
             F.Copy(p.y, 0, y, 0);
@@ -1644,7 +1641,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Init(out PointAccum p);
             ScalarMultBase(n, ref p);
 
-            if (0 == CheckPoint(p.x, p.y, p.z))
+            if (0 == CheckPoint(p))
                 throw new InvalidOperationException();
 
             F.Copy(p.y, y);
diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs
index d3a9caf4d..c592fcdcc 100644
--- a/crypto/src/math/ec/rfc8032/Ed448.cs
+++ b/crypto/src/math/ec/rfc8032/Ed448.cs
@@ -66,12 +66,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             0x02488762U, 0x016EB6BCU, 0x0693F467U };
 
         // 2^225 * B
-        private static readonly uint[] B225_x = { 0x06909ee2U, 0x01d7605cU, 0x0995ec8aU, 0x0fc4d970U, 0x0cf2b361U,
-            0x02d82e9dU, 0x01225f55U, 0x007f0ef6U, 0x0aee9c55U, 0x0a240c13U, 0x05627b54U, 0x0d449d1eU, 0x03a44575U,
-            0x007164a7U, 0x0bd4bd71U, 0x061a15fdU };
-        private static readonly uint[] B225_y = { 0x0d3a9fe4U, 0x030696b9U, 0x07e7e326U, 0x068308c7U, 0x0ce0b8c8U,
-            0x03ac222bU, 0x0304db8eU, 0x083ee319U, 0x05e5db0bU, 0x0eca503bU, 0x0b1c6539U, 0x078a8dceU, 0x02d256bcU,
-            0x04a8b05eU, 0x0bd9fd57U, 0x0a1c3cb8U };
+        private static readonly uint[] B225_x = { 0x06909EE2U, 0x01D7605CU, 0x0995EC8AU, 0x0FC4D970U, 0x0CF2B361U,
+            0x02D82E9DU, 0x01225F55U, 0x007F0EF6U, 0x0AEE9C55U, 0x0A240C13U, 0x05627B54U, 0x0D449D1EU, 0x03A44575U,
+            0x007164A7U, 0x0BD4BD71U, 0x061A15FDU };
+        private static readonly uint[] B225_y = { 0x0D3A9FE4U, 0x030696B9U, 0x07E7E326U, 0x068308C7U, 0x0CE0B8C8U,
+            0x03AC222BU, 0x0304DB8EU, 0x083EE319U, 0x05E5DB0BU, 0x0ECA503BU, 0x0B1C6539U, 0x078A8DCEU, 0x02D256BCU,
+            0x04A8B05EU, 0x0BD9FD57U, 0x0A1C3CB8U };
 
         private const int C_d = -39081;
 
@@ -117,10 +117,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Nat.MulAddTo(ScalarUints, u, v, t);
 
             byte[] result = new byte[ScalarBytes * 2];
-            for (int i = 0; i < t.Length; ++i)
-            {
-                Codec.Encode32(t[i], result, i * 4);
-            }
+            Codec.Encode32(t, 0, t.Length, result, 0);
             return Scalar448.Reduce(result);
         }
 
@@ -147,16 +144,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return F.IsZero(t);
         }
 
-        private static int CheckPoint(uint[] x, uint[] y, uint[] z)
+        private static int CheckPoint(PointProjective p)
         {
             uint[] t = F.Create();
             uint[] u = F.Create();
             uint[] v = F.Create();
             uint[] w = F.Create();
 
-            F.Sqr(x, u);
-            F.Sqr(y, v);
-            F.Sqr(z, w);
+            F.Sqr(p.x, u);
+            F.Sqr(p.y, v);
+            F.Sqr(p.z, w);
             F.Mul(u, v, t);
             F.Add(u, v, u);
             F.Mul(u, w, u);
@@ -169,47 +166,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return F.IsZero(t);
         }
 
-        private static bool CheckPointOrderVar(ref PointAffine p)
-        {
-            Init(out PointProjective r);
-            ScalarMultOrderVar(ref p, ref r);
-            return NormalizeToNeutralElementVar(ref r);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static bool CheckPointVar(ReadOnlySpan<byte> p)
-        {
-            if ((p[PointBytes - 1] & 0x7F) != 0x00)
-                return false;
-            if (Codec.Decode32(p[52..]) < P[13])
-                return true;
-
-            int last = p[28] == 0xFF ? 7 : 0;
-            for (int i = CoordUints - 2; i >= last; --i)
-            {
-                if (Codec.Decode32(p[(i * 4)..]) < P[i])
-                    return true;
-            }
-            return false;
-        }
-#else
-        private static bool CheckPointVar(byte[] p)
-        {
-            if ((p[PointBytes - 1] & 0x7F) != 0x00)
-                return false;
-            if (Codec.Decode32(p, 52) < P[13])
-                return true;
-
-            int last = p[28] == 0xFF ? 7 : 0;
-            for (int i = CoordUints - 2; i >= last; --i)
-            {
-                if (Codec.Decode32(p, i * 4) < P[i])
-                    return true;
-            }
-            return false;
-        }
-#endif
-
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static bool CheckPointFullVar(ReadOnlySpan<byte> p)
         {
@@ -282,6 +238,47 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         }
 #endif
 
+        private static bool CheckPointOrderVar(ref PointAffine p)
+        {
+            Init(out PointProjective r);
+            ScalarMultOrderVar(ref p, ref r);
+            return NormalizeToNeutralElementVar(ref r);
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        private static bool CheckPointVar(ReadOnlySpan<byte> p)
+        {
+            if ((p[PointBytes - 1] & 0x7F) != 0x00)
+                return false;
+            if (Codec.Decode32(p[52..]) < P[13])
+                return true;
+
+            int last = p[28] == 0xFF ? 7 : 0;
+            for (int i = CoordUints - 2; i >= last; --i)
+            {
+                if (Codec.Decode32(p[(i * 4)..]) < P[i])
+                    return true;
+            }
+            return false;
+        }
+#else
+        private static bool CheckPointVar(byte[] p)
+        {
+            if ((p[PointBytes - 1] & 0x7F) != 0x00)
+                return false;
+            if (Codec.Decode32(p, 52) < P[13])
+                return true;
+
+            int last = p[28] == 0xFF ? 7 : 0;
+            for (int i = CoordUints - 2; i >= last; --i)
+            {
+                if (Codec.Decode32(p, i * 4) < P[i])
+                    return true;
+            }
+            return false;
+        }
+#endif
+
         private static byte[] Copy(byte[] buf, int off, int len)
         {
             byte[] result = new byte[len];
@@ -336,6 +333,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
         private static void Dom4(IXof d, byte phflag, byte[] ctx)
         {
+            Debug.Assert(ctx != null);
+
             int n = Dom4Prefix.Length;
 
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
@@ -854,6 +853,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             F.Copy(u, 0, points[0].z, 0);
         }
 
+        //private static bool IsNeutralElementVar(uint[] x, uint[] y)
+        //{
+        //    return F.IsZeroVar(x) && F.IsOneVar(y);
+        //}
+
         private static bool IsNeutralElementVar(uint[] x, uint[] y, uint[] z)
         {
             return F.IsZeroVar(x) && F.AreEqualVar(y, z);
@@ -1486,7 +1490,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Init(out PointProjective p);
             ScalarMultBase(n, ref p);
 
-            if (0 == CheckPoint(p.x, p.y, p.z))
+            if (0 == CheckPoint(p))
                 throw new InvalidOperationException();
 
             F.Copy(p.x, 0, x, 0);
@@ -1503,7 +1507,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             Init(out PointProjective p);
             ScalarMultBase(n, ref p);
 
-            if (0 == CheckPoint(p.x, p.y, p.z))
+            if (0 == CheckPoint(p))
                 throw new InvalidOperationException();
 
             F.Copy(p.x, x);
diff --git a/crypto/src/math/ec/rfc8032/Scalar448.cs b/crypto/src/math/ec/rfc8032/Scalar448.cs
index 5840b05ec..4afe1d2d6 100644
--- a/crypto/src/math/ec/rfc8032/Scalar448.cs
+++ b/crypto/src/math/ec/rfc8032/Scalar448.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
     {
         internal const int Size = 14;
 
-        internal const int ScalarBytes = Size * 4 + 1;
+        private const int ScalarBytes = Size * 4 + 1;
 
         private const ulong M26UL = 0x03FFFFFFUL;
         private const ulong M28UL = 0x0FFFFFFFUL;
diff --git a/crypto/src/math/ec/rfc8032/ScalarUtilities.cs b/crypto/src/math/ec/rfc8032/ScalarUtilities.cs
index 3407c65c7..c70a4f2e8 100644
--- a/crypto/src/math/ec/rfc8032/ScalarUtilities.cs
+++ b/crypto/src/math/ec/rfc8032/ScalarUtilities.cs
@@ -158,17 +158,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #endif
         {
             int i = last;
-            if ((int)x[i] < (int)y[i])
-                return true;
-            if ((int)x[i] > (int)y[i])
-                return false;
-            while (--i >= 0)
+            do
             {
                 if (x[i] < y[i])
                     return true;
                 if (x[i] > y[i])
                     return false;
             }
+            while (--i >= 0);
             return false;
         }
 
diff --git a/crypto/src/math/raw/Nat448.cs b/crypto/src/math/raw/Nat448.cs
index 5189d8936..688f327a4 100644
--- a/crypto/src/math/raw/Nat448.cs
+++ b/crypto/src/math/raw/Nat448.cs
@@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Math.Raw
             Nat224.Mul(x, 7, y, 7, zz, 14);
 
             uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14);
-            uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0);
+            uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0U);
             c21 += Nat224.AddTo(zz, 21, zz, 14, c14);
 
             uint[] dx = Nat224.Create(), dy = Nat224.Create();