summary refs log tree commit diff
path: root/crypto/test
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-08-01 15:37:31 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-08-01 15:37:31 +0700
commitb33a7ee2cf9e46eab44f521387df3c92c9d45842 (patch)
tree52e9de32e7aedc80f87b4d4295947c5e42ecfa14 /crypto/test
parentFix warnings (diff)
downloadBouncyCastle.NET-ed25519-b33a7ee2cf9e46eab44f521387df3c92c9d45842.tar.xz
EC updates from bc-java
- use half-trace when possible (odd m) for decompression/validation
- provide field-specific half-trace methods for custom curves
- clarify the logic of point-order testing for binary curves
- expand test cases for invalid points
Diffstat (limited to 'crypto/test')
-rw-r--r--crypto/test/src/math/ec/test/ECPointTest.cs145
1 files changed, 138 insertions, 7 deletions
diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs
index dbd739023..e1a2b8a6a 100644
--- a/crypto/test/src/math/ec/test/ECPointTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointTest.cs
@@ -5,9 +5,11 @@ using NUnit.Framework;
 
 using Org.BouncyCastle.Asn1.X9;
 using Org.BouncyCastle.Crypto.EC;
+using Org.BouncyCastle.Math.EC.Multiplier;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
+using Org.BouncyCastle.Utilities.Encoders;
 
 namespace Org.BouncyCastle.Math.EC.Tests
 {
@@ -399,10 +401,15 @@ namespace Org.BouncyCastle.Math.EC.Tests
             ImplTestMultiply(q, n.BitLength);
             ImplTestMultiply(infinity, n.BitLength);
 
+            int logSize = 32 - Integers.NumberOfLeadingZeros(curve.FieldSize - 1);
+            int rounds = System.Math.Max(2, System.Math.Min(10, 32 - 3 * logSize));
+
             ECPoint p = q;
-            for (int i = 0; i < 10; ++i)
+            for (int i = 0; ; )
             {
                 ImplTestEncoding(p);
+                if (++i == rounds)
+                    break;
                 p = p.Twice();
             }
         }
@@ -446,14 +453,42 @@ namespace Org.BouncyCastle.Math.EC.Tests
         {
             Assert.IsTrue(g.IsValid());
 
-            BigInteger h = c.Cofactor;
-            if (h != null && h.CompareTo(BigInteger.One) > 0)
+            if (ECAlgorithms.IsF2mCurve(c))
             {
-                if (ECAlgorithms.IsF2mCurve(c))
+                BigInteger h = c.Cofactor;
+                if (null != h)
                 {
-                    ECPoint order2 = c.CreatePoint(BigInteger.Zero, c.B.Sqrt().ToBigInteger());
-                    ECPoint bad = g.Add(order2);
-                    Assert.IsFalse(bad.IsValid());
+                    if (!h.TestBit(0))
+                    {
+                        ECFieldElement sqrtB = c.B.Sqrt();
+                        ECPoint order2 = c.CreatePoint(BigInteger.Zero, sqrtB.ToBigInteger());
+                        Assert.IsTrue(order2.Twice().IsInfinity);
+                        Assert.IsFalse(order2.IsValid());
+                        ECPoint bad2 = g.Add(order2);
+                        Assert.IsFalse(bad2.IsValid());
+                        ECPoint good2 = bad2.Add(order2);
+                        Assert.IsTrue(good2.IsValid());
+
+                        if (!h.TestBit(1))
+                        {
+                            ECFieldElement L = SolveQuadraticEquation(c, c.A);
+                            Assert.IsNotNull(L);
+                            ECFieldElement T = sqrtB;
+                            ECFieldElement x = T.Sqrt();
+                            ECFieldElement y = T.Add(x.Multiply(L));
+                            ECPoint order4 = c.CreatePoint(x.ToBigInteger(), y.ToBigInteger());
+                            Assert.IsTrue(order4.Twice().Equals(order2));
+                            Assert.IsFalse(order4.IsValid());
+                            ECPoint bad4_1 = g.Add(order4);
+                            Assert.IsFalse(bad4_1.IsValid());
+                            ECPoint bad4_2 = bad4_1.Add(order4);
+                            Assert.IsFalse(bad4_2.IsValid());
+                            ECPoint bad4_3 = bad4_2.Add(order4);
+                            Assert.IsFalse(bad4_3.IsValid());
+                            ECPoint good4 = bad4_3.Add(order4);
+                            Assert.IsTrue(good4.IsValid());
+                        }
+                    }
                 }
             }
         }
@@ -543,6 +578,55 @@ namespace Org.BouncyCastle.Math.EC.Tests
             }
         }
 
+        [Test]
+        public void TestExampleFpB0()
+        {
+            /*
+             * The supersingular curve y^2 = x^3 - 3.x (i.e. with 'B' == 0) from RFC 6508 2.1, with
+             * curve parameters from RFC 6509 Appendix A.
+             */
+            BigInteger p = FromHex(
+                  "997ABB1F0A563FDA65C61198DAD0657A"
+                + "416C0CE19CB48261BE9AE358B3E01A2E"
+                + "F40AAB27E2FC0F1B228730D531A59CB0"
+                + "E791B39FF7C88A19356D27F4A666A6D0"
+                + "E26C6487326B4CD4512AC5CD65681CE1"
+                + "B6AFF4A831852A82A7CF3C521C3C09AA"
+                + "9F94D6AF56971F1FFCE3E82389857DB0"
+                + "80C5DF10AC7ACE87666D807AFEA85FEB");
+            BigInteger a = p.Subtract(BigInteger.ValueOf(3));
+            BigInteger b = BigInteger.Zero;
+            byte[] S = null;
+            BigInteger n = p.Add(BigInteger.One).ShiftRight(2);
+            BigInteger h = BigInteger.ValueOf(4);
+
+            ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h));
+
+            X9ECPoint G = ConfigureBasepoint(curve, "04"
+                // Px
+                + "53FC09EE332C29AD0A7990053ED9B52A"
+                + "2B1A2FD60AEC69C698B2F204B6FF7CBF"
+                + "B5EDB6C0F6CE2308AB10DB9030B09E10"
+                + "43D5F22CDB9DFA55718BD9E7406CE890"
+                + "9760AF765DD5BCCB337C86548B72F2E1"
+                + "A702C3397A60DE74A7C1514DBA66910D"
+                + "D5CFB4CC80728D87EE9163A5B63F73EC"
+                + "80EC46C4967E0979880DC8ABEAE63895"
+                // Py
+                + "0A8249063F6009F1F9F1F0533634A135"
+                + "D3E82016029906963D778D821E141178"
+                + "F5EA69F4654EC2B9E7F7F5E5F0DE55F6"
+                + "6B598CCF9A140B2E416CFF0CA9E032B9"
+                + "70DAE117AD547C6CCAD696B5B7652FE0"
+                + "AC6F1E80164AA989492D979FC5A4D5F2"
+                + "13515AD7E9CB99A980BDAD5AD5BB4636"
+                + "ADB9B5706A67DCDE75573FD71BEF16D7");
+
+            X9ECParameters x9 = new X9ECParameters(curve, G, n, h, S);
+
+            ImplAddSubtractMultiplyTwiceEncodingTestAllCoords(x9);
+        }
+
         private void AssertPointsEqual(string message, ECPoint a, ECPoint b)
         {
             // NOTE: We intentionally test points for equality in both directions
@@ -565,5 +649,52 @@ namespace Org.BouncyCastle.Math.EC.Tests
                 Assert.IsTrue(Arrays.AreEqual(a, b));
             }
         }
+
+        private static X9ECPoint ConfigureBasepoint(ECCurve curve, string encoding)
+        {
+            X9ECPoint G = new X9ECPoint(curve, Hex.Decode(encoding));
+            //WNafUtilities.ConfigureBasepoint(G.Point);
+            return G;
+        }
+
+        private static ECCurve ConfigureCurve(ECCurve curve)
+        {
+            return curve;
+        }
+
+        private static BigInteger FromHex(string hex)
+        {
+            return new BigInteger(1, Hex.Decode(hex));
+        }
+
+        private static ECFieldElement SolveQuadraticEquation(ECCurve c, ECFieldElement rhs)
+        {
+            if (rhs.IsZero)
+                return rhs;
+
+            ECFieldElement gamma, z, zeroElement = c.FromBigInteger(BigInteger.Zero);
+
+            int m = c.FieldSize;
+            do
+            {
+                ECFieldElement t = c.FromBigInteger(BigInteger.Arbitrary(m));
+                z = zeroElement;
+                ECFieldElement w = rhs;
+                for (int i = 1; i < m; i++)
+                {
+                    ECFieldElement w2 = w.Square();
+                    z = z.Square().Add(w2.Multiply(t));
+                    w = w2.Add(rhs);
+                }
+                if (!w.IsZero)
+                {
+                    return null;
+                }
+                gamma = z.Square().Add(z);
+            }
+            while (gamma.IsZero);
+
+            return z;
+        }
     }
 }