//Цифровая подпись по примерам
        public static void ElGamal_DigitalSignature(BigInteger n, BigInteger g, BigInteger k, BigInteger a, BigInteger h, ref BigInteger s, ref BigInteger r)
        {
            BigInteger d = BigInteger.ModPow(g, k, n);//Вычисление открытого ключа

            s = BigInteger.ModPow(g, a, n);
            BigInteger reverseElement = GCDEX.GetX(a, n - 1);

            r = BigInteger.ModPow(reverseElement * (h - s * k), 1, n - 1);
            //Console.WriteLine("p={0}\ng={1}\nk={2}\nd={3}\nh={4}\na={5}\ns={6}\nr={7}", n, g, k, d, h, a, s, r);
        }
        //Цифровая подпись
        /// <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);
        }