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("---------------------------------------------------------"); }
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); } }
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); } }
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()); }