private OmgNum _FermaFactorization(Dictionary <OmgNum, OmgNum> result, OmgNum num) { OmgNum factor = null; if (OmgOp.DivMod(num, 2.ToOmgNum()).mod.IsZero()) { factor = 2.ToOmgNum(); } if (factor == null) { OmgNum a = OmgOp.Sqrt(num); OmgNum aSq = OmgOp.Multiply(a, a); bool isSquare = OmgOp.Equal(num, aSq); if (isSquare) { factor = a; } a.Inc(); aSq = OmgOp.Multiply(a, a); var s = OmgOp.Subtract(aSq, num); while (factor == null) { var testSqrt = OmgOp.Sqrt(s); if (OmgOp.Equal(s, OmgOp.Multiply(testSqrt, testSqrt))) { factor = (OmgOp.Equal(testSqrt, a)) ? OmgOp.Add(a, a) : OmgOp.Subtract(a, testSqrt); break; } a.Inc(); aSq = OmgOp.Multiply(a, a); s = OmgOp.Subtract(aSq, num); } } if (factor == null || factor.IsOne()) { return(num); } OmgNum pow = _FindPow(ref num, factor); if (result.ContainsKey(factor)) { result[factor] = OmgOp.Add(result[factor], pow); } else { result[factor] = pow; } return(num); }
private OmgNum _SelectExponent(OmgNum carmN) { OmgNum candidate = ((1 << 16) + 1).ToOmgNum(); OmgNum gcd = OmgOp.Gcd(candidate, carmN); while (!gcd.IsOne()) { gcd = OmgOp.Gcd(candidate.Inc(), carmN); } gcd.Release(); return(candidate); }
public OmgNum FindFactor(OmgNum n, int maxIterations = -1) { m_iterations = 0; m_current = n; OmgNum x = OmgOp.Random(1.ToOmgNum(), OmgOp.Subtract(n, 2.ToOmgNum())); OmgNum y = 1.ToOmgNum(); OmgNum i = 0.ToOmgNum(); OmgNum stage = 2.ToOmgNum(); OmgNum sub = OmgOp.Subtract(x, y).MakeAbs(); OmgNum gcd = OmgOp.Gcd(n, sub); sub.Release(); while (gcd.IsOne()) { if (maxIterations >= 0 && m_iterations++ > maxIterations) { return(null); } if (OmgOp.Equal(i, stage)) { y.Release(); y = new OmgNum(x); stage.MultByTwo(); } OmgNum xSquare = OmgOp.Multiply(x, x).Inc(); x.Release(); x = OmgOp.Mod(xSquare, n); xSquare.Release(); i.Inc(); sub = OmgOp.Subtract(x, y).MakeAbs(); gcd.Release(); gcd = OmgOp.Gcd(n, sub); sub.Release(); } return(gcd); }
private OmgNum _FindFactorsWithPollard(Dictionary <OmgNum, OmgNum> result, OmgNum num) { num = num.Copy(); while (!num.IsOne()) { OmgNum factor = m_polard.FindFactor(num, maxIterations: 100000); if (factor == null || factor.IsOne() || OmgOp.Equal(factor, num)) { return(num); } OmgNum pow = _FindPow(ref num, factor); result[factor] = pow; } return(num); }
public Dictionary <OmgNum, OmgNum> Factorize(OmgNum num) { var initNum = num.Copy(); var result = new Dictionary <OmgNum, OmgNum>(); if (_IsSmallPrime(result, num)) { return(result); } num = _FindFactorsWithPollard(result, num); num = _FermaFactorization(result, num); if (!num.IsOne()) { result[num] = 1.ToOmgNum(); } if (result.Count == 1 && result.TryGetValue(initNum, out var power) && power.IsOne()) { return(result); } var nonPrimeFactors = new Stack <OmgNum>(result.Keys); while (nonPrimeFactors.Count > 0) { var factor = nonPrimeFactors.Pop(); if (result[factor].IsZero()) { result.Remove(factor); continue; } var primeFactors = Factorize(factor); if (primeFactors.Count == 1 && primeFactors.Values.First().IsOne()) { continue; } var topPower = result[factor]; result.Remove(factor); foreach (var primeFactor in primeFactors) { var pow = OmgOp.Multiply(topPower, primeFactor.Value); if (result.ContainsKey(primeFactor.Key)) { result[primeFactor.Key] = OmgOp.Add(result[primeFactor.Key], pow); } else { result[primeFactor.Key] = pow; } } } var keys = new List <OmgNum>(result.Keys); foreach (var key in keys) { if (result[key].IsZero()) { result.Remove(key); } } return(result); }