//Тест Поклингтона
        public static bool Poklington(BigInteger n, int t, List <BigInteger> Simples)
        {
            BigInteger[] As    = new BigInteger[] { };
            bool         check = true;

            for (int i = 0; i < t; i++)
            {
                BigInteger a = BigIntegerRandom.GenerateRandom(1, n, new Random());
                if (BigInteger.ModPow(a, n - 1, n) != 1)
                {
                    return(false);
                }

                Array.Resize <BigInteger>(ref As, As.Length + 1);
                As[As.Length - 1] = a;
            }
            for (int i = 0; i < t; i++)
            {
                for (int j = 0; j < Simples.Count; j++)
                {
                    if (BigInteger.ModPow(As[i], (n - 1) / Simples[j], n) == 1)
                    {
                        check = false;
                        break;
                    }
                }
            }
            return(check);
        }
 public DigitalSignature(int SizeOfSimple)
 {
     BIR = new BigIntegerRandom();
     P   = BigSimpleElgamal(SizeOfSimple);
     SimpleMultipliers(P - 1);
     g = FindG();
 }
 public DigitalSignature(int SizeOfSimple, bool NeedInfoForConsole)
 {
     BIR = new BigIntegerRandom();
     Console.WriteLine("Генерация числа p");
     P = BigSimpleElgamal(SizeOfSimple);
     Console.WriteLine("Разложение числа на простые множители");
     SimpleMultipliers(P - 1);
     Console.WriteLine("Нахождение G");
     g = FindG();
 }
        //Цифровая подпись
        /// <summary>
        /// Цифровая подпись сообщения h по схеме Эль-Гамаля
        /// </summary>
        /// <param name="h">Хэш сообщения</param>
        /// <param name="s"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public bool ElGamal_DigitalSignature(BigInteger h, ref BigInteger s, ref BigInteger r)
        {
            BigInteger k, a, d;

            do
            {
                k = BigIntegerRandom.GenerateRandom(0, P, new Random()); //Случайное число
                d = BigInteger.ModPow(G, k, P);                          //Вычисление открытого ключа
                a = BIR.MakeF(32);
                while (BigInteger.GreatestCommonDivisor(a, P - 1) != 1)
                {
                    a = BIR.MakeF(32);
                }
                s = BigInteger.ModPow(G, a, P);
                BigInteger reverseElement = GCDEX.GetX(a, P - 1);
                r = BigInteger.ModPow(reverseElement * (h - s * k), 1, P - 1);
            } while (r < 0 || !ElGamal_Verification(d, s, r, G, h, P));
            return(true);
        }
        public BigInteger GenerateSimple(int NeededSize)
        {
            bool              check       = false;
            BigInteger        n           = 0;//Большое простое число
            BigInteger        F           = 0;
            BigInteger        R           = 0;
            List <BigInteger> SimplesForN = null;
            BigIntegerRandom  BIR         = new BigIntegerRandom();

            while (!check)
            {
                SimplesForN = new List <BigInteger>();
                F           = BIR.MakeF(NeededSize / 2 + 1, ref SimplesForN);
                R           = BIR.MakeF(NeededSize / 2);
                R           = R >> 1;
                R           = R << 1;
                n           = R * F + 1;
                check       = TestsForSimplicity.Poklington(n, 100, SimplesForN);
            }
            return(n);
        }
        //Вероятностный тест Соловея-Штрассена
        public static bool Solovei_Shtrassen(BigInteger n)
        {
            int    count = 0;
            int    t     = 4;
            Random rnd   = new Random((int)(DateTime.Now.Ticks));

            for (int i = 0; i < t; i++)
            {
                BigInteger a = BigIntegerRandom.GenerateRandom(2, n - 2, rnd);

                if (BigInteger.GreatestCommonDivisor(a, n) != 1)
                {
                    break;
                }

                BigInteger Jc = Jakobi(a, n);
                BigInteger S  = BigInteger.ModPow(a, (n - 1) / 2, n);

                S = (S + 1 == n) ? S - n : S;

                if (Jc != S)
                {
                    break;
                }

                else
                {
                    count++;
                }
            }
            if (count == t)
            {
                return(true);
            }
            return(false);
        }