Advertisement
Guest User

SimoneUrsula

a guest
May 25th, 2016
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.76 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h> // biblioteca necessária para função time
  4. #include <math.h> // sqrt
  5. main()
  6. {
  7. /*
  8. Criptografar os dados: Gerar a Chave Pública
  9. necessário calcular o N e o e
  10. Cálculo do N
  11. N = p * q: O cálculo do N envolve gerar os número p e q
  12. p = tem que ser um número grande primo gerado de forma aleatória
  13. q = tem que ser um número grande primo gerado de forma aleatória e <> p
  14.  
  15. Cálculo do e
  16. e = calcular seu inverso modular
  17. teste de primalidade (precisa ser primo e usar método)
  18.  
  19. Com os valores de N e e se pode calcular a chave pública
  20. KeyPublic =
  21. */
  22. /* definção das variáveis utilizadas */
  23. long long int p;
  24. long long int q;
  25. long long int n;
  26. int e;
  27. int d;
  28. int Key;
  29. long long int qEuler;
  30.  
  31. /*
  32. utilizado para ser o ponto de partida da função rand() --> semente
  33. */
  34. srand(time(NULL));
  35.  
  36. /* Cálculo do N = p * q
  37. gerar o número p
  38. p = tem que ser um número grande primo gerado de forma aleatória
  39. chama a função criada newNumber() para gerar p
  40. */
  41. p = newNumber();
  42. printf("número p = %d", p);
  43. getwchar();
  44.  
  45. /* gerar o número q
  46. q = tem que ser um número grande primo gerado de forma aleatória
  47. chama a função criada newNumber() para gerar q
  48. q<>p: q tem que ser diferente de p
  49. função criada newNumber() não gera dois número iguais
  50. */
  51. q = p;
  52. while (p == q) q = newNumber();
  53. /*
  54. imprime valor q
  55. */
  56. printf("número q = %d", q);
  57. getwchar();
  58.  
  59. /*
  60. Calculo do número N
  61. N = p * q
  62. */
  63. n = p * q;
  64. /*imprime n */
  65. printf("número n = %d ", n);
  66. getwchar();
  67.  
  68. /*
  69. Cálculo do número e
  70. gerar um número pequeno primo, impar e relativamente primo $\o(N)$
  71. Para gerar o número será utilizado a função newNumber(), essa função trabalha com número grande
  72. Para verificar se o número é relativamente primo $\o(N)$, utilizar o algoritmo estendido de Euclides
  73. Para Algoritmo estendido de euclides será utilizado a função modEuclides() criada
  74. primo relativo: utilizado quociente euler: (p-1)*(q-1)
  75. */
  76.  
  77. qEuler = (p - 1) * (q - 1);
  78. /*imprime qEuler */
  79. e = keyE(qEuler, n);
  80. /*imprime e*/
  81. printf("número e = %d ", e);
  82. getwchar();
  83.  
  84.  
  85. /* KeyPublic - temos n, e -
  86. podemos aplicar a fórmula c = m ^ e mod n
  87. m é o valor numérico da letra
  88. para criptografar é aplicar a fórmula a cada letra
  89. */
  90. /* Término da Criptografia dos dados*/
  91.  
  92. /*
  93. Descriptografar dos dados: Gerar a Chave Privada
  94. necessário o N e o d, só calcular o d, o N é o mesmo da Chave Pública
  95. N: é o mesmo da Chave Pública
  96.  
  97. Cálculo do d
  98. d = calcular seu inverso modular, através do algoritmo estendido de Euclides
  99. teste de primalidade (precisa ser primo e usar método)
  100. */
  101.  
  102. /*Tem-se o e e o qEuler.
  103. Para o RSA o X deve ser 1, pois d*e mod qq = 1
  104. (peguei pronto o euclides_ext
  105. apenas renomeei aqui mdcEuclidesEstendido
  106. */
  107. d = keyD(e, qEuler);
  108. /*imprime d */
  109. printf("número d = %d \n", d);
  110. getwchar();
  111.  
  112. /* KeyPrivate - temos n, d -
  113. podemos aplicar a fórmula c = m ^ e mod n
  114. */
  115. /* Término da Descriptografia dos dados */
  116.  
  117. /*
  118. Com os valores de n, e, d
  119. Ter um menu com opções de criptografar, descriptografar e para quebra da chave
  120.  
  121. opção Criptografar: poder escolher arquivo a ser criptogrado
  122. Aplicar a chave pública, n e e ...
  123. mostrar a mensagem criptograda
  124.  
  125. opção Quebra de chave:
  126. mostrar quanto tempo leva para quebrar e depois o arquivo
  127.  
  128. opção Descriptografar: descriptografa, temos n e d
  129. mostra a mensagem descriptografada
  130. */
  131.  
  132. /*
  133. Teste de Força Bruta
  134. */
  135. printf("fatorar n = %d \n", n);
  136. forcaBruta(n);
  137.  
  138. return EXIT_SUCCESS;
  139. }
  140.  
  141. /*
  142. Função newNumber para gerar número de forma aleatória e primo
  143. A função gera um número aleatório através da função rand() do c, ponto de partida é calculado pela função srand() do c, usei hora
  144. Entrada: não tem
  145. Saida: número grande primo gerado aleatoriamente
  146. */
  147. newNumber()
  148. {
  149. /* definação das variaveis utilizadas
  150. /* vaiável n: tipo de dados inteiro grande
  151. gera o número inteiro grande aleatoriamente
  152. a função isPrimi(n) verifica se o número gerado é primo
  153. */
  154. long long int number;
  155. int isPrimi;
  156. isPrimi= 0; /* varíavel começa com zero, só será 1 quando o número gerado for primo
  157. /*
  158. executa o loop while da linha 78 - 90 até o número inteiro grande gerado aleatoriamente ser primo
  159. */
  160. while (isPrimi == 0 )
  161. {
  162. /* função rand() gera um número aleatório
  163. parte do ponto de partida calculado pela função srand
  164. sendo o calculo baseado na hora, em segundo ... desde 1970 até a data atual
  165. */
  166. number = rand();
  167. /*
  168. verifica se o número gerado aleatoriamente é primo
  169. ser primo não significa que passou pelo teste da primalidade,
  170. mas para o teste a premissa é ser primo
  171. */
  172. isPrimi = Primi(number);
  173. }
  174.  
  175. return number; /* retorna o número gerado */
  176. }
  177.  
  178. /*
  179. Função isPrimi()? verifica se o número é primo
  180. Para um nro ser primo precisa ser divisível por ele mesmo e por 1
  181. ?? Verificar se tem algo mais, Cormen fala algo que isso é um pseudoprimo(), precisa utilizar Fermat ou outro método além desse
  182. para o Teste de Prmalidade ??
  183. Entrada: nro a ser verificado se é primo[
  184. Saída: 1 se for primo e 0 se não for primo
  185. */
  186. int Primi(long long int number)
  187. {
  188. int i = 0;
  189. int nroVezes = 0;
  190. /*
  191. se o nrovezes = 2 é porque o nro é primo sqrt(number)
  192. se o nrovezes = 2 não precisa continuar a divisão porque o nro não é primo - performance
  193. */
  194. for(i = 1; (i < number) && (nroVezes < 3); i++)
  195. if (number % i == 0) nroVezes += 1;
  196.  
  197. /* sai do loop */
  198. if (nroVezes = 2)
  199. return 1;
  200. else return 0;
  201.  
  202.  
  203.  
  204. }
  205.  
  206. /*
  207. Função KeyE: calcula o e
  208. Enrada: recebe o qeuler -> já calculado
  209. Saida: devolve o cálculo do e
  210. */
  211. keyE(long long int qEuler, long long int n)
  212. {
  213. /*
  214. Definição das variáveis
  215. */
  216. int key = 0;
  217. int ok = 0;
  218. int mdcE = 0;
  219.  
  220. /*
  221. chave pública tem que ser um pequeno gerado aleatoriamente, chama função criada newNumber()
  222. número precisa ser primo, a propria rotina newNumber() já faz este teste
  223. número precisa ser impar, o while abaixo será executado enquando o número gerado não for impar
  224. no while é pego o resto da divisão -: no c usa %, se ele for = 0 é par
  225. a parada do while é quando o número for impar
  226. */
  227. while (ok != 1) { /* Impar e MDC( e, qeuler ) == 1 */
  228. key = newNumber();
  229. /* ser impar */
  230. if ((key % 2 != 0) && (key > 1) && key < (n-1))
  231. {
  232.  
  233. /*
  234. mdc - para ver se primo relativo
  235. o e ter que ser um um primo relativo
  236. para isso calculamos o mdc entre o número e o quociente de euler recebido por parâmentro
  237. Chamar a função criada modEuclides() passando o e e qeuler
  238. O número e deve ser calculado de maneira que o MDC (máximo divisor comum)
  239. entre e e qeuler seja 1, dessa forma, e seja relativamente primo de qeuler.
  240. MDC( e, qeuler ) == 1 e o número gerado tem que estar entre 1 e n-1
  241. */
  242.  
  243.  
  244. mdcE = mdc(qEuler,key );
  245. //printf("número mdcE %d \n", mdcE);
  246. //getwchar();
  247.  
  248. if (mdcE == 1) ok = 1;
  249. }
  250. }
  251. return key;
  252. }
  253.  
  254. /*
  255. Função KeyE: calcula o d
  256. Enrada: recebe o qeuler e o e-> já calculados
  257. Saida: devolve o cálculo do d
  258. */
  259. keyD(int e, long long int qEuler)
  260. {
  261. /*
  262. Definição das variáveis
  263. */
  264. int mdcD = 0;
  265. mdcD = mdcEuclidesEstendido(e, qEuler, 1);
  266. /*
  267. chamando a função que calcula o d
  268. Retorna o nro da expressao ção que calcula o d. Ela retorna um número que case na
  269. expressão: d*e mod qq = X
  270.  
  271. Fazer o teste para ver se está ok
  272. */
  273. //printf("número e = %d \n", e);
  274. // printf("número qEuler = %d \n", qEuler);
  275. //printf("número mdcD = %d \n", mdcD);
  276. //getwchar();
  277.  
  278.  
  279. return mdcD;
  280.  
  281. }
  282.  
  283.  
  284. /*
  285. Função para calcuar o inverso modular
  286. Entrada: 2 parametros
  287. Saida: r: máximo divisor comum
  288. */
  289. mdc(long long int a, long long int b )
  290. {
  291. /*
  292. Definição das variáveis
  293. */
  294. long long int r;
  295. //r = a%b;
  296. r = mod(a, b);
  297. a = b;
  298. b = r;
  299.  
  300. /*
  301. Se o r não for zero, vai entrar no loço de repetição
  302. laço de repetição até o r for diferente de zero - condição de parada
  303. */
  304. while (r != 0) {
  305. // r = a%b;
  306. r = mod(a, b);
  307. a = b;
  308. b = r;
  309. }
  310. // printf("número r = %d\n ", r);
  311. // printf("número a = %d \n", a);
  312. return a; /* maior divisor comum */
  313. }
  314.  
  315.  
  316.  
  317. /*
  318. TITULO: Algoritmo de euclides extendido (calcula o D RSA)
  319. DATA: 13/Agosto/2009
  320. */
  321.  
  322.  
  323. /* Aritmética modular é também considerada como o "algoritmo do relógio".
  324.  
  325. Ao extrair o modulo 12, como resposta possível pode-se ter números de
  326. 0 a 11. Nunca negativo, pois a ideia é de um relógio com 12 posições, sendo
  327. a primeira o zero e a última o 11.
  328.  
  329. Porém o operador de módulo do C (operador %) computa apenas o resto da divisão
  330. e gera números negativos. Em C:
  331.  
  332. -2 mod 12 = -2 (não está entre 0 e 11)
  333. 2 mod -12 = 2 (não está entre -11 e 0)
  334.  
  335. O C dizer que -2 mod 12 é -2 significa dizer que ele está a -2 de distância do
  336. final do relógio, ou seja, está em 10 (o início e também o final do relógio é o zero).
  337.  
  338. Dizer que 2 mod -12 significa um relógio ao contrário (0, -1, -2, -3, .. -11, andando
  339. no sentido anti-horário) e que o valor 2 está a 2 posições de distância do 0, ou seja,
  340. está em -10.
  341.  
  342. Nesta artimética modular o resultado da operação PRECISA SER do mesmo sinal
  343. do divisor.
  344.  
  345. Observou-se que o operador de módulo do python (%) não tem este comportamento,
  346. calculando o módulo não negativo. A biblioteca bn.h do openssl possui ambos,
  347. tanto a função BN_mod que simplesmente retorna o resto da divisão (comportamento
  348. igual ao %) como a função BN_nnmod que calcula o módulo não negativo.
  349.  
  350. Nesta versão em C resolveu-se fazer uma pequena correção na resposta dada pelo
  351. operador de módulo, pois o algoritmo de euclides precisa do módulo positivo.
  352. */
  353. mod(long long int a, long long int b)
  354. {
  355. long long int r = a % b;
  356.  
  357. /* Uma correçã é necessária se r e b não forem do mesmo sinal */
  358.  
  359. /* se r for negativo e b positivo, precisa corrigir */
  360. if ((r < 0) && (b > 0)) return (b + r);
  361.  
  362. /* Se ra for positivo e b negativo, nova correcao */
  363. if ((r > 0) && (b < 0)) return (b + r);
  364.  
  365. return (r);
  366. }
  367.  
  368.  
  369. /*
  370. Entrada: 3 parametros
  371. Saida: r: máximo divisor comum
  372. */
  373. mdcEuclidesEstendido(long long int a, long long int b, long long int c)
  374. {
  375. long long int r;
  376. r = mod(b, a);
  377.  
  378. if (r == 0){
  379. return (mod((c / a), (b / a))); // retorna mod((c/a) , (b/a))
  380. }
  381.  
  382. return ((mdcEuclidesEstendido(r, a, -c) * b + c) / (mod(a, b)));
  383. }
  384.  
  385. /*
  386. Teste de Força Bruta
  387. Ataques Matemáticos
  388. Três são os ataques matemáticos:
  389. * Fatorar n em dois números primos. Isto possibilita calcular Primo relativo n = (p-1)(q-1),
  390. e com isso determinar o valor de d = e-1 (mod f n)
  391. *Determinar Primo relativo n diretamente, sem determinar p e q,
  392. permitindo novamente determinar o valor de d = e-1
  393. (mod Primo relativo n)
  394. * Determinar d sem descobrir Primo relativo n.
  395. */
  396. forcaBruta(long long int n)
  397. {
  398. long long int fat;
  399.  
  400. printf("\nFatorial calculado: %d", fat);
  401. getchar();
  402. for(fat = 1; n > 1; n = n - 1){
  403. fat = fat * n;
  404. // printf("\nFatorial calculado: %d", fat);
  405. // getchar();
  406. }
  407. return 0;
  408. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement