Advertisement
sve_vash

Untitled

Jun 12th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.21 KB | None | 0 0
  1. #include <iostream>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <string>
  6. #include <vector>
  7. #include <ctime>
  8. #include "InfInt.h"
  9.  
  10.  
  11. /////35742549198872617291353508656626642567
  12. /////359334085968622831041960188598043661065388726959079837
  13.  
  14. /////19417091861583877910490308387583607491604123508745646291616809803288063839914277427844396698129011691681486302256267788924072838297914608887914403084151733
  15.  
  16. //////24848401783389118830883536511746092086211663600625721820978008915738591540866418413678832001037346516549789719402507891354266759914154881730210759626584581
  17.  
  18.  
  19.  
  20. //////////генерация
  21. InfInt generate() {
  22. InfInt t = 1;
  23. for (int i = 0; i < 512; i++) {
  24. t *= 2;
  25. t += rand() % 2;
  26. }
  27. return(t);
  28. }
  29. ///////////
  30.  
  31. ///////быстрое возведение в степень по модулю
  32. InfInt modPow(InfInt base, InfInt exponent, InfInt mod) {
  33. InfInt x = 1;
  34. InfInt y = base;
  35. while (exponent > 0) {
  36. if (exponent % 2 == 1)
  37. x = (x * y) % mod;
  38. y = (y * y) % mod;
  39. exponent = exponent / 2;
  40. }
  41. return x % mod;
  42. }
  43. ////////
  44.  
  45.  
  46. ////////Миллер-Рабин
  47. bool MillerRabinTest(const InfInt n1, int k) {
  48. InfInt n = n1;
  49. // если n == 2 или n == 3 - эти числа простые, возвращаем true
  50. if (n == 2 || n == 3)
  51. return true;
  52.  
  53. // если n < 2 или n четное - возвращаем false
  54. if (n < 2 || n % 2 == 0)
  55. return false;
  56.  
  57. // представим n − 1 в виде (2^s)·t, где t нечётно, это можно сделать последовательным делением n - 1 на 2
  58. InfInt t = n - 1;
  59.  
  60. int s = 0;
  61.  
  62. while (t % 2 == 0) {
  63. t /= 2;
  64. s += 1;
  65. }
  66.  
  67. // повторить k раз
  68. for (int i = 0; i < k; i++)
  69. {
  70. // выберем случайное целое число a в отрезке [2, n − 2]
  71.  
  72. InfInt a;
  73.  
  74. do {
  75. a = generate() - 100;
  76. }
  77. while (a < 2 || a >= n - 2);
  78.  
  79. // x ← a^t mod n, вычислим с помощью возведения в степень по модулю
  80. InfInt x = modPow(a, t, n);
  81.  
  82. // если x == 1 или x == n − 1, то перейти на следующую итерацию цикла
  83. if (x == 1 || x == n - 1)
  84. continue;
  85.  
  86. // повторить s − 1 раз
  87. for (int r = 1; r < s; r++) {
  88. // x ← x^2 mod n
  89. x = modPow(x, 2, n);
  90.  
  91. // если x == 1, то вернуть "составное"
  92. if (x == 1)
  93. return false;
  94.  
  95. // если x == n − 1, то перейти на следующую итерацию внешнего цикла
  96. if (x == n - 1)
  97. break;
  98. }
  99.  
  100. if (x != n - 1)
  101. return false;
  102. }
  103.  
  104. // вернуть "вероятно простое"
  105. return true;
  106. }
  107. //////////
  108.  
  109. //////////НОД
  110. InfInt GCD(InfInt num1, InfInt num2) {
  111. while ((num1 != 0) && (num2 != 0)) {
  112. if (num1 > num2) {
  113. num1 = num1 % num2;
  114. }
  115. else {
  116. num2 = num2 % num1;
  117. }
  118. }
  119. return (num1 + num2);
  120. }
  121. ///////////
  122.  
  123. //////////
  124. InfInt calculateE(InfInt fi) {
  125. // Выбирается целое число e ( 1 < e < fi ) // взаимно простое со значением функции Эйлера (fi)
  126.  
  127. for (InfInt e = 2; e < fi; e++) {
  128. if (GCD(e, fi) == 1) {
  129. return e;
  130. }
  131. }
  132. return -1;
  133. // InfInt e;
  134. // do {
  135. // e = generate();
  136. // } while (e != fi && GCD(e, fi) == 1);
  137. // return e;
  138. //&& !MillerRabinTest(e, 20)
  139. }
  140. //////////
  141.  
  142. //////////
  143. InfInt calculateD(InfInt e, InfInt fi) {
  144. // Вычисляется число d, мультипликативно обратное к числу e по модулю φ(n), то есть число, удовлетворяющее сравнению:
  145. // d ⋅ e ≡ 1 (mod φ(n))
  146.  
  147. InfInt d;
  148. InfInt k = 1;
  149.  
  150. while (true) {
  151. k += fi;
  152.  
  153. if (k % e == 0) {
  154. d = (k / e);
  155. return d;
  156. }
  157. }
  158. }
  159. ///////////
  160.  
  161. ///////////
  162. InfInt encrypt(InfInt i, InfInt e, InfInt n) {
  163. InfInt current, result;
  164.  
  165. current = i;
  166. result = 1;
  167.  
  168. result = modPow(current, e, n);
  169.  
  170. return result;
  171. }
  172. //////////
  173.  
  174. //////////
  175. InfInt decrypt(InfInt i, InfInt d, InfInt n) {
  176. InfInt current, result;
  177.  
  178. current = i;
  179. result = 1;
  180.  
  181. result = modPow(current, d, n);
  182.  
  183. return result;
  184. }
  185. ///////////
  186.  
  187. ///////////
  188. int main() {
  189. srand(unsigned(time(nullptr)));
  190.  
  191. //Cоздание открытого и секретного ключей
  192.  
  193. //1. Выбираются два различных случайных простых числа p и q заданного размера
  194.  
  195. ///////////
  196. InfInt p;
  197.  
  198. do {
  199. p = generate();
  200. } while (!MillerRabinTest(p, 20));
  201.  
  202. //p = "1303253110366565616703329909559";
  203.  
  204. std::cout << "p = " << p << "\n";
  205.  
  206. InfInt q;
  207.  
  208. do {
  209. q = generate();
  210. } while (!MillerRabinTest(q, 20));
  211.  
  212. //q = "359334085968622831041960188598043661065388726959079837";
  213.  
  214. std::cout << "q = " << q << "\n";
  215. //////////
  216.  
  217. // 2. Вычисляется их произведение n = p ⋅ q, которое называется модулем.
  218. InfInt n = p * q;
  219. std::cout << "n = " << n << "\n";
  220.  
  221. // 3. Вычисляется значение функции Эйлера от числа n: φ(n) = (p−1)⋅(q−1)
  222. InfInt fi = (p - 1)*(q - 1);
  223. std::cout << "fi = " << fi << "\n";
  224.  
  225. // 4. Выбирается целое число e ( 1 < e < φ(n) ), взаимно простое со значением функции Эйлера (t)
  226. // Число e называется открытой экспонентой
  227. InfInt e = calculateE(fi);
  228. std::cout << "e = " << e << "\n";
  229.  
  230. // 5. Вычисляется число d, мультипликативно обратное к числу e по модулю φ(n), то есть число, удовлетворяющее сравнению:
  231. // d ⋅ e ≡ 1 (mod φ(n))
  232. InfInt d = calculateD(e, fi);
  233. std::cout << "d = " << d << "\n";
  234.  
  235. // 6. Пара {e, n} публикуется в качестве открытого ключа RSA
  236. // 7. Пара {d, n} играет роль закрытого ключа RSA и держится в секрете
  237.  
  238.  
  239. std::cout << "ENTER THE MESSAGE\n";
  240.  
  241. std::string msg;
  242. getline(std::cin, msg);
  243. std::vector <InfInt> encrypted(msg.length());
  244.  
  245. //шифрование c=m^e(mod n)
  246. for (long long int i = 0; i < msg.length(); i++) {
  247. encrypted[i] = encrypt(msg[i], e, n);
  248. }
  249.  
  250. std::cout << "\nTHE ENCRYPTED MESSAGE IS: ";
  251.  
  252. for (long long i = 0; i < msg.length(); i++) {
  253. std::cout << (char)encrypted[i].toInt();
  254. }
  255.  
  256. std::vector <InfInt> decrypted(msg.length());
  257. //дешифрование c^d = (m^e)^d = m(mod n)
  258. for (long long i = 0; i < msg.length(); i++) {
  259. decrypted[i] = decrypt(encrypted[i], d, n);
  260. }
  261.  
  262. std::cout << "\nTHE DECRYPTED MESSAGE IS: ";
  263. for (long long int i = 0; i < msg.length(); i++) {
  264. std::cout << (char)decrypted[i].toInt();
  265. }
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement