コード例 #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();
            }
        }
コード例 #2
0
ファイル: Gcder.cs プロジェクト: clewrus/AlgStruct
        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);
        }
コード例 #3
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);
        }
コード例 #4
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;
        }
コード例 #5
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);
        }
コード例 #6
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);
        }
コード例 #7
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);
        }
コード例 #8
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);
            }
        }
コード例 #9
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);
        }
コード例 #10
0
        public SignaureKey GenerateSignature(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 carmN = _Carmichael(p.Dec(), q.Dec());
            OmgNum e     = _SelectRandomExponent(carmN, out OmgNum d);

            p.Release();
            p.Release();

            return(new SignaureKey {
                cert = new SignCertificate {
                    N = n.Copy(), D = d
                },
                secret = new SignSecret()
                {
                    N = n, E = e
                }
            });
        }
コード例 #11
0
ファイル: PrimeGenerator.cs プロジェクト: clewrus/AlgStruct
        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);
        }
コード例 #12
0
ファイル: Multiplier.cs プロジェクト: clewrus/AlgStruct
        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);
            }
        }
コード例 #13
0
ファイル: RsaUtility.cs プロジェクト: clewrus/AlgStruct
        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);
            }
        }
コード例 #14
0
ファイル: PrimeGenerator.cs プロジェクト: clewrus/AlgStruct
        public OmgNum GeneratePrime(int bitLength)
        {
            if (bitLength < 0)
            {
                return(null);
            }

            if (bitLength == 0)
            {
                return(0.ToOmgNum());
            }

            OmgNum randNum = OmgOp.Random(bitLength);

            while (_TestFailed(randNum))
            {
                randNum.Release();
                randNum = OmgOp.Random(bitLength);
            }

            return(randNum);
        }
コード例 #15
0
ファイル: Multiplier.cs プロジェクト: clewrus/AlgStruct
        internal RawNum MultiplyKaratsuba(RawNum left, RawNum right)
        {
            if (left.IsZero() || right.IsZero())
            {
                return(OmgPool.GetRawZero());
            }

            int n = Math.Min(left.Size, right.Size);

            (RawNum head, RawNum tail)leftSep  = _SeparateHead(left, n);
            (RawNum head, RawNum tail)rightSep = _SeparateHead(right, n);

            RawNum headsProd = Multiply(leftSep.head, rightSep.head);
            RawNum tailsProd = Multiply(leftSep.tail, rightSep.tail);

            RawNum headTail = Multiply(leftSep.head, rightSep.tail);
            RawNum tailHead = Multiply(leftSep.tail, rightSep.head);

            OmgNum midSum = OmgOp.Add(new OmgNum(headTail), new OmgNum(tailHead));

            m_multRaw = OmgPool.GetRawZero();

            m_multRaw.CopyFrom(tailsProd);
            midSum.Raw.Digits.InsertRange(0, Enumerable.Repeat <uint>(0, n));
            headsProd.Digits.InsertRange(0, Enumerable.Repeat <uint>(0, 2 * n));

            OmgNum res      = OmgOp.Add(new OmgNum(tailsProd), midSum);
            OmgNum finalRes = OmgOp.Add(new OmgNum(headsProd), res);

            midSum.Release();
            res.Release();
            OmgPool.ReleaseNumber(headTail);
            OmgPool.ReleaseNumber(tailHead);

            return(finalRes.Raw);
        }