Advertisement
EgorYankovsky

OK2

Oct 14th, 2022
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.23 KB | Cybersecurity | 0 0
  1. /*
  2.  * ГЕНЕРАЦИЯ КЛЮЧЕЙ
  3.  *  1. Генерируется случайное простое число p.
  4.  *  2. Выбирается целое число g — первообразный корень p.
  5.  *  3. Выбирается случайное целое число x такое, что ( 1 < x < p − 1 ).
  6.  *  4. Вычисляется y = g ^ x mod p .
  7.  *  5. Открытым ключом является ( y , g , p ), закрытым ключом — число x.
  8.  * ШИФРОВАНИЕ
  9.  *  0. Вводим М, меньшее p
  10.  *  1. Выбираем сессионный ключ - случайное число, взаимно простое с (р - 1), k такое, что 1 < k < p-1
  11.  *  2. Вычисляются числа a = (g ^ k) mod p и b = (y ^ k * M) mod p
  12.  *  3. Пара чисел (a, b) являются шифротекстом
  13.  * РАСШИФРОВАНИЕ
  14.  *  0. Зная закрытый ключ х, исходное сообщение модно вычислить из шифротекта (a, b) по формуле
  15.  *  1. M = (b * a ^ (p - 1 - x)) mod p
  16.  */
  17.  
  18.  
  19. // ok
  20. static bool isCoprime(uint num1, uint num2)
  21. {
  22.     while (num1 != 0 && num2 != 0)
  23.     {
  24.         if (num1 > num2)
  25.             num1 %= num2;
  26.         else
  27.             num2 %= num1;
  28.     }
  29.     return num1 + num2 == 1;
  30. }
  31.  
  32. // ok
  33. static uint funEuler(uint n)
  34. {
  35.     return n - 1;
  36. }
  37.  
  38.  
  39. // hope that ok
  40. static uint fastPow(uint value, uint pow)
  41. {
  42.     if (pow == 0)
  43.         return 1;
  44.     uint z = fastPow(value, pow / 2);
  45.     if (pow % 2 == 0)
  46.         return (z * z);
  47.     else
  48.         return value * z * z;
  49. }
  50.  
  51. // nihua ne ok
  52. static bool isPrimitivalRoot(uint p, uint g)
  53. {
  54.     if (!isCoprime(p, g))
  55.         return false;
  56.     uint gg = fastPow(g, funEuler(p) / 2) % p;
  57.     if (gg == 1)
  58.         return false;
  59.     uint l = funEuler(p) / p;
  60.     List<uint> values = new List<uint>();
  61.     for (uint i = 1; i <= funEuler(g); i++)
  62.     {
  63.         if (values.Contains(fastPow(g, i) % p))
  64.             return false;
  65.         values.Add(fastPow(g, i) % p);
  66.     }
  67.     return true;
  68. }
  69.  
  70. // ok
  71. static bool isPrime(uint n)
  72. {
  73.     for (uint i = 2; i * i <= n; ++i)
  74.         if (n % i == 0)
  75.             return false;
  76.     return true;
  77. }
  78.  
  79. /***    Main        ***/
  80.  
  81. Console.Write("Enter p: ");
  82. uint p = Convert.ToUInt16(Console.ReadLine());
  83. while (!isPrime(p))
  84. {
  85.     Console.Write($"{p} is not prime !!!\n" +
  86.                   $"Enter p: ");
  87.     p = Convert.ToUInt16(Console.ReadLine());
  88. }
  89. Console.Write("Enter g: ");
  90. uint g = Convert.ToUInt16(Console.ReadLine());
  91. while (!isPrimitivalRoot(p, g))
  92. {
  93.     Console.Write($"{g} is not primitival root of {p} !!!\n" +
  94.                   $"Enter g: ");
  95.     g = Convert.ToUInt16(Console.ReadLine());
  96. }
  97.  
  98. Console.Write("Enter x: ");
  99. uint x = Convert.ToUInt16(Console.ReadLine());
  100. while (!(1 < x && x < p - 1))
  101. {
  102.     Console.Write($"{x} is not between 1 and n - 1 !!!\n" +
  103.                   $"Enter x: ");
  104.     x = Convert.ToUInt16(Console.ReadLine());
  105. }
  106.  
  107. uint y = fastPow(g, x) % p;
  108. List<uint> publicKey = new List<uint>{y, p, g};
  109. uint privateKey = x;
  110. Console.WriteLine($"Public key: ({publicKey[0]}, {publicKey[1]}, {publicKey[2]})\n" +
  111.                   $"Private key: {privateKey}");
  112.  
  113. Console.Write("Enter M: ");
  114. uint M = Convert.ToUInt16(Console.ReadLine());
  115. while (!(M < p))
  116. {
  117.     Console.Write($"{M} is not smaller than {p} !!!\n" +
  118.                   $"Enter M: ");
  119.     M = Convert.ToUInt16(Console.ReadLine());
  120. }
  121.  
  122. Console.Write("Enter k: ");
  123. uint k = Convert.ToUInt16(Console.ReadLine());
  124. while (!(isCoprime(k, p - 1) && 1 < k && k < p - 1))
  125. {
  126.     Console.Write($"{k} is not coprime with {p - 1} or {k} is not between 1 and {p -1} !!!\n" +
  127.                   $"Enter k: ");
  128.     k = Convert.ToUInt16(Console.ReadLine());
  129. }
  130.  
  131. List<uint> hiddenText = new List<uint> {fastPow(g, k) % p, (fastPow(y, k) * M) % p};
  132. Console.WriteLine($"Hidden text: ({hiddenText[0]},{hiddenText[1]})");
  133.  
  134. Console.Write("Enter x: ");
  135. uint x1 = Convert.ToUInt16(Console.ReadLine());
  136. if (x != x1)
  137.     Console.WriteLine("Secret keys are not equal !!!");
  138.  
  139. uint M1 = (fastPow(y, k) * M) % p * fastPow(fastPow(g, k) % p, p - 1 - x) % p;
  140. Console.WriteLine($"Your text: {M1}");
  141.  
  142.  
  143. Console.ReadKey();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement