Professional Documents
Culture Documents
2. METODOLOGIA
As etapas deste trabalho seguiram a ordem abaixo:
Como já mencionado, a redução modular consiste em encontrar o resto da divisão do número pelo
módulo pretendido. O algoritmo clássico de redução modular em precisão múltipla é aplicar o algoritmo
de divisão ao número e ao módulo e tomar o resto. Entretanto, esse é o algoritmo básico que demanda
maior esforço computacional, devido à grande quantidade requerida de subtrações e multiplicações em
precisão múltipla. Existem alguns algoritmos de redução modular 1que procuram evitar essa divisão. Na
adição e subtração modulares, quando os inteiros envolvidos são menores que o módulo m, a redução é
bastante simples. Na adição, se a soma for menor que m, o resultado da redução é ela própria, se for
maior, subtrai-se dela m, apenas uma vez. Na subtração, se o resultado for positivo, ele é mantido, se for
negativo, soma-se m. Se estiverem sendo usadas apenas variáveis sem sinal, pode-se fazer a comparação
entre as magnitudes e, se a do minuendo for a menor, soma-se m a ele antes da subtração.
Na multiplicação, como o resultado pode ser muitas vezes maior que o módulo, é bastante usado o
algoritmo clássico. Há métodos que são mais eficientes em determinadas situações, como a Redução de
Montgomery, em exponenciações, e a Redução de Barrett, quando se fazem muitas reduções com o
mesmo módulo. Todos esses algoritmos são descritos na referência [1].
Graças a uma propriedade das operações modulares, (a.b) mod m = (a mod m . b mod m) mod m
(a mod m é a redução de a módulo m), é possível se fazer exponenciações modulares no computador. A
maneira mais óbvia para isso seria calcular xy mod m com y multiplicações e reduções sucessivas de x. No
entanto, o fato de o expoente poder ter até milhares de bits torna essa operação inviável.
O método mais clássico de exponenciação modular rápida é a exponenciação binária. Seja A a
variável onde será guardado o resultado de xy mod m e S uma variável auxiliar. Primeiramente, atribui-se
1 à variável A e x a S. Se o bit menos significativo de y for 1 (y ímpar), multiplica-se A por S. Em
seguida, divide-se y por 2 (essa divisão é apenas um deslocamento para a direita da representação binária
de y), atribui-se a S o valor de S2 mod m e, se o bit menos significativo do novo valor de y for 1,
multiplica-se novamente A por S. Repete-se esse procedimento até o valor de y ser zero e retorna-se o
valor de A (na segunda iteração, S será igual a x2 mod m; na terceira, x4 mod m, e assim por diante). O
número de iterações será o número de bits de y.
Há outros métodos mais eficientes, como a exponenciação em blocos de k bits e a exponenciação
de Montgomery, que evita o algoritmo clássico de divisão nas reduções modulares. Além desses, há os
algoritmos de expoente fixo e os de base fixa, vantajosos quando se fazem muitas exponenciações com o
mesmo expoente e com a mesma base, respectivamente. Os algoritmos de expoente fixo são úteis na
codificação e decodificação do RSA e na decodificação do ElGamal. Os algoritmos de base fixa são úteis
na codificação do ElGamal. Todos os métodos aqui mencionados estão descritos na referência [1].
Além das mencionadas acima, as outras aplicações de interesse criptográfico estudadas foram o
teorema chinês do resto, enunciado na referência [1], e a determinação do máximo divisor comum, com
destaque para o algoritmo de Euclides estendido, que é útil devido à sua possível utilização para encontrar
o inverso de um número x módulo m. x-1 mod m é um número y entre 1 e m – 1 tal que (x.y) mod m = 1.
Ele só existe se mdc (x,m) = 1 e, se existir, é único. Esse conceito é importantíssimo para a criptografia e,
neste trabalho, é usado no RSA.
4. ESTRUTURAS DE DADOS
5. BIBLIOTECA GMP
A biblioteca GMP, cujo manual é a referência [5], possui algoritmos eficientes de precisão
múltipla reunidos em funções prontas, as quais necessitam apenas serem chamadas. Pode operar com
inteiros, racionais e números de ponto flutuante e as funções inteiras, que são as de interesse para a
criptografia, são aproximadamente 150. Ela foi incorporada ao compilador Visual C++ 7.0 e usada na
implementação dos cifrários RSA e ElGamal.
A GMP define o tipo inteiro de precisão múltipla, de tamanho variável e expansível, como mpz_t
e todas as funções inteiras começam com mpz_. Essas variáveis precisam ser inicializadas e, quando não
forem mais usadas, terem seus espaços limpos. Um exemplo de função inteira é mpz_powm (mpz_t rop,
mpz_t base, mpz_t exp, mpz_t mod), que é a exponenciação modular e atribui a rop o valor de
baseexp mod mod. Por convenção, a variável de saída é sempre o primeiro argumento. As variáveis mpz_t
já são de chamada por referência, por isso, elas podem ser passadas a funções criadas pelo usuário e ter
seus valores alterados dentro da função sem necessidade da passagem de ponteiros.
A GMP possui também comandos de entrada e saída, respectivamente gmp_scanf e gmp_printf,
que lêem e imprimem números grandes na sua representação normal em base 10. Com o acréscimo da
biblioteca stdio.h, a GMP pode também ler e imprimir os números grandes em arquivos, em qualquer base
de 2 a 36, sendo que essa última utiliza os dígitos de 0 a 9 e todas as letras do alfabeto inglês. Com esses
comandos e mais as funções de operações internas, a implementação dos cifrários se tornou bastante
simples.
6.1. RSA
Para implementar um sistema RSA, primeiramente uma entidade A gera dois números primos
aleatórios grandes p e q e os multiplica, dando origem ao número n. Em seguida, ela calcula φ = (p-1)(q-1)
e gera um número aleatório e menor que φ tal que mdc (e,φ) = 1. Depois disso, A calcula d = e-1 mod φ. A
chave pública é {e,n} e a chave privada é {d,n}.
Para criptografar uma mensagem m, uma entidade B adquire a chave pública de A, calcula c = me
mod n e envia c para A. Para decifrá-la, A calcula m = cd mod n. A segurança desse método está na
dificuldade em decompor um número grande em fatores primos, principalmente se esses fatores também
forem grandes. Se alguém conseguisse descobrir p e q a partir de n, poderia calcular φ e, como e é público,
calcularia d usando o algoritmo de Euclides estendido. Para que o RSA seja seguro, e e d não devem ser
pequenos.
6.2. ElGamal
No ElGamal, todas as entidades podem ter os mesmos números p e α, sendo p um número primo
grande e α um gerador de Zp* (conjunto {x | 1 ≤ x ≤ p – 1}). Gerador de Zp* é um número α tal que a
função αx mod p seja injetora nesse conjunto. Então, uma entidade A gera um número aleatório a entre 1 e
p – 1 e calcula β = αa mod p. A chave pública será {β,p,α} e a chave privada, {a}.
Para cada m, B gera um número aleatório k e calcula γ = αk mod p e δ = (m.βk) mod p, enviando,
em seguida, {γ,δ} para A, que decifra a mensagem calculando m = (γp – 1 – a. δ) mod p (γp – 1 – a é igual a α-ak
e δ é igual a m.αak). A segurança do ElGamal está baseada na dificuldade em se tirar logaritmos discretos
de números grandes, ou seja, de se obter a a partir de β, p e α (a = logαβ mod p). a e β devem ser grandes,
além disso, deve-se escolher um k diferente para cada m.
7. CONCLUSÃO
Analisando os fatores de segurança dos cifrários apresentados, conclui-se que a aritmética de
precisão múltipla é uma necessidade para a criptografia moderna devido ao crescente avanço dos
computadores, que se tornam capazes de fazer uma criptoanálise cada vez mais rápida, para números cada
vez maiores. Alguns dos algoritmos estudados são bastante eficientes e vários deles estão reunidos na
biblioteca GMP, que facilita muito a implementação dos sistemas criptográficos. Para um processador de
32 bits, a maior base possível em uma programação de alto nível é 216, esse número, aliado a um bom
algoritmo, já torna viáveis os cálculos.
Todo esse trabalho de iniciação científica visou entender a relação entre a aritmética de precisão
múltipla e a criptografia de chave pública, objetivo que foi atingido. A implementação dos cifrários
funcionou bem e tem um nível de segurança aceitável para aplicações criptográficas reais. Esse nível só
foi possível graças ao uso dos inteiros de precisão múltipla. Portanto, a pesquisa teve uma boa utilidade
prática, além de ter sido uma excelente fonte de aprendizado.
AGRADECIMENTOS
Agradecemos ao aluno de mestrado Gabriel Marchesan Almeida, por sua ajuda na integração da
GMP em um compilador do Windows, o Visual C++ 7.0.
REFERÊNCIAS BIBLIOGRÁFICAS
1. Menezes, A.J.; Oorschot, P.C. van; Vanstone, S.A.; Handbook of Applied Cryptography; CRC
Press, 1996.
2. Welschenbach, M.; Cryptography in C and C++; Apress, 2001.
3. Gathen, J. von zur; Gerhard, J.; Modern Computer Algebra; Cambridge University Press, 2003.
4. Rosing, M.; Implementing Elliptic Curve Cryptography; Manning, 1999.
5. Granlund, T.; The GNU MP, The Multiple Precision Arithmetic Library; Edition 4.1.2, Free
Software Foundation, 2002.