Ejemplo n.º 1
0
 public void SquareModP(ulong[] inputOutput)
 {
     AsmX64Operations.KaratsubaSquare(inputOutput, temporary2x, N, temporaryKaratsubaBuffer);
     this.GetModFriendlyPrime(temporary2x);
     for (int i = N; --i >= 0;)
     {
         inputOutput[i] = temporary2x[i];
     }
 }
Ejemplo n.º 2
0
        public static bool UnitTest()
        {
            Random random = new Random(101);
            int    n      = 2048 / 64;

            ulong[] a   = new ulong[n];
            ulong[] b   = new ulong[n];
            ulong[] m   = new ulong[n];
            ulong[] am1 = new ulong[n];
            ulong[] am3 = new ulong[n];
            ulong[] c1  = new ulong[n * 2];
            ulong[] c2  = new ulong[n * 2];
            ulong[] c3  = new ulong[n * 2];
            ulong[] s0  = new ulong[n * 2];
            ulong[] s1  = new ulong[n * 2];
            ulong[] s2  = new ulong[n * 2];

            BigInteger a0, b0, m0;

            TimeSpan
                elapsedMontgomeryExpMod = TimeSpan.Zero,
                elapsedExpMod           = TimeSpan.Zero,
                elapsedBigIntegerExpMod = TimeSpan.Zero;
            bool ok = true;

            for (int iteration = 1; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                getRandom(m, random); m[0] &= ulong.MaxValue - 1;
                a0 = new BigInteger(a.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                b0 = new BigInteger(b.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());
                m0 = new BigInteger(m.SelectMany(l => BitConverter.GetBytes(l)).Concat(Enumerable.Repeat((byte)0, 1)).ToArray());

                a.CopyTo(am1, 0);
                ExpMod(am1, b, m, n, 5);

                BigInteger am2 = BigInteger.Zero;
                elapsedBigIntegerExpMod += MeasureTime(() =>
                {
                    am2 = BigInteger.ModPow(a0, b0, m0);
                });
                var bytes1 = am1.SelectMany(l => BitConverter.GetBytes(l)).ToArray();
                var bytes2 = am2.ToByteArray();
                ok &= Enumerable.Range(0, Math.Min(bytes1.Length, bytes2.Length)).All(idx => bytes1[idx] == bytes2[idx]);
            }

            for (int iteration = 1; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                getRandom(m, random); m[0] |= 1;
                a.CopyTo(am1, 0);
                a.CopyTo(am3, 0);

                elapsedMontgomeryExpMod += MeasureTime(() =>
                {
                    MontgomeryExpMod(am1, b, m, n, 6);
                });
                elapsedExpMod += MeasureTime(() =>
                {
                    ExpMod(am3, b, m, n, 5);
                });

                ok &= Enumerable.Range(0, n).All(idx => am3[idx] == am1[idx]);
            }

            TimeSpan
                elapsedMulDirect = TimeSpan.Zero,
                elapsedKaratsuba = TimeSpan.Zero;

            ulong[] temporaryKaratsubaBuffer = new ulong[GetKaratsubaMultiplicationBufferSize(n)];
            for (int iteration = 128; --iteration >= 0;)
            {
                getRandom(a, random);
                getRandom(b, random);
                AsmX64Operations.Multiply(a, a, s0, n);

                elapsedMulDirect += MeasureTime(() =>
                {
                    AsmX64Operations.Multiply(a, b, c1, n);
                    AsmX64Operations.Square(a, s1, n);
                });
                elapsedKaratsuba += MeasureTime(() =>
                {
                    AsmX64Operations.Karatsuba(a, b, c2, n, temporaryKaratsubaBuffer);
                    AsmX64Operations.KaratsubaSquare(a, s2, n, temporaryKaratsubaBuffer);
                });

                ok &= Enumerable.Range(0, n * 2).All(idx => c1[idx] == c2[idx]);
                ok &= Enumerable.Range(0, n * 2).All(idx => s0[idx] == s1[idx]);
                ok &= Enumerable.Range(0, n * 2).All(idx => s1[idx] == s2[idx]);
            }
            if (!ok)
            {
                //MessageBox.Show("not ok - error");
                return(false);
            }
            //MessageBox.Show(
            //    "elapsedMontgomeryExpMod: " + elapsedMontgomeryExpMod.ToString() + "\r\n" +
            //    "elapsedExpMod: " + elapsedExpMod.ToString() + "\r\n" +
            //    "elapsedBigIntegerExpMod: " + elapsedBigIntegerExpMod.ToString() + "\r\n" +
            //    "normal: " + elapsedMulDirect.ToString() + "  karatsuba: " + elapsedKaratsuba.ToString());
            return(true);
        }