Criptografia de chave pública é um lindo conceito, mas depende de ser capaz de determinar funções FP e FS que funcionem corretamente juntas. FP é fácil para qualquer um computar e FS é fácil somente para o portador da chave secreta computar. Deno- minamos um esquema que cumpre esses critérios criptossistema de chave pública, e o criptossistema RSA, ou apenas RSA,4 é um desses esquemas.
O RSA depende de diversas facetas da teoria dos números, muitas das quais estão relacionadas à aritmética modular. Em aritmética modular, escolhemos um inteiro positivo, digamos n, e sempre que chegamos a n imediatamente voltamos a 0. É como aritmética comum com inteiros, mas sempre dividimos por n e tomamos o resto. Por exemplo, se estivermos trabalhando com módulo 5, os únicos valores possíveis são 0, 1, 2, 3, 4 e 3 + 4 = 2, visto que 7 dividido por 5 dá resto 2. Vamos definir um operador, mod, para calcular restos, de modo que possamos dizer 7 mod 5 = 2. Aritmética modular é como aritmética de relógio, porém substituindo 12 por 0 no mostrador do relógio. Se você foi dormir às 11 horas e dormir oito horas, acordará às 7: (11 + 8) mod 12 = 7.
O que é particularmente interessante na aritmética modular é que podemos adotar operações mod no meio de expressões e não mudar o resultado:5
+ = + = = a b n a n b n n ab n a n b n n a n a n n
( )mod (( mod ) ( mod ))mod ; mod (( mod )( mod ))mod ; mod ( mod ) mod .
b b
Para qualquer inteiro x, temos que xn mod n é 0.
Além disso, para que o RSA cumpra os critérios para um criptossistema de chave pública, duas propriedades da teoria dos números relacionadas a números primos devem valer. Como você deve saber, um número primo é um inteiro maior que 1 que tem somente dois fatores inteiros: 1 e ele mesmo. Por exemplo, 7 é primo, mas 6 não é, já que pode ser fatorado como 2·3. A primeira propriedade à qual RSA recorre é que, se você tiver um número que é o produto de dois números primos grandes secretos, ninguém mais pode (a+b)modn=((amodn)+(bmodn))m
odn;abmodn=((amodn)(bmodn))m-
odn;abmodn=(amodn)bmodn:
4 O nome deve-se a seus inventores, Ronald Rivest, Adi Shamir e Leonard Adelman.
5 Como exemplo, para ver que ab mod n = ((a mod n)(b mod n))mod n, suponha que a mod n = x e
b mod n = y. Então existem inteiros i e j tais que a = ni + x e b = nj + y e, portanto,
= + + = + + + = + + + = = ab n ni x nj y n n ij xnj yni xy n n ij n xnj n yni n xy n n xy n a n b n n mod ( )( )mod ( )mod
(( mod ) ( mod ) ( mod ) ( mod ))mod
mod
(( mod )( mod ))mod
2 2 abmodn=(ni+x)(nj+y)modn =(n²ij+xnj+yni+xy)modn=( (n²ijmodn)+(xnjmodn)+(yni- modn)+(xymodn))modn=xy- modn=((amodn)(bmodn))modn
determinar esses fatores em qualquer quantidade de tempo razoável. Lembre-se de que dissemos no Capítulo 1 que alguém poderia testar todos os divisores ímpares possíveis até a raiz quadrada do número, mas se o número for grande — centenas de milhares de dígitos −, sua raiz quadrada tem metade desse número de dígitos, o que ainda pode ser muito grande. Embora teoricamente alguém possa encontrar um desses fatores, os recursos exigidos (tempo e/ou poder de computação) tornariam impraticável achar um fator.6
A segunda propriedade é que, embora fatorar um número primo grande seja difícil, não é difícil determinar se um número grande é primo. Você pode achar que é impos- sível determinar que um número não é primo — isto é, o número é composto — sem determinar, no mínimo, um fator não trivial (um fator que não é 1 nem é o próprio número). Na verdade, é possível fazer isso. Um modo é o teste de primalidade AKS,7 o primeiro algoritmo a determinar se um número de n bits é primo no tempo O n
(
c)
para alguma constante c. Embora o teste de primalidade AKS seja considerado teoricamente eficiente, ainda não é prático para números grandes. Em vez disso, podemos usar o teste de primalidade Miller-Rabin. A desvantagem do teste Miller-Rabin é que ele pode cometer erros e declarar que um número é primo quando na verdade ele é composto (todavia, se o teste declarar que um número é composto, o número é definitivamente composto). A boa notícia é que a taxa de erro é 1 em 2s, onde podemos escolher o valor positivo de s quequisermos. Portanto, se estivermos dispostos a conviver com um erro em, digamos, cada 250 testes, podemos determinar com certeza quase perfeita se um número é primo. Lem-
bre-se de que dissemos no Capítulo 1 que 250 é aproximadamente um milhão de bilhões,
ou aproximadamente 1.000.000.000.000.000. Se você ainda se sentir desconfortável com um erro em 250 testes, com um pouco mais de esforço pode transformá-lo em um erro
em 260 testes; 260 é aproximadamente mil vezes maior que 250. Isso porque o tempo para
executar o teste Miller-Rabin aumenta apenas linearmente com o parâmetro s e, portanto, aumentar s de 10, isto é, de 50 para 60, aumenta o tempo de execução somente em 20%, mas diminui a taxa de erro por um fator de 210, que é igual a 1.024.
Eis como eu me prepararia para usar o criptossistema RSA. Depois de vermos como o RSA funciona, temos de abordar vários detalhes.
1. Escolha aleatoriamente dois números primos muito grandes, p e q, que não são iguais um ao outro. Quão grande é muito grande? No mínimo, 1.024 bits cada ou, no mínimo, 309 dígitos decimais. Maior é melhor ainda.
2. Compute n = pq. Esse é um número que tem, no mínimo, 2.048 bits ou, no mínimo, 618 dígitos decimais.
3. Compute r=(p−1)(q−1), que é quase tão grande quanto n.
4. Selecione um inteiro ímpar pequeno e que seja relativamente primo de r: o único divisor comum de e e r deve ser 1. Qualquer tal inteiro pequeno serve.
5. Compute d como o inverso multiplicativo de e, módulo r. Isto é, ed mod r deve ser igual a 1.
Onc
r=(p−1)(q−1)
6 Por exemplo, se o número tiver 1.000 bits, sua raiz quadrada terá 500 bits, e pode ser tão grande
quanto 2500. Mesmo que alguém pudesse testar um trilhão de trilhões possíveis divisores por segundo,
o Sol já teria se apagado há muito tempo, antes de esse alguém alcançar 2500. 7 O nome deve-se a seus inventores, Manindra Agrawal, Neeraj Kayal e Nitin Saxena.
6. Declare que minha chave pública RSA é o par P = (e,n).
7. Mantenha o par S = (d, n) como minha chave secreta RSA e não a revele a ninguém. 8. Defina as funções FP e FS por
= = F x x n F x x n ( ) mod ; ( ) mod : p e s d
Essas funções podem operar sobre um bloco de texto comum ou sobre um bloco de texto cifrado, cujos bits interpretamos como representativos de inteiros grandes.
Vamos examinar um exemplo, mas usando números pequenos para que possamos entender o que está acontecendo.
1. Escolha os números primos p = 17 e q = 29. 2. Compute n = pq = 493.
3. Compute r = (p − 1)(q − 1) = 448.
4. Selecione e = 5, que é relativamente primo de 448 (ou seja, são primos entre si). 5. Compute d = 269. Para verificar: ed = 5·269 = 1345 e, portanto,
= = ⋅ + =
edmodr 1345 mod 448 (3 448 1) mod 448 1. 6. Declare que minha chave pública RSA é P = (5,493). 7. Mantenha S = (269,493) como minha chave secreta RSA. 8. Como exemplo, vamos computar FP (327):
= = =
Fp(327) 327 mod 493 3.738.856.210.407 mod 493 2595
Se computarmos FS (259) = 259259 3, devemos obter 327 de volta. Obtemos, mas na
verdade você não quer ver todos os dígitos na expressão 259269. Você pode procurar
na Internet uma calculadora de precisão arbitrária e testar esse número com ela (eu testei). Então, novamente, como estamos trabalhando com aritmética modular, não precisamos computar o valor real de 259269; podemos expressar todos os resultados
intermediários módulo 493; portanto, se você quisesse, poderia começar com o produto 1 e fazer o seguinte 269 vezes: multiplique o que você tem por 259 e tome o produto módulo 493. Você obterá um resultado de 327 (eu fiz isso, ou melhor, um programa de computador que eu escrevi fez).
Damos a seguir os detalhes a abordar para montar e usar o RSA: • Como se trabalha com números que têm centenas de dígitos?
• Embora não seja um obstáculo testar se um número é primo, como eu sei que posso encontrar números primos grandes em uma quantidade de tempo razoável? • Como eu acho e de modo que e e r são relativamente primos?
• Como eu computo d de modo que seja o inverso multiplicativo de e, módulo r? • Se d é grande, como eu computo xd mod n em uma quantidade de tempo razoável?
• Como eu sei que as funções FP e FS são inversas uma da outra?