Пример #1
0
        void PollardPMinusOneEntry(long number, long b)
        {
            try
            {
                long a = 2, p;
                for (int j = 2; j <= b; j++)
                {
                    a = CryptographyMath.PowerSearch(a, j, number);
                }

                p = CryptographyMath.ExtendedGCD(a - 1, number)[0];
                if (p != 1 || p != number)
                {
                    MessageBox.Show(p.ToString() + " - делитель " + number.ToString());
                }
                else
                {
                    MessageBox.Show("Увы, попробуй ещё раз");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка:" + ex.Message);
            }
        }
        void FermaEntry(long number, long cycles)
        {
            try
            {
                long a, b;
                bool prime = true;
                for (int i = 0; i < cycles; i++)
                {
                    a = (long)rnd.Next(2, (int)number - 1);
                    b = CryptographyMath.PowerSearch(a, number - 1, number);

                    if (b != 1)
                    {
                        MessageBox.Show("Число  " + number.ToString() + " скорее всего составное");
                        prime = false;
                        break;
                    }
                }

                if (prime)
                {
                    MessageBox.Show("Число  " + number.ToString() + " вероятно простое");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка:" + ex.Message);
            }
        }
        public void PohlingHellman(long h, long g, long p)
        {
            var CountOccurencesList = CountOccurences(CryptographyMath.Factorization(p - 1)).ToList();
            var CongruenceList      = new List <KeyValuePair <long, long> >();

            Log("---------------------------------------------------------");
            Log(String.Format(" Решаем уравнение {0} = ({1})^x (mod {2})", h, g, p));
            Log("---------------------------------------------------------");
            PrintFormated("q", "e", "g^((p-1)/q^e)", "h^((p-1)/q^e)", "Уравнение (g^((p-1)/q^e))^x = h^((p-1)/q^e) для x");
            foreach (var i in Enumerable.Range(0, CountOccurencesList.Count))
            {
                var e1 = CryptographyMath.FixModulo((long)BigInteger.ModPow(g, ((p - 1) / BigInteger.Pow(CountOccurencesList[i].Key, CountOccurencesList[i].Value)), p), p);
                var e2 = CryptographyMath.FixModulo((long)BigInteger.ModPow(h, ((p - 1) / BigInteger.Pow(CountOccurencesList[i].Key, CountOccurencesList[i].Value)), p), p);

                CongruenceList.Add(CryptographyMath.CongruencePair(h, g, p, CountOccurencesList[i].Key, (long)CountOccurencesList[i].Value, e1, e2));

                var e3 = CongruenceList[CongruenceList.Count - 1].Key % CongruenceList[CongruenceList.Count - 1].Value;
                var e4 = CongruenceList[CongruenceList.Count - 1].Value;
                PrintFormated(CountOccurencesList[i].Key, CountOccurencesList[i].Value, e1, e2, String.Format("x = {0} (mod {1})", e3, e4));
            }
            Log(String.Format(" Решаем систему уравнений с помощью КТО:"));
            Log("---------------------------------------------------------");
            Log(String.Format(" x = {0}", CryptographyMath.ChineseRemainderAlgorithm(CongruenceList)));
            Log("---------------------------------------------------------");
        }
Пример #4
0
        void RabinMillerEntry(long number)
        {
            try
            {
                long baseNum            = (long)rnd.Next(2, (int)number - 2);
                long s                  = 0; // степень двойки
                long t                  = 0; // нечетное число, n-1 = 2^s*t
                bool searchRequired     = true;
                long primeSearchCounter = 0;

                // если число n чётное или НОД(baseNum, n)!=1, то оно составное
                if (number % 2 == 0 || CryptographyMath.ExtendedGCD(baseNum, number)[0] != 1)
                {
                    MessageBox.Show("Число " + number.ToString() + " скорее всего составное");
                }
                else
                {
                    t = (number - 1);
                    //представляем число n - 1 в таком виде: n-1 = 2^s*t,  находим s и t
                    while (searchRequired)
                    {
                        if (t % 2 == 0)
                        {
                            s++;
                            t = (number - 1) / (long)Math.Pow(2, s);
                        }
                        else
                        {
                            searchRequired = false;
                        }
                    }

                    //если baseNum^t = 1 (mod n), или baseNum^((2^r)*t) = -1 (mod n) при 0<=r<s , то n псевдопростое по основанию baseNum
                    for (int i = 0; i < s; i++)
                    {
                        long atn = CryptographyMath.PowerSearch(baseNum, t, number);                                                 // возводим а в степень t по модулю n

                        if ((Math.Abs(atn) == 1) || (CryptographyMath.PowerSearch(atn, (long)Math.Pow(2, i), number) == number - 1)) // вместо того, чтобы писать Stepen(atn, (long) Math.Pow(2, i), n) == -1
                        {
                            MessageBox.Show("Число " + number.ToString() + " вероятно простое");
                            break;
                        }
                        else
                        {
                            primeSearchCounter += 1;
                        }
                    }
                    //если ни при одном r (0<=r<s) не выполняется baseNum^((2^r)*t) = -1 (mod n), то n составное
                    if (primeSearchCounter == s)
                    {
                        MessageBox.Show(" Число " + number.ToString() + " составное");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка:" + ex.Message);
            }
        }
Пример #5
0
        public int?PollardParallel(long _g, long _a, long _m, long _n)
        {
            Random rand   = new Random();
            int    length = 100;

            var lpows  = new List <int>();
            var rpows  = new List <int>();
            var ai     = new List <int>();
            var bi     = new List <int>();
            var si     = new List <int>();
            var ti     = new List <int>();
            var result = new List <int>();

            for (int i = 0; i < length; i++)
            {
                ai.Add(rand.Next(0, (int)(_n - 1)));
                bi.Add(rand.Next(0, (int)(_n - 1)));
                lpows.Add((int)((CryptographyMath.FastPower(_g, ai[i], _n) * CryptographyMath.FastPower(_a, bi[i], _n)) % _n));
            }

            si.Add(rand.Next(0, (int)(_n - 1)));
            ti.Add(rand.Next(0, (int)(_n - 1)));
            rpows.Add((int)(CryptographyMath.FastPower(_g, si[0], _n) * CryptographyMath.FastPower(_a, ti[0], _n) % _n));

            LogWithoutDate("\ti\tgi\tai\tbi\tsi\tti");

            LogWithoutDate("\t" + 0 + "\t" + rpows[0] + "\t" + ai[0] + "\t" + bi[0] + "\t" + si[0] + "\t" + ti[0]);

            for (int i = 0; i < rpows.Count; i++)
            {
                int index = EasyCalculatableFunction((int)_m, rpows[i], rpows.Count) - 1;
                rpows.Add((int)((rpows[i] * lpows[index]) % _n));
                si.Add((int)((si[i] + ai[index]) % _n));
                ti.Add((int)((ti[i] + bi[index]) % _n));

                LogWithoutDate("\t" + (i + 1) + "\t" + rpows[i + 1] + "\t" + ai[index] + "\t" + bi[index] + "\t" + si[i + 1] + "\t" + ti[i + 1]);

                for (int j = 0; j < rpows.Count; j++)
                {
                    for (int k = 0; k < rpows.Count; k++)
                    {
                        if (rpows[k] == rpows[j] && j != k)
                        {
                            if (si[k] != si[j])
                            {
                                long x = Math.Abs(si[k] - si[j]) * CryptographyMath.FastPower(Math.Abs(ti[j] - ti[k]), CryptographyMath.Euler(_a) - 1, _a);
                                x = x % _m;
                                if (_a == CryptographyMath.FastPower(_g, x, _m))
                                {
                                    return((int)x);
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
        void ParseAndRunDixon()
        {
            var N         = (int)_inputNumber.Value;
            var instances = (int)_inputThreads.Value;

            var calculateOperations = _calculateOperations.Checked;

            if (CryptographyMath.IsPower(N))
            {
                Log("N = " + N + " - степень простого числа");
            }
            else
            {
                DixonAlgorithm(N, instances, calculateOperations);
            }
        }
Пример #7
0
        public int AutoFindN(long _g, long _m)
        {
            int  i   = 1;
            var  lst = new List <long>();
            long res = CryptographyMath.FastPower(_g, i, _m);

            while (res != 1)
            {
                if (lst.Contains(res))
                {
                    Log("Не выйдет найти х - плохой диапазон значений. Попробуйте выбрать другие значения!");
                    return(-1);
                }
                else
                {
                    lst.Add(res);
                    i++;
                    res = CryptographyMath.FastPower(_g, i, _m);
                }
            }
            return(i);
        }
        private void DixonAlgorithm(int N, int numOfInstances, bool calculateOperations)
        {
            Log("Начинаем подбор. Факторизуемое число - " + N + " .Кол-во инстансов - " + numOfInstances);

            var tasks = new List <Task>();

            for (int iter = 0; iter < numOfInstances; iter++)
            {
                tasks.Add(new Task(() =>
                {
                    try
                    {
                        var calculateOps = calculateOperations;
                        var primesUponN  = CryptographyMath.SieveOfEratosthenes(N).ToList();
                        if (primesUponN.Contains(N))
                        {
                            Log("Число " + N + " - простое!");
                            return;
                        }

                        primesUponN.RemoveAt(0);//Remove 1 from list

                        var minN   = (int)Math.Sqrt(N);
                        var M      = Math.Pow(LofN(N), 0.5);
                        var primes = primesUponN.Where(x => x <= M).ToList();

                        if (primes.Count == 0)
                        {
                            Log("Слишком маленькое число !!");
                            return;
                        }

                        var B = new List <long>(primes.ConvertAll(i => (long)i));//build factor base
                        int h = B.Count + 1;

                        var smoothed         = new List <SmoothInfo>();
                        var operationCounter = new List <DixonOperations>();
                        var answerNotFound   = true;

                        while (answerNotFound)
                        {
                            int curFound = 0;
                            smoothed.Clear();
                            while (curFound < h)
                            {
                                var b = random.Next(minN + 1, N - 1);
                                var a = long.Parse(BigInteger.ModPow(new BigInteger(b), new BigInteger(2), new BigInteger(N)).ToString());

                                if (calculateOps)
                                {
                                    operationCounter.Add(DixonOperations.GenerateB);
                                    operationCounter.Add(DixonOperations.GenerateA);
                                }

                                if (a == 0)
                                {
                                    continue;
                                }

                                var factors = new List <long>();

                                if (calculateOps)
                                {
                                    operationCounter.Add(DixonOperations.CheckSmooth);
                                }

                                if (CryptographyMath.IsSmooth(a, B, out factors))
                                {
                                    var smooth  = new SmoothInfo();
                                    smooth.a    = a;
                                    smooth.b    = b;
                                    smooth.aVec = factors;
                                    factors.ForEach(x => smooth.epsVec.Add(x % 2));
                                    smoothed.Add(smooth);
                                    curFound += 1;
                                }
                                else
                                {
                                    continue;
                                }
                            }

                            for (int first = 0; first < smoothed.Count && answerNotFound == true; first++)
                            {
                                for (int second = first; second < smoothed.Count && answerNotFound == true; second++)
                                {
                                    if (first != second)
                                    {
                                        if (calculateOps)
                                        {
                                            operationCounter.Add(DixonOperations.CheckLinearEquation);
                                        }

                                        var vecOne = smoothed[first];
                                        var vecTwo = smoothed[second];

                                        var deltaLeft     = smoothed.Count - (smoothed.Count - first);
                                        var deltaMiddle   = second - (first + 1);
                                        var currentAnswer = new List <double>();
                                        var matrix        = new List <List <double> >();

                                        //create correct matrix here
                                        for (int i = 0; i < vecOne.aVec.Count; i++)
                                        {
                                            var vertex = new List <double>();
                                            vertex.AddRange(Enumerable.Repeat(0.0, deltaLeft));
                                            vertex.Add(vecOne.aVec[i]);
                                            vertex.AddRange(Enumerable.Repeat(0.0, deltaMiddle));
                                            vertex.Add(vecTwo.aVec[i]);
                                            vertex.Add(0);
                                            matrix.Add(vertex);
                                        }

                                        CryptographyMath.TheTruePowerfullGauss(matrix, currentAnswer);

                                        if (currentAnswer.Any(x => x != 0))
                                        {
                                            var probableX = (vecOne.b * vecTwo.b) % N;

                                            var probableY = 1.0;
                                            for (int i = 0; i < B.Count; i++)
                                            {
                                                var value  = B[i];
                                                var step   = (vecOne.aVec[i] + vecTwo.aVec[i]) / 2.0;
                                                probableY *= Math.Pow(value, step);
                                            }

                                            probableY = probableY % N;

                                            if (calculateOps)
                                            {
                                                operationCounter.Add(DixonOperations.CheckXY);
                                            }

                                            if ((probableX == probableY) || (probableX == -probableY))
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                //n = u * v
                                                //u = gcd(x+y,n)
                                                //v = gcd(x-y,n)

                                                var u = CryptographyMath.ExtendedGCD((int)(probableX + probableY), N)[0];
                                                var v = CryptographyMath.ExtendedGCD((int)(probableX - probableY), N)[0];

                                                if (calculateOps)
                                                {
                                                    operationCounter.Add(DixonOperations.CalculateGcd);
                                                    operationCounter.Add(DixonOperations.CalculateGcd);
                                                }

                                                if (((u * v) == N) && (u != 1) && (v != 1))
                                                {
                                                    Log("Разложение найдено - (" + u + ") * (" + v + ") = " + N);
                                                    answerNotFound = false;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            continue;
                                        }
                                    }
                                }
                            }
                        }

                        if (calculateOps)
                        {
                            var finalResult  = "\r\nОбщее кол-во выполненых операций:" + operationCounter.Count + "\r\n";
                            var countResults = operationCounter.GroupBy(x => x).ToDictionary(x => x.Key, y => y.Count());
                            foreach (var info in countResults)
                            {
                                finalResult += info.Key + " - " + info.Value + "\r\n";
                            }

                            Log(finalResult);
                        }
                    }
                    catch (Exception e)
                    {
                        if (e.Message.Contains("OutOfMemoryException"))
                        {
                            Log("Недостаточно памяти для вычисления значения");
                        }
                        else
                        {
                            Log("Возникла ошибка:" + e.Message);
                        }
                        return;
                    }
                }));
            }

            tasks.ForEach(x => x.Start());
        }