summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-02-06 10:40:10 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-02-06 10:40:10 +0700
commitb20b587c973e7e57384e5a11f2444a97fa26727a (patch)
treeede7853aae5762420bea4d15e88983608ce704bb
parentInitial work on the Curve25519 field implementation (diff)
downloadBouncyCastle.NET-ed25519-b20b587c973e7e57384e5a11f2444a97fa26727a.tar.xz
A few improvements to the fixed-point comb
-rw-r--r--crypto/src/math/ec/multiplier/FixedPointCombMultiplier.cs26
-rw-r--r--crypto/src/math/ec/multiplier/FixedPointUtilities.cs12
2 files changed, 28 insertions, 10 deletions
diff --git a/crypto/src/math/ec/multiplier/FixedPointCombMultiplier.cs b/crypto/src/math/ec/multiplier/FixedPointCombMultiplier.cs
index 51ed5d7c5..bbfe71a0d 100644
--- a/crypto/src/math/ec/multiplier/FixedPointCombMultiplier.cs
+++ b/crypto/src/math/ec/multiplier/FixedPointCombMultiplier.cs
@@ -7,23 +7,39 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
     {
         protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
         {
-            int width = 4;
+            ECCurve c = p.Curve;
+            int size = FixedPointUtilities.GetCombSize(c);
+
+            if (k.BitLength > size)
+            {
+                /*
+                 * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+                 * Still, if we want to handle larger scalars, we could allow customization of the comb
+                 * size, or alternatively we could deal with the 'extra' bits either by running the comb
+                 * multiple times as necessary, or by using an alternative multiplier as prelude.
+                 */
+                throw new InvalidOperationException("fixed-point comb doesn't support scalars larger than the curve order");
+            }
+
+            // TODO Call method to let subclasses select width
+            int width = size > 257 ? 6 : 5;
 
             FixedPointPreCompInfo info = FixedPointUtilities.Precompute(p, width);
             ECPoint[] lookupTable = info.PreComp;
 
-            ECCurve c = p.Curve;
             int d = (c.Order.BitLength + width - 1) / width;
 
             ECPoint R = c.Infinity;
 
-            for (int i = d - 1; i >= 0; --i)
+            int top = d * width - 1;
+            for (int i = 0; i < d; ++i)
             {
                 int index = 0;
-                for (int j = width - 1; j >= 0; --j)
+
+                for (int j = top - i; j >= 0; j -= d)
                 {
                     index <<= 1;
-                    if (k.TestBit(j * d + i))
+                    if (k.TestBit(j))
                     {
                         index |= 1;
                     }
diff --git a/crypto/src/math/ec/multiplier/FixedPointUtilities.cs b/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
index ddce74d31..8a04fcdc1 100644
--- a/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
+++ b/crypto/src/math/ec/multiplier/FixedPointUtilities.cs
@@ -4,6 +4,12 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
 {
     public class FixedPointUtilities
     {
+        public static int GetCombSize(ECCurve c)
+        {
+            BigInteger order = c.Order;
+            return order == null ? c.FieldSize + 1 : order.BitLength;
+        }
+
         public static FixedPointPreCompInfo GetFixedPointPreCompInfo(PreCompInfo preCompInfo)
         {
             if ((preCompInfo != null) && (preCompInfo is FixedPointPreCompInfo))
@@ -24,11 +30,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
 
             if (lookupTable == null || lookupTable.Length != n)
             {
-                BigInteger order = c.Order;
-                if (order == null)
-                    throw new InvalidOperationException("fixed-point precomputation needs the curve order");
-
-                int bits = order.BitLength;
+                int bits = GetCombSize(c);
                 int d = (bits + width - 1) / width;
 
                 ECPoint[] pow2Table = new ECPoint[width];