示例#1
0
        public ElGamale(long p, long g, long X, long K, long Message)
        {
            try
            {
                if (!Supporting.Simple(p))
                {
                    throw new Exception("p should be simple");
                }

                r = new Random(DateTime.Now.Second);
                if (X == 0)
                {
                    x = r.Next(1, (int)p);
                }
                else
                {
                    x = X;
                }
                this.p = p;
                this.g = g;
                Y      = Supporting.bin_pow(g, x, p);
                m      = Message;
                if (K == 0)
                {
                    while (!Supporting.MutuallySimple(k, p - 1))
                    {
                        k = r.Next(1, (int)p - 1);
                    }
                }

                else
                {
                    k = K;
                    if (!(1 < k && k < p - 1) && !Supporting.MutuallySimple(k, p - 1))
                    {
                        throw new Exception("k - сессионный ключ обязан придерживаться условия 1<k<p-1");
                    }
                }
                A = Supporting.bin_pow(g, k, p);

                B = (Supporting.bin_pow(Y, k, p) * (m % p)) % p;

                DecodeM = ((B % p) * Supporting.divide_pow(A, x, p)) % p;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
示例#2
0
        public ElGamaleSignature(long p, long g, long x, long K, long message)
        {
            sk = new SecretKey(x, p);     //Secret key: (x)
            pk = new PublicKey(p, g, sk); //Public key: (p,g,y)
            M  = message;
            if (K == 0)
            {
                while (!Supporting.MutuallySimple(k, p - 1))
                {
                    k = r.Next(1, (int)p - 1);
                }
            }
            else
            {
                k = K;
                if (!(1 < k && k < p - 1) && !Supporting.MutuallySimple(k, p - 1))
                {
                    throw new Exception("k - сессионный ключ обязан придерживаться условия 1<k<p-1");
                }
            }


            ReverseK = Supporting.ResolveModuleEquation(1, p - 1, k, p - 1,
                                                        1); //Поиск к^-1 через уравнение k*k^-1 mod (p-1) = 1

            A = Supporting.bin_pow(g, k, p);
            B = ((M - x * A) * ReverseK) % (p - 1); //цифровая подпись из чисел A и B,
            if (B < 0)
            {
                B += p - 1;
            }
            // проверка подлинности подписи
            ANumber1 = (Supporting.bin_pow(pk.y, A, p) * Supporting.bin_pow(A, B, p)) % p;
            ANumber2 = Supporting.bin_pow(g, M, p);
            if (ANumber1 == ANumber2)
            {
                Аuthenticity = true;
            }
            else
            {
                Аuthenticity = false;
            }
        }
示例#3
0
        public override string ToString()
        {
            string output;

            Supporting.gnd(k, pk.p - 1, out output);
            return($"Выберем числа p={pk.p} и g={pk.g}(примитивный элемент) и случайный секретный ключ x={sk.x}\n"
                   + $"Вычислим значение открытого ключа y = g^x mod p = {pk.g}^{sk.x} mod {pk.p} ={pk.y}\n"
                   + $"Вычислим цифровую подпись для сообщения M = {M}\n"
                   + $"    1)Сначала выберем случайное число k = {k}, 1<k<p-1, такое, что числа k и p-1 взаимно простые - {Supporting.MutuallySimple(k, pk.p - 1)}\n" +
                   $" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n" +
                   $" Проверка на взаимную простоту чисел k и p-1 ,т.е убедимся ,что НОД(k,p-1)=1\n {output}\n" +
                   $" Если НОД = 1, то действительно НОД({k},{pk.p-1})=1                                                                                      \n" +
                   $" |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
                   + $"1.1)Найдём число k^-1 такое что выполняется условие k*k^(-1) = 1 mod(p-1) т.е {k}*{k}^(-1) = 1 mod {pk.p - 1} | k^-1 = {ReverseK} \n"
                   + $"    2)Вычислить числа a = g^k mod p = {pk.g}^{k} mod {pk.p} = {A}, и с помощью секретного ключа x вычислим b = (M-xa)k^-1 mod (p-1)={B}\n"
                   + $"Тем самым цифровая подпись представляет собой пару чисел: a = {A}, b = {B}..\n"
                   + $"    3)Проверим подпись. Приняв сообщение M = {M} и цифровую подпись (a = {A} и b = {B})\n"
                   + $"Получатель вычисляет два числа 1)(y^a)*(a^b) mod p = {ANumber1}\n "
                   + $"И 2) g^M mod p = {ANumber2}\n"
                   + $"Проверим они равны? - {Аuthenticity}\n"
                   + "Если два числа равны , то принятое получателем сообщение признается подлинным , иначе сообщение фальшивое или цифровая подпись не подлинная\n");
        }