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; } }
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; } }
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"); }