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); } } } } }
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)); } }