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 _MakeFastPow(OmgNum left, RawNum right, OmgNum mod) { if (right.IsZero()) { var res = OmgPool.GetRawZero(); res.Digits.Add(1); return(new OmgNum(res)); } var rightCopy = OmgPool.GetRawZero(); rightCopy.CopyFrom(right); bool even = (rightCopy.Digits[0] & 1) == 0; if (even) { rightCopy.DivByTwo(); var p = _MakeFastPow(left, rightCopy, mod); OmgNum powSquare = OmgOp.Multiply(p, p); OmgNum powSquareModded = OmgOp.Mod(powSquare, mod); powSquare.Release(); p.Release(); OmgPool.ReleaseNumber(rightCopy); return(powSquareModded); } else { _SubOne(rightCopy); var p = _MakeFastPow(left, rightCopy, mod); OmgNum powPlusOne = OmgOp.Multiply(p, left); OmgNum powPlusOneModded = OmgOp.Mod(powPlusOne, mod); powPlusOne.Release(); p.Release(); OmgPool.ReleaseNumber(rightCopy); return(powPlusOneModded); } }
public bool IsPrime(OmgNum tested) { foreach (var prime in s_smallPrimes) { if (OmgOp.Less(tested, prime) || OmgOp.Equal(tested, prime)) { return(true); } var mod = OmgOp.Mod(tested, prime); bool isComposite = mod.IsZero(); mod.Release(); if (isComposite) { return(false); } } return(true); }