Example #1
0
 public bool IsSameAs(FastECPoint other)
 {
     if (this.IsInfinity != other.IsInfinity)
     {
         return(false);
     }
     if (this.IsInfinity)
     {
         return(true);
     }
     other = other.Normalize();
     return(new Bitsy.Core.FastInteger(this.X) == other.X && new Bitsy.Core.FastInteger(this.Y) == other.Y);
 }
Example #2
0
        public static bool ECCUnitTest()
        {
            Random random = new Random(104);
            int    n      = 8;
            bool   ok     = true;

            TimeSpan
                elapsedInvertFast = TimeSpan.Zero,
                elapsedInvertSlow = TimeSpan.Zero;

            byte[] randomBytes = new byte[16 * n];
            for (int i = 20; --i >= 0;)
            {
                ulong[] a0 = new ulong[n * 2]; a0[0] = 1UL;
                random.NextBytes(randomBytes);
                ulong[] x = Enumerable.Range(0, n * 2).Select(idx => idx >= n ? 0 : BitConverter.ToUInt64(randomBytes, idx * 8)).ToArray();
                random.NextBytes(randomBytes);
                ulong[] p = Enumerable.Range(0, n).Select(idx => BitConverter.ToUInt64(randomBytes, idx * 8)).ToArray();
                p[0] |= 1;
                GetDivMod(a0, p, n);
                GetDivMod(x, p, n);
                ulong[] a1 = a0.ToArray();
                ulong[] a2 = a0.ToArray();

                var fx = new FastInteger(x);
                var fp = new FastInteger(p);
                var f0 = new FastInteger(a0);
                if (fx.ToString() != x.ToBigInteger().ToString() || fp.ToString() != p.ToBigInteger().ToString() || f0.ToString() != a0.ToBigInteger().ToString())
                {
                    ok = false;
                }
                FastInteger idv = f0.DivideModulo(fx, fp);
                elapsedInvertFast += MeasureTime(() =>
                {
                    AsmX64Operations.DivideModuloPrime(a1, x, p, n);
                });
                elapsedInvertSlow += MeasureTime(() =>
                {
                    AsmX64Operations.DivideModPSlow(a2, x, p, n);
                });

                if (a1.ToBigInteger().ToString() != idv.ToString())
                {
                    ok = false;
                }

                ulong[] r1 = new ulong[n * 2];
                Multiply(a1, x, r1, n);
                GetDivMod(r1, p, n);

                ulong[] r2 = new ulong[n * 2];
                Multiply(a2, x, r2, n);
                GetDivMod(r2, p, n);

                if (!Enumerable.Range(0, n).All(idx => r1[idx] == r2[idx]))
                {
                    ok = false;
                }
            }

            TimeSpan
                elapsedExponentiationSlow      = TimeSpan.Zero,
                elapsedExponentiation521       = TimeSpan.Zero,
                elapsedExponentiationBigInt    = TimeSpan.Zero,
                elapsedExponentiationFastInt   = TimeSpan.Zero,
                elapsedExponentiationBigInt521 = TimeSpan.Zero,
                elapsedExponentiationFast      = TimeSpan.Zero;
            SECP256K1Base           ecc        = new SECP256K1Base();
            SECP521R1Base           ecc2       = new SECP521R1Base();
            ECCSecP256K1FastInteger fastEcc    = new ECCSecP256K1FastInteger();
            ECCSecP521R1            ecc521     = new ECCSecP521R1();

            random = new Random(105);
            OwnECPoint point    = ecc.G;
            OwnECPoint point521 = ecc2.G;

            ok          = ok && ecc.Verify(point);
            ok          = ok && ecc2.Verify(point521);
            ok          = ok && ecc2.UnitTest();
            randomBytes = new byte[ecc.N * 8];
            ECC other = new ECC();
            int ops   = 1;

            ulong[] order521 = ecc2.Order.ToArray();
            order521[0]--;
            for (int i = ops; --i >= 0;)
            {
                random.NextBytes(randomBytes);
                BigInteger orderInteger = randomBytes.ToBigInteger();
                ulong[]    order        = Enumerable.Range(0, ecc.N).Select(idx => BitConverter.ToUInt64(randomBytes, idx * 8)).ToArray();
                OwnECPoint point2       = ecc.MultiplyReference(point, order);
                OwnECPoint point3       = new OwnECPoint();
                OwnECPoint point521_O   = new OwnECPoint();
                ECPoint    point8_521   = null;
                elapsedExponentiation521 += MeasureTime(() =>
                {
                    point521_O = ecc2.MultiplyWithEndomorphism(point521, order521);
                });
                elapsedExponentiationBigInt521 += MeasureTime(() =>
                {
                    point8_521 = ecc521.ECMultiplication(order521.ToBigInteger());
                });
                ok = ok && point521_O.X.IsEqual(point521.X) && point521_O.Y.ToBigInteger() + point521.Y.ToBigInteger() == (BigInteger.One << 521) - BigInteger.One;
                ok = ok && point8_521.X == point521.X.ToBigInteger() && point8_521.Y + point521.Y.ToBigInteger() == (BigInteger.One << 521) - BigInteger.One;
                FastECPoint point6 = ecc.ECMultiplication(randomBytes.ToFastInteger());
                OwnECPoint  point4 = new OwnECPoint();
                ECPoint     point5 = null;
                ECPoint     point7 = null;
                elapsedExponentiationSlow += MeasureTime(() =>
                {
                    point3 = ecc.Multiply(point, order);
                });
                elapsedExponentiationFast += MeasureTime(() =>
                {
                    point4 = ecc.MultiplyWithEndomorphism(point, order);
                });
                elapsedExponentiationBigInt += MeasureTime(() =>
                {
                    point5 = other.ECMultiplication(orderInteger);
                });
                elapsedExponentiationFastInt += MeasureTime(() =>
                {
                    point7 = fastEcc.ECMultiplication(orderInteger);
                });
                ok &= ecc.Verify(point2);
                ok &= ecc.Verify(point3);
                ok &= ecc.Verify(point4);
                ok &= other.Verify(point5);

                if (!ok || !point2.IsSameAs(point3) || !point2.IsSameAs(point4) || !point2.IsSameAs(point5) ||
                    !point2.IsSameAs(point6) || !point2.IsSameAs(point7))
                {
                    ok = false;
                }
            }
            //MessageBox.Show(
            //    "secP521r1 ecc multiplication: " + elapsedExponentiation521.ToString() + " ops/sec = " + (ops / elapsedExponentiation521.TotalSeconds).ToString("N3") + "\r\n" +
            //    "P521R1 BigInt ecc multiplication: " + elapsedExponentiationBigInt521.ToString() + " ops/sec = " + (ops / elapsedExponentiationBigInt521.TotalSeconds).ToString("N3") + "\r\n" +
            //    "Fast ecc multiplication: " + elapsedExponentiationFast.ToString() + " ops/sec = " + (ops / elapsedExponentiationFast.TotalSeconds).ToString("N3") + "\r\n" +
            //    "BigInteger ecc multiplication: " + elapsedExponentiationBigInt.ToString() + " ops/sec = " + (ops / elapsedExponentiationBigInt.TotalSeconds).ToString("N3") + "\r\n" +
            //    "FastInteger ecc multiplication: " + elapsedExponentiationFastInt.ToString() + " ops/sec = " + (ops / elapsedExponentiationFastInt.TotalSeconds).ToString("N3") + "\r\n" +
            //    "Slow ecc multiplication: " + elapsedExponentiationSlow.ToString() + " ops/sec = " + (ops / elapsedExponentiationSlow.TotalSeconds).ToString("N3") + "\r\n", "Time",
            //     MessageBoxButtons.OK, MessageBoxIcon.Information);

            return(ok);
        }