//Тест Поклингтона
        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);
        }
        //Цифровая подпись
        /// <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 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);
        }