public static BigInteger ShanksAlgorithm(BigInteger alpha, BigInteger beta, BigInteger n) { return(BabyStepGiantStep.bsgs2(alpha, beta, n)); BigInteger m = (n - 1).Sqrt() + 1; BigInteger a = BigInteger.ModPow(alpha, m, n); BigInteger b = ExtendedGCD(alpha, n)[1]; List <BigInteger[]> L1 = new List <BigInteger[]>(); List <BigInteger[]> L2 = new List <BigInteger[]>(); for (int ii = 0; ii < m; ii++) { L1.Add(new BigInteger[] { ii, BigInteger.ModPow(a, ii, n) }); BigInteger second = beta * BigInteger.Pow(b, ii) % n; while (second < 0) { second += n; } L2.Add(new BigInteger[] { ii, second }); } L1 = L1.OrderBy(x => x[1]).ToList(); L2 = L2.OrderBy(x => x[1]).ToList(); int i = 0; int j = 0; bool found = false; while (!found && i < m && j < m) { if (L1[j][1] == L2[i][1]) { return(m * L1[j][0] + L2[i][0] % n); } else if (BigInteger.Abs(L1[j][1]) > BigInteger.Abs(L2[i][1])) { i += 1; } else { j += 1; } } return(-1); }
private void DoMagicBtn_Click(object sender, EventArgs e) { BSGSProgressBar.Value = 0; BigInteger a, b, m, answer; a = 0; b = 0; m = 0; answer = 0; ResultLabel.Visible = false; ResultLabel.ForeColor = Color.Red; BigInteger.TryParse(ABox.Text, out a); BigInteger.TryParse(BBox.Text, out b); BigInteger.TryParse(MBox.Text, out m); if (a < 2 || b < 0 || m < 3 || b > m) { ResultLabel.Text = "Неправильный ввод данных"; } else if (!(CryptoMath.isPrime(m))) { ResultLabel.Text = "М должно быть простым"; } else { if (m.ToString().Length > 10) { ResultLabel.Text = "Слишком большое М - \nВозможна нехватка памяти"; ResultLabel.Visible = true; } try { BSGSProgressBar.Visible = true; this.Enabled = false; answer = BabyStepGiantStep.bsgs2(a, b, m, BSGSProgressBar); } catch (OutOfMemoryException) { ResultLabel.Text = "Нехватка оперативной памяти"; ResultLabel.Visible = true; this.Enabled = true; return; } if (answer == -1) { ResultLabel.Text = "Такого Х не найдено"; } else { ResultLabel.ForeColor = Color.Green; ResultLabel.Text = $"X = {answer}"; if (BigInteger.ModPow(a, answer, m) != b) { ResultLabel.Text += "?"; } } } BSGSProgressBar.Visible = false; ResultLabel.Visible = true; this.Enabled = true; }