コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }