summary refs log tree commit diff
path: root/crypto
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2014-01-25 20:52:28 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2014-01-25 20:52:28 +0700
commit0d360477865400dfe98e1aeade606d57e11def80 (patch)
tree3593e41ff9dd374c7c315bc90291a67cf262fb7f /crypto
parentChange F2m test curve to match Java version more clearly (diff)
downloadBouncyCastle.NET-ed25519-0d360477865400dfe98e1aeade606d57e11def80.tar.xz
Port latest Java fixes for lambda-projective and make it the default for F2m
Diffstat (limited to 'crypto')
-rw-r--r--crypto/src/math/ec/ECCurve.cs18
-rw-r--r--crypto/src/math/ec/ECPoint.cs142
2 files changed, 92 insertions, 68 deletions
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 832145e2e..9679fdb89 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -463,7 +463,7 @@ namespace Org.BouncyCastle.Math.EC
      */
     public class F2mCurve : ECCurve
     {
-        private const int F2M_DEFAULT_COORDS = COORD_AFFINE;
+        private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE;
 
         private static IFiniteField BuildField(int m, int k1, int k2, int k3)
         {
@@ -827,7 +827,12 @@ namespace Org.BouncyCastle.Math.EC
                 case COORD_LAMBDA_AFFINE:
                 case COORD_LAMBDA_PROJECTIVE:
                 {
-                    if (!X.IsZero)
+                    if (X.IsZero)
+                    {
+                        if (!Y.Square().Equals(B))
+                            throw new ArgumentException();
+                    }
+                    else
                     {
                         // Y becomes Lambda (X + Y/X) here
                         Y = Y.Divide(X).Add(X);
@@ -847,16 +852,11 @@ namespace Org.BouncyCastle.Math.EC
             int			yTilde,
             BigInteger	X1)
         {
-
             ECFieldElement xp = FromBigInteger(X1);
-            ECFieldElement yp = null;
+            ECFieldElement yp;
             if (xp.IsZero)
             {
-                yp = (F2mFieldElement)m_b;
-                for (int i = 0; i < m - 1; i++)
-                {
-                    yp = yp.Square();
-                }
+                yp = m_b.Sqrt();
             }
             else
             {
diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs
index 5dbffda09..67cbebcda 100644
--- a/crypto/src/math/ec/ECPoint.cs
+++ b/crypto/src/math/ec/ECPoint.cs
@@ -907,7 +907,7 @@ namespace Org.BouncyCastle.Math.EC
             bool			withCompression)
             : base(curve, x, y, withCompression)
         {
-            if ((x != null && y == null) || (x == null && y != null))
+            if ((x == null) != (y == null))
             {
                 throw new ArgumentException("Exactly one of the field elements is null");
             }
@@ -1118,7 +1118,12 @@ namespace Org.BouncyCastle.Math.EC
                 case ECCurve.COORD_LAMBDA_PROJECTIVE:
                 {
                     if (X1.IsZero)
+                    {
+                        if (X2.IsZero)
+                            return (F2mPoint)curve.Infinity;
+
                         return b.AddSimple(this);
+                    }
 
                     ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0);
                     ECFieldElement L2 = b.RawYCoord, Z2 = b.GetZCoord(0);
@@ -1156,13 +1161,21 @@ namespace Org.BouncyCastle.Math.EC
                     if (X2.IsZero)
                     {
                         // TODO This can probably be optimized quite a bit
+                        ECPoint p = this.Normalize();
+                        X1 = p.RawXCoord;
+                        ECFieldElement Y1 = p.YCoord;
 
-                        ECFieldElement Y1 = this.RawYCoord, Y2 = L2;
+                        ECFieldElement Y2 = L2;
                         ECFieldElement L = Y1.Add(Y2).Divide(X1);
 
                         X3 = L.Square().Add(L).Add(X1).Add(curve.A);
+                        if (X3.IsZero)
+                        {
+                            return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed);
+                        }
+
                         ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1);
-                        L3 = X3.IsZero ? Y3 : Y3.Divide(X3).Add(X3);
+                        L3 = Y3.Divide(X3).Add(X3);
                         Z3 = curve.FromBigInteger(BigInteger.One);
                     }
                     else
@@ -1171,13 +1184,19 @@ namespace Org.BouncyCastle.Math.EC
 
                         ECFieldElement AU1 = A.Multiply(U1);
                         ECFieldElement AU2 = A.Multiply(U2);
+
+                        X3 = AU1.Multiply(AU2);
+                        if (X3.IsZero)
+                        {
+                            return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed);
+                        }
+
                         ECFieldElement ABZ2 = A.Multiply(B);
                         if (!Z2IsOne)
                         {
                             ABZ2 = ABZ2.Multiply(Z2);
                         }
 
-                        X3 = AU1.Multiply(AU2);
                         L3 = AU2.Add(B).Square().Add(ABZ2.Multiply(L1.Add(Z1)));
 
                         Z3 = ABZ2;
@@ -1322,6 +1341,11 @@ namespace Org.BouncyCastle.Math.EC
                     ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq);
 
                     ECFieldElement X3 = T.Square();
+                    if (X3.IsZero)
+                    {
+                        return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed);
+                    }
+
                     ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq);
 
                     ECFieldElement b = curve.B;
@@ -1366,61 +1390,61 @@ namespace Org.BouncyCastle.Math.EC
             }
         }
 
-        public override ECPoint TwicePlus(ECPoint b)
-        {
-            if (this.IsInfinity)
-                return b;
-            if (b.IsInfinity)
-                return Twice();
-
-            ECCurve curve = this.Curve;
-
-            ECFieldElement X1 = this.RawXCoord;
-            if (X1.IsZero)
-            {
-                // A point with X == 0 is it's own additive inverse
-                return b;
-            }
-
-            int coord = curve.CoordinateSystem;
-
-            switch (coord)
-            {
-                case ECCurve.COORD_LAMBDA_PROJECTIVE:
-                {
-                    // NOTE: twicePlus() only optimized for lambda-affine argument
-                    ECFieldElement X2 = b.RawXCoord, Z2 = b.GetZCoord(0);
-                    if (X2.IsZero || !Z2.IsOne)
-                    {
-                        return Twice().Add(b);
-                    }
-
-                    ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0);
-                    ECFieldElement L2 = b.RawYCoord;
-
-                    ECFieldElement X1Sq = X1.Square();
-                    ECFieldElement L1Sq = L1.Square();
-                    ECFieldElement Z1Sq = Z1.Square();
-                    ECFieldElement L1Z1 = L1.Multiply(Z1);
-
-                    ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1);
-                    ECFieldElement L2plus1 = L2.AddOne();
-                    ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).Multiply(T).Add(X1Sq.Multiply(Z1Sq));
-                    ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq);
-                    ECFieldElement B = X2Z1Sq.Add(T).Square();
-
-                    ECFieldElement X3 = A.Square().Multiply(X2Z1Sq);
-                    ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq);
-                    ECFieldElement L3 = A.Add(B).Square().Multiply(T).Add(L2plus1.Multiply(Z3));
-
-                    return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
-                }
-                default:
-                {
-                    return Twice().Add(b);
-                }
-            }
-        }
+        //public override ECPoint TwicePlus(ECPoint b)
+        //{
+        //    if (this.IsInfinity)
+        //        return b;
+        //    if (b.IsInfinity)
+        //        return Twice();
+
+        //    ECCurve curve = this.Curve;
+
+        //    ECFieldElement X1 = this.RawXCoord;
+        //    if (X1.IsZero)
+        //    {
+        //        // A point with X == 0 is it's own additive inverse
+        //        return b;
+        //    }
+
+        //    int coord = curve.CoordinateSystem;
+
+        //    switch (coord)
+        //    {
+        //        case ECCurve.COORD_LAMBDA_PROJECTIVE:
+        //        {
+        //            // NOTE: twicePlus() only optimized for lambda-affine argument
+        //            ECFieldElement X2 = b.RawXCoord, Z2 = b.GetZCoord(0);
+        //            if (X2.IsZero || !Z2.IsOne)
+        //            {
+        //                return Twice().Add(b);
+        //            }
+
+        //            ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0);
+        //            ECFieldElement L2 = b.RawYCoord;
+
+        //            ECFieldElement X1Sq = X1.Square();
+        //            ECFieldElement L1Sq = L1.Square();
+        //            ECFieldElement Z1Sq = Z1.Square();
+        //            ECFieldElement L1Z1 = L1.Multiply(Z1);
+
+        //            ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1);
+        //            ECFieldElement L2plus1 = L2.AddOne();
+        //            ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).Multiply(T).Add(X1Sq.Multiply(Z1Sq));
+        //            ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq);
+        //            ECFieldElement B = X2Z1Sq.Add(T).Square();
+
+        //            ECFieldElement X3 = A.Square().Multiply(X2Z1Sq);
+        //            ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq);
+        //            ECFieldElement L3 = A.Add(B).Square().Multiply(T).Add(L2plus1.Multiply(Z3));
+
+        //            return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
+        //        }
+        //        default:
+        //        {
+        //            return Twice().Add(b);
+        //        }
+        //    }
+        //}
 
         public override ECPoint Negate()
         {