summary refs log tree commit diff
path: root/crypto/src/math/ec/ECAlgorithms.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-01-22 11:40:05 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-01-22 11:40:05 +0700
commit73cb18129e632b44ddae7f9c589fd9c17c77d3ca (patch)
treecbe867e5538f2a9d37f3eadb49a4104a64261971 /crypto/src/math/ec/ECAlgorithms.cs
parentImplement TwicePlus optimization in Fp curves (diff)
downloadBouncyCastle.NET-ed25519-73cb18129e632b44ddae7f9c589fd9c17c77d3ca.tar.xz
Use new Math.Field classes in EC curves, and avoid casting in client code
Diffstat (limited to 'crypto/src/math/ec/ECAlgorithms.cs')
-rw-r--r--crypto/src/math/ec/ECAlgorithms.cs170
1 files changed, 91 insertions, 79 deletions
diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs
index be4fd1b14..06288132b 100644
--- a/crypto/src/math/ec/ECAlgorithms.cs
+++ b/crypto/src/math/ec/ECAlgorithms.cs
@@ -1,93 +1,105 @@
 using System;
 
-using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.Field;
 
 namespace Org.BouncyCastle.Math.EC
 {
-	public class ECAlgorithms
-	{
-		public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a,
-			ECPoint Q, BigInteger b)
-		{
-			ECCurve c = P.Curve;
-			if (!c.Equals(Q.Curve))
-				throw new ArgumentException("P and Q must be on same curve");
+    public class ECAlgorithms
+    {
+        public static bool IsF2mCurve(ECCurve c)
+        {
+            IFiniteField field = c.Field;
+            return field.Dimension > 1 && field.Characteristic.Equals(BigInteger.Two)
+                && field is IPolynomialExtensionField;
+        }
 
-			// Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
-			if (c is F2mCurve)
-			{
-				F2mCurve f2mCurve = (F2mCurve) c;
-				if (f2mCurve.IsKoblitz)
-				{
-					return P.Multiply(a).Add(Q.Multiply(b));
-				}
-			}
+        public static bool IsFpCurve(ECCurve c)
+        {
+            return c.Field.Dimension == 1;
+        }
 
-			return ImplShamirsTrick(P, a, Q, b);
-		}
+        public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a,
+            ECPoint Q, BigInteger b)
+        {
+            ECCurve c = P.Curve;
+            if (!c.Equals(Q.Curve))
+                throw new ArgumentException("P and Q must be on same curve");
 
-		/*
-		* "Shamir's Trick", originally due to E. G. Straus
-		* (Addition chains of vectors. American Mathematical Monthly,
-		* 71(7):806-808, Aug./Sept. 1964)
-		*  
-		* Input: The points P, Q, scalar k = (km?, ... , k1, k0)
-		* and scalar l = (lm?, ... , l1, l0).
-		* Output: R = k * P + l * Q.
-		* 1: Z <- P + Q
-		* 2: R <- O
-		* 3: for i from m-1 down to 0 do
-		* 4:        R <- R + R        {point doubling}
-		* 5:        if (ki = 1) and (li = 0) then R <- R + P end if
-		* 6:        if (ki = 0) and (li = 1) then R <- R + Q end if
-		* 7:        if (ki = 1) and (li = 1) then R <- R + Z end if
-		* 8: end for
-		* 9: return R
-		*/
-		public static ECPoint ShamirsTrick(
-			ECPoint		P,
-			BigInteger	k,
-			ECPoint		Q,
-			BigInteger	l)
-		{
-			if (!P.Curve.Equals(Q.Curve))
-				throw new ArgumentException("P and Q must be on same curve");
+            // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
+            if (c is F2mCurve)
+            {
+                F2mCurve f2mCurve = (F2mCurve) c;
+                if (f2mCurve.IsKoblitz)
+                {
+                    return P.Multiply(a).Add(Q.Multiply(b));
+                }
+            }
 
-			return ImplShamirsTrick(P, k, Q, l);
-		}
+            return ImplShamirsTrick(P, a, Q, b);
+        }
 
-		private static ECPoint ImplShamirsTrick(ECPoint P, BigInteger k,
-			ECPoint Q, BigInteger l)
-		{
-			int m = System.Math.Max(k.BitLength, l.BitLength);
-			ECPoint Z = P.Add(Q);
-			ECPoint R = P.Curve.Infinity;
+        /*
+        * "Shamir's Trick", originally due to E. G. Straus
+        * (Addition chains of vectors. American Mathematical Monthly,
+        * 71(7):806-808, Aug./Sept. 1964)
+        *  
+        * Input: The points P, Q, scalar k = (km?, ... , k1, k0)
+        * and scalar l = (lm?, ... , l1, l0).
+        * Output: R = k * P + l * Q.
+        * 1: Z <- P + Q
+        * 2: R <- O
+        * 3: for i from m-1 down to 0 do
+        * 4:        R <- R + R        {point doubling}
+        * 5:        if (ki = 1) and (li = 0) then R <- R + P end if
+        * 6:        if (ki = 0) and (li = 1) then R <- R + Q end if
+        * 7:        if (ki = 1) and (li = 1) then R <- R + Z end if
+        * 8: end for
+        * 9: return R
+        */
+        public static ECPoint ShamirsTrick(
+            ECPoint		P,
+            BigInteger	k,
+            ECPoint		Q,
+            BigInteger	l)
+        {
+            if (!P.Curve.Equals(Q.Curve))
+                throw new ArgumentException("P and Q must be on same curve");
 
-			for (int i = m - 1; i >= 0; --i)
-			{
-				R = R.Twice();
+            return ImplShamirsTrick(P, k, Q, l);
+        }
 
-				if (k.TestBit(i))
-				{
-					if (l.TestBit(i))
-					{
-						R = R.Add(Z);
-					}
-					else
-					{
-						R = R.Add(P);
-					}
-				}
-				else
-				{
-					if (l.TestBit(i))
-					{
-						R = R.Add(Q);
-					}
-				}
-			}
+        private static ECPoint ImplShamirsTrick(ECPoint P, BigInteger k,
+            ECPoint Q, BigInteger l)
+        {
+            int m = System.Math.Max(k.BitLength, l.BitLength);
+            ECPoint Z = P.Add(Q);
+            ECPoint R = P.Curve.Infinity;
 
-			return R;
-		}
-	}
+            for (int i = m - 1; i >= 0; --i)
+            {
+                R = R.Twice();
+
+                if (k.TestBit(i))
+                {
+                    if (l.TestBit(i))
+                    {
+                        R = R.Add(Z);
+                    }
+                    else
+                    {
+                        R = R.Add(P);
+                    }
+                }
+                else
+                {
+                    if (l.TestBit(i))
+                    {
+                        R = R.Add(Q);
+                    }
+                }
+            }
+
+            return R;
+        }
+    }
 }