예제 #1
0
 public void TestOrderFinder(IOrderFinder orderFinder)
 {
     for (long n = 2; n < 500; n++)
     {
         for (long a = 1; a < n; a++)
         {
             if (MathUtils.GCD(a, n) != 1)
             {
                 continue;
             }
             long res = orderFinder.Find(a, n);
             if (MathUtils.FastPowMod(a, res, n) != 1)
             {
                 Assert.Fail("a^r is not congruent to one.", a, n, res, MathUtils.FastPowMod(a, res, n));
             }
             for (int rp = 1; rp < res; rp++)
             {
                 if (MathUtils.FastPowMod(a, rp, n) == 1)
                 {
                     Assert.Fail("There is a smaller value r\' than r with a^r\' is congruent to one", a, n, res, rp);
                 }
             }
         }
     }
 }
예제 #2
0
        long FindDivisor(long n)
        {
            if (PrimeChecker.Prime(n))
            {
                throw new Exception("Number is already prime, can't find any nontrivial divisor.");
            }
            if ((n & 1) == 0)
            {
                return(2);
            }
            var rt = FindRoot(n);

            if (rt != -1)
            {
                return(rt);
            }

            while (true)
            {
                long a = (MathUtils.Random() % (n - 1)) + 1;
                long g = MathUtils.GCD(n, a);
                if (g != 1)
                {
                    return(g);
                }
                long r = OrderFinder.Find(a, n);
                if ((r & 1) != 0)
                {
                    continue;
                }
                if (MathUtils.FastPowMod(a, r / 2, n) == n - 1)
                {
                    continue;
                }
                long DivShare = MathUtils.FastPowMod(a, r / 2, n) - 1;
                return(MathUtils.GCD(n, DivShare));
            }
        }