예제 #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 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;
        }
예제 #3
0
        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);
        }
예제 #4
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);
        }
예제 #5
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);
        }