Пример #1
0
        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;
        }