Teoria Aritmética dos Números – MA553 Monografia

Propaganda
Teoria Aritmética dos Números – MA553
Monografia: Um algoritmo para solução de congruências
do tipo
≡ (
).
Campinas, outubro de 2007
Antonio Carlos Campello, RA 059076
Isabel Leal, RA 061533
Resumo:
Nessa monografia, estudaremos alguns conceitos básicos de teoria aritmética
dos números, em particular congruências e testes de primalidade de inteiros,
com o objetivo de formular um algoritmo preciso para resolver a seguinte
problemática:
Sejam , ∈
≡1(
Introdução:
. Quais são os primos , com
)?
+1≤
≤ , tais que
Os primeiros trabalhos em teoria aritmética dos números são datados da Índia Antiga (por volta do ano de 800 AC) e envolvem soluções inteiras para as
chamadas equações diofantinas [1], contudo, os resultados mais importantes
no assunto só foram demonstrados pelos gregos, por volta do século 3 antes
de Cristo. Dentre os matemáticos gregos, podemos colocar em posição de
destaque Euclides de Alexandria (330-260 AC) e Eratóstenes de Cirene, (276 194 AC).
Euclides foi professor, matemático e escritor. Sua principal obra (e
contribuição) para a matemática foram “Os elementos”, em que são
estabelecidas as bases da geometria euclidiana. Em teoria de números, é
possível enumerar diversos resultados notáveis (e usados até hoje) atribuidos
a ele, como o algoritmo para a divisão, a demonstração da irracionalidade do
número √2 (diagonal de um quadrado de lado 1) e a prova da infinitude dos
números primos. Todas essa demonstrações podem ser encontradas em [1].
Eratóstenes, por sua vez, realizou sua maior contribuição para a teoria de
números com a criação do chamado Crivo de Eratóstenes, que será descrito
cuidadosamente a seguir. O Crivo é, até hoje, uma das formas mais eficientes
para criação de listas de números primos e, portanto, tem grande
aplicabilidade, por exemplo, na teoria de criptografia.
Dentre outros matemáticos que estudaram teoria dos números, foram
notáveis Pierre de Fermat (1601-1665 DC), Leonhard Euler (1707-1783 DC),
Friedrich Gauss (1777-1855 DC), et al.
1. Crivo de Eratóstenes
Def. 1.1: Se e são números inteiros, dizemos que a divide b, denotando
por | , se existir um inteiro c tal que = .
Def. 1.2: Dizemos que d é o máximo divisor comum de a e b (e denotamos
por ( , ) = ), se d é o maior inteiro que divide a e b.
Def. 1.3: Um número inteiro n (n>1) é dito primo, se possuir somente dois
divisores positivos, n e 1. Se n não é primo, dizemos que ele é composto.
Teorema 1.1 (fundamental da Aritmética): Todo inteiro maior do que 1 pode
ser representado de maneira única (a menos da ordem) como um produto de
fatores primos.
Demonstração: (i) Existência: Suponhamos, por absurdo, o oposto da tese,
ou seja, que existe pelo menos um inteiro maior do que 1 que não possa ser
representado por fatores primos. Seja A o conjunto de todos esses números.
Como A é um subconjunto dos inteiros, certamente ele possui um elemento
mínimo, pelo Princípio da Boa Ordenação. Seja esse elemento. Como é
maior do que 2 (já que 2 é primo, e tem fatoração em fatores primos), então
existem a e b, tais que = , com <
< , e como ∉
∉ ,
eles possuem fatoração e, portanto, = , possui fatoração, o que
absurdo, pois ∈ . Logo, A não pode ter elemento mínimo, e, portanto,
= ∅, o que completa a demonstração da existência.
(ii) Unicidade: Para demonstrar a unicidade, vamos lançar mão do seguinte
lema, cuja demonstração pode ser encontrada em [1]: Se |
… , com p
primo, então
divide pelo menos um fator
do produto.
Sejam =
… =
… duas fatorações de x. Perceba que os ′
não são necessariamente distintos, assim como os ’s . Da igualdade, e da
definição de divisibilidade, verificamos que |
…
e, portanto, pelo
lema, existe k tal que, | →
= , já que ambos são primos. Por
extensão, para qualquer < , existe um < tal que | →
= . Por
fim, basta provar que n=k, que é trivial, já que, se n>k, teriamos que
… …
=
… =
… , o que é absurdo, já que > 1. Ou
seja, o conjunto de deve ser idêntico ao de , finalizando a demonstração
da unicidade.
Por (i) e (ii), está demonstrado o Teorema Fundamental da Aritmética.
Teorema 1.2: Se n não é primo, então possui, necessariamente, um fator
primo menor do que ou igual a √ .
Demonstração: Sendo n composto, então
= . , onde 0 < <
e
0 < < , o que pode ser visto como uma consequência do teorema
anteiror. Sem perda de generalidade, vamos supor que ≤ . Suponhamos,
por absurdo, que
> √ . Logo,
= . > √ . √ = , chegando na
desigualdade > , que é obviamente um absurdo. Portanto, ≤ √ e,
pelo teorema anterior, a possui algum fator primo, que deve ser menor que a
e, por conseguinte, menor que √ . Daí, concluímos que n possui um fator
primo menor que √ , o que completa a demonstração.
Corolário 1.1: Se um número não possui nenhum fator primo p, tal que
2 ≤ ≤ √ , então é primo.
Demonstração: Segue imediatamente do teorema, aplicando-se a sua
contrapositiva.
O Crivo de Eratóstenes é uma consequência do Teorema 1.2 e do Corolário
1.1. Já que para verificar se um número é primo basta testar divisibilidade
pelos números menores que √ , então para criar uma lista de primos até n, é
suficiente ter uma lista de todos os números até n e excluir dela todos os
múltiplos de primos menores que √ . Esse processo pode ser descrito pelo
seguinte algoritmo:
Algoritmo 1(Crivo de Eratóstenes):
Entrada: inteiro positivo ímpar .
Saída: lista de primos ímpares ≤ .
Etapa 1: Comece criando um vetor v de ( − 1)/2 posições, cada uma das
quais deve estar preenchida com o valor 1; e fazendo
= 3.
Etapa 2: Se
> , escreva em uma lista os números 2 + 1 para os quais a
j-ésima entrada do vetor v é 1 e pare; senão senão vá para a etapa 3.
Etapa 3: Se a posição ( − 1)/2 do vetor v está preenchida com 0
incremente P de 2 e volte à etapa 2; senão vá para a etapa 4.
Etapa 4: Atribua o valor de
a uma nova variável T: substitua por zero o
valor da posição ( − 1)/2 do vetor v e incremente de 2 ; repita essas
duas instruções até que T > n; quando isto acontecer, incremente P de 2 e
volte à etapa 2.
É fácil ver que a etapa 2 do algoritmo é uma consequência imediata do
Teorema 1.2 e do seu corolário. O algoritmo acima, da maneira descrita, é
uma versão do Crivo de Eratóstenes que cria uma lista de todos os primos
ímpares. Se quisermos criar uma lista de todos os primos, basta adicionar o 2,
que é, obviamente, o único primo par. Para mais informações sobre o
algoritmo acima, ver referência [3].
O algoritmo acima será uma das chaves para a solução do problema
proposto.
2. Congruências
A principal motivação dessa sessão é apresentar alguns conceitos e
propriedades básicas de congruências e, por fim, formular um algoritmo
eficiente para calcular potenciação em aritmética de módulo que será usado
para, depois de encontrados os números primos p, testar se
≡
1(
).
Def.2.1: Sejam a e b números inteiros. Dizemos que a é congruente a b,
), se |( − ). Se
módulo m ( > 0) e denotamos por ≡ (
∤ ( − ), dizemos que a é incongruente a b, módulo m, e denotamos por
( ).
≢
Propriedades: Se a,b,c,d,e e m são inteiros tais que ≡
), então as seguintes propriedades são válidas:
≡ (
1.
2.
3.
4.
5.
6.
+
−
≡
+
−
≡
≡
≡
≡
≡
(
(
+ (
− (
+
−
(
(
)
)
)
)
(
) e
)
)
Enunciamos aqui algumas propriedades das congruências. A demonstração
de todas elas pode ser encontradas em [2]. Vamos nos limitar à
demonstração de duas delas:
) → |( − ), ou seja
Demonstração (propriedade 1): Se ≡ (
|( + − − ) → |( + ) − ( + ) e, por definição, + ≡ +
(
), completando a demonstração.
) → |( − ), ou seja m também divide
(Propriedade 3): Se ≡ (
( − ) multiplicado por algum inteiro não nulo. Sendo esse inteiro , temos
que |( − ) →
=
(
).
As demonstrações para as outras propriedades são análogas e seguem
imediatamente da definição de congruência, dada em 2.1, e das
propriedades básicas da divisão.
Apenas com essas propriedades, é possível criar um algoritmo eficiente para
calcular a forma reduzida de potencias em módulo n sem, necessariamente,
ter que calcular a potência do número e depois verificar a congruência,
simplificando, portanto, vários passos computacionais. Vejamos uma
motivação para o algoritmo:
Considere o problema de calcular a forma reduzida (com
< ) de
≡ (
). E seja
= 2 +
2
+ …
a representação
binária de , onde os coeficientes valem 0 ou 1. Logo, temos que
=
…
…
= ( )
.
e assim por diante.
Perceba que, pela propriedade 3, basta calcular o módulo reduzido de cada
componente
e multiplicar todos eles, módulo n. Além do mais, os
valores de
são facilmente identificáveis: 1, se o expoente “restante” for
ímpar, ou zero caso contrário.
A argumentação exposta acima nos conduz ao seguinte algoritmo:
Algoritmo 2
Entrada: Inteiros a, e e n, onde , > 0
Saída: a forma reduzida de
módulo
≥ 0.
Etapa 1: Começe com A = a, P = 1 e E = e.
Etapa 2: Se E = 0, retorne P.
Etapa 3: Se E for ímpar, então atribua a P o valor do resto da divisão de AP
por n e a E o valor ( − 1)/2 e vá para a etapa 5, senão vá para a etapa 4.
Etapa 4: Se E for par então atribua a E o valor de /2 e vá para a etapa 5.
Etapa 5: Troque A por . (
) e vá para 2.
Mais detalhes sobre o algoritmo também podem ser encontrados na
referência bibliográfica [3], no seu apêndice.
3. A congruência
≡
(
).
Tendo em mente os resultados apresentados nas sessões 1 e 2, podemos,
enfim, atacar o problema objetivo desta monografia, desenvolvendo um
algoritmo para o cálculo de congruências do tipo
≡ 1(
), sendo
+ 1 ≤ ≤ , um primo e , inteiros.
Antes de apresentar o algoritmo, entretanto, precisamos fazer duas
modificações no Crivo de Eratóstenes, de modo que ele escreva na lista
apenas os números maiores do que + 1. Para isso, basta adicionar à etapa
2 a condicional: Se 2 + 1 > + 1, escreva na lista. A outra modificação, é
adicionar o número 2 ao início da lista, aumentando em 1 o seu tamanho.
Vamos chamar esse novo algoritmo de Algoritmo 1’.
Com essa modificação, temos ferramentas suficientes para criar um
algoritmo simples capaz de resolver o problema proposto.
Algoritmo 3
Entrada: Valores para a e r, conforme a descrição do problema dada acima.
Saida: Uma lista com os primos que satisfazem a equação.
Etapa 1: Utilize o Algoritmo 1’ para criar um vetor com todos os primos de
+ 1 até , que chamaremos de vetor A.
Etapa 2: Crie um novo vetor B.
Etapa 3: Para todos os elementos da lista A, verifique, através do Algoritmo
2, se
≡1(
). Se sim, inclua no vetor B o elemento p e passe
para o próximo elemento de A. Caso contrário, apenas passe para o próximo
elemento de A.
Apesar da aparente simplicidade desse algoritmo, algumas considerações
necessitam ser feitas a seu respeito.
Em primero lugar, o algoritmo proposto envolve a chamada de outros dois
algoritmos (1 e 2), o que aumenta a sua complexidade e custo
computacional, tornando-o dependende da eficiência dos dois algoritmos.
Em segundo, há, de maneira intrínseca ao algoritmo, a exigência de criação
de um vetor A, que pode ser arbitrariamente grande, a depender da
quantidade de primos distribuidos entre a+1 e r. Isso quer dizer, que o
algoritmo está limitado ao tamanho máximo que um vetor pode ter em uma
linguagem de programação, em algum sistema. Implementações futuras
envolvendo listas ligadas, aritmética de precisão múltipla e computação
algébrica melhorariam substancialmente a sua eficiência, assim como
diminuiriam a sua dependência de uma memória alocada.
Além disso, vemos que o vetor B não possui um tamanho pré-determinado.
Implementações para o algoritmo, deveriam envolver alocação dinâmica
para a sua criação, já que, a prori, não é sabida nenhuma forma para a
distribuição de primos que satisfazem a propriedade a seguir.
Por fim, a implementação das idéias aqui apresentadas foi feita na linguagem
C e baseou-se fielmente nos algoritmos propostos nessa monografia. Além
das soluções triviais (para a = 1), encontramos a solução para a = 3 e p = 11,
que verifica a seguinte relação de congruência: 3 ≡ 1 (
11 ).
Referências
[1] Niven, I. et al, An Introduction to the Theory of Numbers, Fifth Edition.
[2] Santos, J.P.O, Introdução à Teoria dos Números, IMPA 2003.
[3] Coutinho, S.C, Números Inteiros e Criptografia RSA, IMPA 2005.
Download