summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-08-04 19:07:38 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-08-04 19:07:38 +0700
commit022f35026b1945d81c4750cf80626685148ceb35 (patch)
treec29aedda9f8e084270b879f9b166658d038b7eee
parentImplement promotion for ECPoint precomputations (diff)
downloadBouncyCastle.NET-ed25519-022f35026b1945d81c4750cf80626685148ceb35.tar.xz
EdDSA refactoring
- tighten scalar bounds for wNAF
- provide CMov in field classes
- fix spelling of Straus
-rw-r--r--crypto/src/math/ec/rfc7748/X25519Field.cs14
-rw-r--r--crypto/src/math/ec/rfc7748/X448Field.cs20
-rw-r--r--crypto/src/math/ec/rfc8032/Ed25519.cs24
-rw-r--r--crypto/src/math/ec/rfc8032/Ed448.cs22
4 files changed, 46 insertions, 34 deletions
diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs
index b5938e2e7..3a06941dd 100644
--- a/crypto/src/math/ec/rfc7748/X25519Field.cs
+++ b/crypto/src/math/ec/rfc7748/X25519Field.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
         private static readonly int[] RootNegOne = { 0x020EA0B0, 0x0386C9D2, 0x00478C4E, 0x0035697F, 0x005E8630,
             0x01FBD7A7, 0x0340264F, 0x01F0B2B4, 0x00027E0E, 0x00570649 };
 
-        private X25519Field() {}
+        protected X25519Field() {}
 
         public static void Add(int[] x, int[] y, int[] z)
         {
@@ -67,6 +67,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
             z[5] = z5; z[6] = z6; z[7] = z7; z[8] = z8; z[9] = z9;
         }
 
+        public static void CMov(int cond, int[] x, int xOff, int[] z, int zOff)
+        {
+            Debug.Assert(0 == cond || -1 == cond);
+
+            for (int i = 0; i < Size; ++i)
+            {
+                int z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
+                z_i ^= (diff & cond);
+                z[zOff + i] = z_i;
+            }
+        }
+
         public static void CNegate(int negate, int[] z)
         {
             Debug.Assert(negate >> 1 == 0);
diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs
index 7cda6ebcc..f1e89e520 100644
--- a/crypto/src/math/ec/rfc7748/X448Field.cs
+++ b/crypto/src/math/ec/rfc7748/X448Field.cs
@@ -1,8 +1,6 @@
 using System;
 using System.Diagnostics;
 
-using Org.BouncyCastle.Math.Raw;
-
 namespace Org.BouncyCastle.Math.EC.Rfc7748
 {
     [CLSCompliantAttribute(false)]
@@ -12,7 +10,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
 
         private const uint M28 = 0x0FFFFFFFU;
 
-        private X448Field() {}
+        protected X448Field() {}
 
         public static void Add(uint[] x, uint[] y, uint[] z)
         {
@@ -74,6 +72,20 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
             z[8] = z8; z[9] = z9; z[10] = z10; z[11] = z11; z[12] = z12; z[13] = z13; z[14] = z14; z[15] = z15;
         }
 
+        public static void CMov(int cond, uint[] x, int xOff, uint[] z, int zOff)
+        {
+            Debug.Assert(0 == cond || -1 == cond);
+
+            uint MASK = (uint)cond;
+
+            for (int i = 0; i < Size; ++i)
+            {
+                uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i];
+                z_i ^= (diff & MASK);
+                z[zOff + i] = z_i;
+            }
+        }
+
         public static void CNegate(int negate, uint[] z)
         {
             Debug.Assert(negate >> 1 == 0);
@@ -81,7 +93,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748
             uint[] t = Create();
             Sub(t, z, t);
 
-            Nat.CMov(Size, negate, t, 0, z, 0);
+            CMov(-negate, t, 0, z, 0);
         }
 
         public static void Copy(uint[] x, int xOff, uint[] z, int zOff)
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index 702c48dd3..b798bdf2d 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -270,7 +270,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
         private static sbyte[] GetWnaf(uint[] n, int width)
         {
-            Debug.Assert(n[ScalarUints - 1] >> 31 == 0);
+            Debug.Assert(n[ScalarUints - 1] >> 28 == 0);
 
             uint[] t = new uint[ScalarUints * 2];
             {
@@ -284,7 +284,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 }
             }
 
-            sbyte[] ws = new sbyte[256];
+            sbyte[] ws = new sbyte[253];
 
             uint pow2 = 1U << width;
             uint mask = pow2 - 1U;
@@ -423,7 +423,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             DecodeScalar(k, 0, nA);
 
             PointAccum pR = new PointAccum();
-            ScalarMultStraussVar(nS, nA, pA, pR);
+            ScalarMultStrausVar(nS, nA, pA, pR);
 
             byte[] check = new byte[PointBytes];
             EncodePoint(pR, check, 0);
@@ -597,10 +597,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             for (int i = 0; i < PrecompPoints; ++i)
             {
-                int mask = ((i ^ index) - 1) >> 31;
-                Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ypx_h, 0); off += X25519Field.Size;
-                Nat.CMov(X25519Field.Size, mask, precompBase, off, p.ymx_h, 0); off += X25519Field.Size;
-                Nat.CMov(X25519Field.Size, mask, precompBase, off, p.xyd, 0);   off += X25519Field.Size;
+                int cond = ((i ^ index) - 1) >> 31;
+                X25519Field.CMov(cond, precompBase, off, p.ypx_h, 0);   off += X25519Field.Size;
+                X25519Field.CMov(cond, precompBase, off, p.ymx_h, 0);   off += X25519Field.Size;
+                X25519Field.CMov(cond, precompBase, off, p.xyd, 0);     off += X25519Field.Size;
             }
         }
 
@@ -945,7 +945,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             X25519Field.Copy(p.z, 0, z, 0);
         }
 
-        private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointAccum r)
+        private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointAccum r)
         {
             Precompute();
 
@@ -958,13 +958,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             PointSetNeutral(r);
 
-            int bit = 255;
-            while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0)
-            {
-                --bit;
-            }
-
-            for (; ; )
+            for (int bit = 252;;)
             {
                 int wb = ws_b[bit];
                 if (wb != 0)
diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs
index 597062269..842839396 100644
--- a/crypto/src/math/ec/rfc8032/Ed448.cs
+++ b/crypto/src/math/ec/rfc8032/Ed448.cs
@@ -279,7 +279,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
         private static sbyte[] GetWnaf(uint[] n, int width)
         {
-            Debug.Assert(n[ScalarUints - 1] >> 31 == 0U);
+            Debug.Assert(n[ScalarUints - 1] >> 30 == 0U);
 
             uint[] t = new uint[ScalarUints * 2];
             {
@@ -293,7 +293,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 }
             }
 
-            sbyte[] ws = new sbyte[448];
+            sbyte[] ws = new sbyte[447];
 
             uint pow2 = 1U << width;
             uint mask = pow2 - 1U;
@@ -432,7 +432,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             DecodeScalar(k, 0, nA);
 
             PointExt pR = new PointExt();
-            ScalarMultStraussVar(nS, nA, pA, pR);
+            ScalarMultStrausVar(nS, nA, pA, pR);
 
             byte[] check = new byte[PointBytes];
             EncodePoint(pR, check, 0);
@@ -568,9 +568,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             for (int i = 0; i < PrecompPoints; ++i)
             {
-                int mask = ((i ^ index) - 1) >> 31;
-                Nat.CMov(X448Field.Size, mask, precompBase, off, p.x, 0);   off += X448Field.Size;
-                Nat.CMov(X448Field.Size, mask, precompBase, off, p.y, 0);   off += X448Field.Size;
+                int cond = ((i ^ index) - 1) >> 31;
+                X448Field.CMov(cond, precompBase, off, p.x, 0);     off += X448Field.Size;
+                X448Field.CMov(cond, precompBase, off, p.y, 0);     off += X448Field.Size;
             }
         }
 
@@ -1032,7 +1032,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             X448Field.Copy(p.y, 0, y, 0);
         }
 
-        private static void ScalarMultStraussVar(uint[] nb, uint[] np, PointExt p, PointExt r)
+        private static void ScalarMultStrausVar(uint[] nb, uint[] np, PointExt p, PointExt r)
         {
             Precompute();
 
@@ -1045,13 +1045,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             PointSetNeutral(r);
 
-            int bit = 447;
-            while (bit > 0 && ((byte)ws_b[bit] | (byte)ws_p[bit]) == 0)
-            {
-                --bit;
-            }
-
-            for (;;)
+            for (int bit = 446;;)
             {
                 int wb = ws_b[bit];
                 if (wb != 0)