Example #1
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 #2
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 #3
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 #4
0
 public static IEnumerable <OmgNum> Encode(IEnumerable <OmgNum> message, PubKey key)
 {
     foreach (var num in message)
     {
         yield return(OmgOp.Pow(num, key.E, key.N));
     }
 }
Example #5
0
 private static IEnumerable <OmgNum> Decode(IEnumerable <OmgNum> message, SignCertificate cert)
 {
     foreach (var num in message)
     {
         yield return(OmgOp.Pow(num, cert.D, cert.N));
     }
 }
Example #6
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 #7
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 #8
0
 private static IEnumerable <OmgNum> Encode(IEnumerable <OmgNum> message, SignSecret secret)
 {
     foreach (var num in message)
     {
         yield return(OmgOp.Pow(num, secret.E, secret.N));
     }
 }
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
        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 #11
0
        private bool _IsTrivial(RawNum left, RawNum right)
        {
            OmgNum absLeft  = new OmgNum(left);
            OmgNum absRight = new OmgNum(right);

            return(OmgOp.Less(absLeft, absRight));
        }
Example #12
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 #13
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 #14
0
        static void Main(string[] args)
        {
            var a = 234234.ToOmgNum();
            var b = "85430534954938530495935803495482304983".ToOmgNum();
            var c = "100000000000000000000000000000000".ToOmgNum();
            var d = "-100000000000000000".ToOmgNum();


            var a1 = OmgOp.Add(a, c);
            var a2 = OmgOp.Subtract(a, c);
            var a3 = OmgOp.Multiply(a, b);
            var a4 = OmgOp.DivMod(b, c);
            var a6 = OmgOp.Pow(b, c, a);
            var a7 = OmgOp.Sqrt(b);


            var sys1 = new OmgEqSys();

            sys1.AddEq(1287.ToOmgNum(), 447.ToOmgNum(), 516.ToOmgNum());

            bool success1 = sys1.TrySolve(out List <(OmgNum root, OmgNum mod)> solution1);

            var sys2 = new OmgEqSys();


            bool success2 = sys2.TrySolve(out var solution2);
        }
Example #15
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 #16
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 #17
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 #18
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 #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
        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 #21
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 #22
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 #23
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 #24
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 #25
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 #26
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 #27
0
        internal RawNum FindGcd(RawNum left, RawNum right)
        {
            if (left.IsZero())
            {
                RawNum gcd = OmgPool.GetRawZero();
                gcd.CopyFrom(right);
                return(gcd);
            }

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

            divModRes.div.Release();

            RawNum gcdRes = FindGcd(divModRes.mod.Raw, left);

            divModRes.mod.Release();

            return(gcdRes);
        }
Example #28
0
        static void Main(string[] args)
        {
            // Rho Pollard
            var primeA = "99194853094755497".ToOmgNum();
            var primeB = "2971215073".ToOmgNum();

            var primesProd = OmgOp.Multiply(primeA, primeB);

            var polard = new PolardFactorization();
            var factor = polard.FindFactor(primesProd);

            Console.WriteLine($"factor: {factor}");

            // Rho Discrete Log

            var rhoLogFinder = new RhoLog();

            (OmgNum a, OmgNum b, OmgNum p)log = (5.ToOmgNum(), 3.ToOmgNum(), 2017.ToOmgNum());
            var discreteLog = rhoLogFinder.FindLog(log.a, log.b, log.p);

            Console.WriteLine($"{discreteLog} : {OmgOp.Pow(log.a, discreteLog, log.p)}");

            // Factorization

            var factorizer    = new Factorization();
            var factorization = factorizer.Factorize("63782453".ToOmgNum());

            Console.WriteLine($"factorization: {String.Join(' ', factorization.Select(x => ($"{x.Key}^{x.Value}")))}");
            // EulerF

            var euler = factorizer.EulerFunction("63782453".ToOmgNum());

            Console.WriteLine($"euler: {euler}");

            // MobiusF

            var mobius1 = factorizer.Mobius("63782453".ToOmgNum());
            var mobius2 = factorizer.Mobius("4".ToOmgNum());

            Console.WriteLine($"mobius1: {mobius1}");
            Console.WriteLine($"mobius2: {mobius2}");
        }
Example #29
0
        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);
        }
Example #30
0
        public static IEnumerable <OmgNum> Decode(IEnumerable <OmgNum> code, PrivKey key)
        {
            foreach (var num in code)
            {
                OmgNum m1 = OmgOp.Pow(num, key.dP, key.P);
                OmgNum m2 = OmgOp.Pow(num, key.dQ, key.Q);

                OmgNum mdif = OmgOp.Subtract(m1, m2);
                OmgNum h    = OmgOp.Multiply(key.qInv, mdif, key.P);

                OmgNum hq = OmgOp.Multiply(h, key.Q);
                OmgNum m  = OmgOp.Add(m2, hq);

                m1.Release();
                m2.Release();
                mdif.Release();
                h.Release();
                hq.Release();

                yield return(m);
            }
        }