Example #1
0
        internal RawNum Sqrt(RawNum left)
        {
            m_targetSquare    = left;
            m_targetSquareNum = m_targetSquare.OmgWrapper();

            m_rootAprox = OmgPool.GetRawZero();
            m_buffer    = OmgPool.GetRawZero();

            _FillInitialApproximation();

            while (!_AproxEqualToBuffer())
            {
                var aproxCopy = OmgPool.GetRawZero();
                aproxCopy.CopyFrom(m_rootAprox);

                var bufferCopy = OmgPool.GetRawZero();
                bufferCopy.CopyFrom(m_buffer);

                _MakeGeronIteration();

                if (OmgOp.Equal(aproxCopy.OmgWrapper(), m_buffer.OmgWrapper()) &&
                    OmgOp.Equal(bufferCopy.OmgWrapper(), m_rootAprox.OmgWrapper()) &&
                    OmgOp.Less(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper()))
                {
                    break;
                }

                OmgPool.ReleaseNumber(bufferCopy);
                OmgPool.ReleaseNumber(aproxCopy);
            }

            OmgPool.ReleaseNumber(m_buffer);
            return(m_rootAprox);
        }
Example #2
0
        public Key GenerateKey(int keyByteLength)
        {
            int componentLength = keyByteLength * 8 / 2;

            OmgNum p = m_primeSource.GeneratePrime(componentLength);
            OmgNum q = m_primeSource.GeneratePrime(componentLength);

            OmgNum n = OmgOp.Multiply(p, q);

            OmgNum phiP  = OmgOp.Subtract(p, OmgNum.GetConst(1));
            OmgNum phiQ  = OmgOp.Subtract(q, OmgNum.GetConst(1));
            OmgNum carmN = _Carmichael(phiP, phiQ);

            OmgNum e = _SelectExponent(carmN);

            bool dpExists   = OmgOp.TryInverseByMod(e, phiP, out OmgNum dP);
            bool dQExists   = OmgOp.TryInverseByMod(e, phiQ, out OmgNum dQ);
            bool qInvExists = OmgOp.TryInverseByMod(q, p, out OmgNum qInv);

            if (!dpExists || !dQExists || !qInvExists)
            {
                throw new OmgFailException("Inverse is impossible");
            }

            return(new Key {
                pub = new PubKey {
                    N = n, E = e
                },
                priv = new PrivKey {
                    P = p, Q = q, dP = dP, dQ = dQ, qInv = qInv
                }
            });
        }
Example #3
0
        private bool _MakeTest(OmgNum testBase)
        {
            OmgNum numDec         = (new OmgNum(m_tested)).Dec();
            OmgNum tested         = OmgOp.Pow(testBase, m_initialTested, m_tested);
            OmgNum iterationsLeft = new OmgNum(m_powerOfTwo);

            try {
                if (OmgOp.Equal(tested, OmgNum.GetConst(1)) || OmgOp.Equal(tested, numDec))
                {
                    return(true);
                }

                while (!iterationsLeft.IsZero())
                {
                    iterationsLeft.Dec();

                    var nwTested = OmgOp.Multiply(tested, tested, m_tested);
                    tested.Release();
                    tested = nwTested;

                    if (OmgOp.Equal(tested, numDec))
                    {
                        return(true);
                    }
                }

                return(false);
            }
            finally {
                numDec.Release();
                tested.Release();
                iterationsLeft.Release();
            }
        }
Example #4
0
        private bool _LeftAbsIsLess(OmgNum left, OmgNum right)
        {
            var absLeft  = new OmgNum(left.Raw);
            var absRight = new OmgNum(right.Raw);

            return(OmgOp.Less(absLeft, absRight));
        }
Example #5
0
        internal RawNum ExtendedGcd(RawNum left, RawNum right, out OmgNum x, out OmgNum y)
        {
            if (left.IsZero())
            {
                x = 0.ToOmgNum();
                y = 1.ToOmgNum();

                RawNum gcd = OmgPool.GetRawZero();
                gcd.CopyFrom(right);
                return(gcd);
            }

            var divModRes = OmgOp.DivMod(right.OmgWrapper(), left.OmgWrapper());

            RawNum gcdRes = ExtendedGcd(divModRes.mod.Raw, left, out OmgNum x2, out OmgNum y2);

            divModRes.mod.Release();

            OmgNum multRes = OmgOp.Multiply(divModRes.div, x2);

            divModRes.div.Release();

            x = OmgOp.Subtract(y2, multRes);
            y2.Release();
            multRes.Release();

            y = x2;
            return(gcdRes);
        }
Example #6
0
        public OmgNum EulerFunction(OmgNum num)
        {
            var factorization = Factorize(num);

            var one = 1.ToOmgNum();

            OmgNum result = 1.ToOmgNum();

            foreach (var factor in factorization)
            {
                OmgNum phiP = null;

                if (factor.Value.IsOne())
                {
                    phiP = OmgOp.Subtract(factor.Key, one);
                }
                else
                {
                    var pTonMinusOne = OmgOp.Pow(factor.Key, OmgOp.Subtract(factor.Value, one));
                    phiP = OmgOp.Multiply(pTonMinusOne, OmgOp.Subtract(factor.Key, one));
                    pTonMinusOne.Release();
                }
                var nwRes = OmgOp.Multiply(result, phiP);

                result.Release();
                phiP.Release();

                result = nwRes;
            }

            return(result);
        }
Example #7
0
        private bool _IsTrivial(RawNum left, RawNum right)
        {
            OmgNum absLeft  = new OmgNum(left);
            OmgNum absRight = new OmgNum(right);

            return(OmgOp.Less(absLeft, absRight));
        }
Example #8
0
        public (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right)
        {
            _InitializeDivModResult();

            if (OmgOp.Equal(right, s_two))
            {
                _DivModByTwo(left);
                return(m_divRes, m_modRes);
            }

            bool isNegative = left.IsNegative != right.IsNegative;

            m_divRes.IsNegative = isNegative;

            _FindDivModSolution(left.Raw, right.Raw);

            if (isNegative)
            {
                m_divRaw.Inc();
                _Subtract(right.Raw, m_modRaw);
            }

            _RemoveModLeadingZeros();
            return(m_divRes, m_modRes);
        }
Example #9
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);
        }
Example #10
0
        private void _InitializeDivModResult()
        {
            m_divRes = OmgPool.GetZero();
            m_divRaw = m_divRes.Raw;

            _InitializeModResult();
        }
Example #11
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;
        }
Example #12
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);
        }
Example #13
0
        private OmgNum _SelectRandomExponent(OmgNum carmN, out OmgNum D)
        {
            OmgNum e = OmgOp.Random(OmgNum.GetConst(0), carmN);

            while (!OmgOp.TryInverseByMod(e, carmN, out D))
            {
                e = OmgOp.Random(OmgNum.GetConst(0), carmN);
            }

            return(e);
        }
Example #14
0
        public OmgNum Mobius(OmgNum num)
        {
            var factorization = Factorize(num);

            if (factorization.Values.Any(x => !x.IsOne()))
            {
                return(0.ToOmgNum());
            }

            return((factorization.Count % 2 == 0) ? 1.ToOmgNum() : (-1).ToOmgNum());
        }
Example #15
0
        private OmgNum _Carmichael(OmgNum phiP, OmgNum phiQ)
        {
            OmgNum pq    = OmgOp.Multiply(phiP, phiQ);
            OmgNum pqGCD = OmgOp.Gcd(phiP, phiQ);

            OmgNum lcm = OmgOp.Div(pq, pqGCD);

            pq.Release();
            pqGCD.Release();

            return(lcm);
        }
Example #16
0
        private void _DivModByTwo(OmgNum num)
        {
            var rawNum = num.Raw;

            if (!rawNum.IsZero() && ((rawNum.Digits[0] & 1) == 1))
            {
                m_modRaw.Digits.Add(1);
            }

            m_divRaw.CopyFrom(rawNum);
            m_divRaw.DivByTwo();
        }
Example #17
0
        public void SetTestedNumber(OmgNum num)
        {
            m_tested?.Release();
            m_tested = num;

            m_shurelyNotAPrime = OmgOp.Less(num, OmgNum.GetConst(2));
            m_shurelyNotAPrime = m_shurelyNotAPrime || !m_smallPrimeTester.IsPrime(m_tested);

            if (!m_shurelyNotAPrime && OmgOp.Greater(num, OmgNum.GetConst(1)))
            {
                _FactorPowerOfTwo(num);
            }
        }
Example #18
0
        public void NumberOfPrimesLessThen10000base2and3()
        {
            int count = 0;

            for (int i = 1; i < 10000; i++)
            {
                m_millerRabin.SetTestedNumber(i.ToOmgNum());
                if (m_millerRabin.IsPrimeToBase(OmgNum.GetConst(2)) && m_millerRabin.IsPrimeToBase(OmgNum.GetConst(3)))
                {
                    count++;
                }
            }
            Assert.AreEqual(count, 1227);
        }
Example #19
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);
        }
Example #20
0
        public OmgNum Mod(OmgNum left, OmgNum right)
        {
            _InitializeModResult();
            bool isNegative = left.IsNegative != right.IsNegative;

            _FindModSolution(left.Raw, right.Raw);

            if (isNegative)
            {
                _Subtract(right.Raw, m_modRaw);
            }

            _RemoveModLeadingZeros();
            return(m_modRes);
        }
Example #21
0
        private bool _IsSmallPrime(Dictionary <OmgNum, OmgNum> result, OmgNum num)
        {
            smallPrimesOmg ??= smallPrimes.Select(x => x.ToOmgNum()).ToArray();

            foreach (var prime in smallPrimesOmg)
            {
                if (OmgOp.Equal(prime, num))
                {
                    result[prime] = 1.ToOmgNum();
                    return(true);
                }
            }

            return(false);
        }
Example #22
0
        internal OmgNum Subtract(OmgNum left, OmgNum right)
        {
            if (left.IsNegative != right.IsNegative)
            {
                throw new OmgFailException("logic error");
            }

            m_subRes = OmgPool.GetZero();
            m_subRaw = m_subRes.Raw;

            _CalcSubtraction(left, right);

            _RemoveLeadingZeros();
            return(m_subRes);
        }
Example #23
0
        private void _CalcSubtraction(OmgNum left, OmgNum right)
        {
            bool flipSign   = (left.IsNegative == true);
            bool leftIsLess = _LeftAbsIsLess(left, right);

            if (leftIsLess)
            {
                m_subRes.IsNegative = !flipSign;
                _SubtractBiggerLess(right.Raw, left.Raw);
            }
            else
            {
                m_subRes.IsNegative = flipSign;
                _SubtractBiggerLess(left.Raw, right.Raw);
            }
        }
Example #24
0
        public bool IsPrimeToBase(OmgNum testBase)
        {
            if (OmgOp.Less(m_tested, OmgNum.GetConst(1)))
            {
                return(false);
            }

            if (m_shurelyNotAPrime)
            {
                return(false);
            }

            bool result = _MakeTest(testBase);

            return(result);
        }
Example #25
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);
        }
Example #26
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);
        }
Example #27
0
        private void _MakeGeronIteration()
        {
            OmgNum rootAprox = m_rootAprox.OmgWrapper();

            var res = OmgOp.DivMod(m_targetSquareNum, rootAprox);

            res.mod.Release();

            OmgNum sum = OmgOp.Add(rootAprox, res.div);

            res.div.Release();

            sum.Raw.DivByTwo();

            OmgPool.ReleaseNumber(m_buffer);
            m_buffer    = m_rootAprox;
            m_rootAprox = sum.Raw;
        }
Example #28
0
        private bool _TestFailed(OmgNum num)
        {
            m_primeTester.SetTestedNumber(num.Copy());

            for (int i = 0; i < m_testsPerNumber; i++)
            {
                OmgNum testBase = OmgOp.Random(OmgNum.GetConst(2), num);
                bool   isPrime  = m_primeTester.IsPrimeToBase(testBase);
                testBase.Release();

                if (!isPrime)
                {
                    return(true);
                }
            }

            return(false);
        }
Example #29
0
        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);
            }
        }
Example #30
0
        public static void Main(string[] args)
        {
            var primeGenerator = new PrimeGenerator();

            OmgNum[] primes = new OmgNum[5];
            for (int i = 0; i < primes.Length; i++)
            {
                primes[i] = primeGenerator.GeneratePrime(128);
                Console.WriteLine($"prime {i}: {primes[i]}");
            }

            Console.WriteLine();

            Console.WriteLine($"base2 : {primes[0].ToString(2)}");
            Console.WriteLine($"base10: {primes[0].ToString(10)}");
            Console.WriteLine($"base64: {primes[0].ToString(64)}");

            Console.WriteLine($"base64: {primes[0].EncodeToBase64()}");
        }