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 void _FactorPowerOfTwo(OmgNum num) { m_powerOfTwo?.Release(); m_initialTested?.Release(); var n = OmgOp.Subtract(num, OmgNum.GetConst(1)); m_powerOfTwo = 0.ToOmgNum(); (OmgNum div, OmgNum mod)divMod = OmgOp.DivMod(n, OmgNum.GetConst(2)); while (divMod.mod.IsZero()) { n.Release(); divMod.mod.Release(); n = divMod.div; m_powerOfTwo.Inc(); divMod = OmgOp.DivMod(n, OmgNum.GetConst(2)); } divMod.div.Release(); divMod.mod.Release(); m_initialTested = n; }
private OmgNum _FindPow(ref OmgNum num, OmgNum factor) { OmgNum pow = 0.ToOmgNum(); while (true) { var divMod = OmgOp.DivMod(num, factor); if (!divMod.mod.IsZero()) { break; } pow.Inc(); divMod.mod.Release(); num.Release(); num = divMod.div; } if (pow.IsZero()) { throw new Exception(); } return(pow); }
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); }