
“O maior número primo é
2 32582657 -1 . E afirmo com orgulho que me lembrei de todos os seus números ... em forma binária ".
Karl PomeranceUm número natural é chamado primo se tiver apenas dois divisores diferentes: um e ele próprio. A tarefa de encontrar números primos assombra os matemáticos há muito tempo. Por um longo tempo, esse problema não teve aplicação prática direta, mas tudo mudou com o advento da criptografia de chave pública. Este artigo discute várias maneiras de procurar números primos, tanto de interesse puramente acadêmico quanto usados atualmente em criptografia.
Peneira de Eratóstenes
Peneira de Eratóstenes - um algoritmo proposto pelo matemático grego antigo Eratóstenes. Este método permite encontrar todos os números primos menores que um número
n . A essência do método é a seguinte. Pegue um conjunto de números de 2 a
n . Riscar todos os números divisíveis por 2, exceto 2. Do conjunto (eliminamos), passamos para o próximo número “não eliminado” - 3, novamente riscamos tudo o que é divisível por 3. Passamos para o próximo número restante - 5 e assim sucessivamente até chegamos ao
n . Depois de executar as etapas acima, apenas os números primos permanecerão na lista original.
O algoritmo pode ser ligeiramente otimizado. Como um dos divisores do número composto
n é obrigatório
, o algoritmo pode ser parado após a exclusão dos números divisíveis por
.
Ilustração da operação do algoritmo da Wikipedia:
A complexidade do algoritmo é
ao mesmo tempo, para armazenar informações sobre quais números foram riscados, é necessário
memória.
Há várias otimizações para reduzir esses indicadores. Um truque chamado
fatoração de roda é incluir na lista inicial apenas números
coprime com os primeiros números primos (por exemplo, menos de 30). Em teoria, propõe-se levar os primeiros simples até cerca de
. Isso reduz a complexidade do algoritmo em
vezes. Além disso, a chamada segmentação é usada para reduzir o consumo de memória. O conjunto inicial de números é dividido em segmentos de tamanho
e para cada segmento, a peneira de Eratóstenes é aplicada separadamente. O consumo de memória é reduzido para
.
Peneira Atkin
Um algoritmo melhor para selecionar números compostos foi proposto por Atkin e Bershtein e foi chamado
de Peneira de Atkin . Este método é baseado nas três propriedades a seguir dos números primos.
Propriedade 1Se
n for um número positivo que não seja múltiplo do quadrado de um número primo e que
. Então
n é primo se e somente se o número de raízes da equação
estranho.
Propriedade 2Se
n for um número positivo que não seja múltiplo do quadrado de um número primo e que
. Então
n é primo se e somente se o número de raízes da equação
estranho.
Propriedade 3Se
n for um número positivo que não seja múltiplo do quadrado de um número primo e que
. Então
n é primo se e somente se o número de raízes da equação
estranho.
As evidências para essas propriedades são fornecidas
neste artigo .
No estágio inicial do algoritmo, a peneira de Atkin é uma matriz
A do tamanho
n preenchida com zeros. Para determinar números primos, todos
. Para cada par é calculado
,
,
e o valor dos elementos da matriz
,
,
aumenta em um. No final do algoritmo, os índices de todos os elementos da matriz que possuem valores ímpares são números primos ou quadrados de um número primo. Na última etapa do algoritmo, os quadrados dos números restantes no conjunto são riscados.
Da descrição do algoritmo resulta que a complexidade computacional da peneira de Atkin e o consumo de memória são
. Ao usar a fatoração e segmentação das rodas, a estimativa de complexidade do algoritmo é reduzida para
e consumo de memória até
.
Números de Mersenne e teste de Luke-Lemer
Obviamente, com esses indicadores de complexidade, mesmo a peneira otimizada da Atkin não pode ser usada para procurar primos realmente grandes. Felizmente, existem testes rápidos para verificar se um determinado número é primo. Ao contrário dos algoritmos de peneira, esses testes não são projetados para procurar todos os números primos, eles só conseguem dizer com alguma probabilidade se um determinado número é primo.
Um desses métodos de teste é o
teste de Luc-Lemer . Este é um teste determinístico e incondicional da simplicidade. Isso significa que a aprovação no teste garante a simplicidade do número. Infelizmente, o teste é destinado apenas a números de um tipo especial
onde
p é um número natural. Esses números são chamados de números de Mersenne.
O teste de Luke-Lemer afirma que o número de Mersenne
primo se e somente se
p for primo e
divide
membro da sequência
definir recursivamente:
para
.
Para o número
comprimento de
p bits, a complexidade computacional do algoritmo é
.
Devido à simplicidade e ao determinismo do teste, os maiores números primos conhecidos são os números de Mersenne. O maior número primo conhecido de hoje é
, sua notação decimal consiste em 24.862.048 dígitos. Você pode admirar essa beleza
aqui .
Teorema de Fermat e teste de Miller-Rabin
Não são conhecidos muitos números primos de Mersenne; portanto, a criptografia de chave pública requer uma maneira diferente de pesquisar números primos. Um desses métodos é o
teste de simplicidade de Fermat . É baseado no pequeno teorema de Fermat, que afirma que se
n é primo, então para qualquer
a que não seja divisível por
n , a igualdade
. A prova do teorema pode ser encontrada na
Wikipedia .
O teste de simplicidade de Fermat é um teste probabilístico, que consiste em enumerar vários valores de
a se pelo menos um deles satisfizer a desigualdade
, o número
n é composto. Caso contrário,
n é provavelmente primo. Quanto mais valores de
um usado no teste, maior a probabilidade de
n ser primo.
Infelizmente, existem números compostos
n para os quais a comparação
vale para todos
um primo mutuamente com
n . Esses números são chamados de
números Carmichael . Os números compostos que passam com êxito no teste de Fermat são chamados Fermat pseudo-simples. O número de Fermat pseudo-simples é infinito; portanto, o teste de Fermat não é a maneira mais confiável de determinar números primos.
Teste de Miller-RabinResultados mais confiáveis podem ser alcançados combinando o pequeno teorema de Fermat e o fato de que para um primo
p não há outras raízes da equação
exceto 1 e -1. O teste de Miller-Rabin enumera vários valores de
a e verifica se as seguintes condições são verdadeiras.
Seja
p um primo e
, então para qualquer
uma de pelo menos uma das condições for verdadeira:
- Existe um número inteiro r <s tal que
Pelo teorema de Fermat
e desde
da propriedade das raízes da equação
segue-se que, se acharmos que uma das condições não é satisfeita, então
p é um número composto. Se uma das condições for cumprida, o número
a é chamado de testemunha da simplicidade do número
n, de acordo com Miller, e o número
n em si é provavelmente primo.
Quanto mais testemunhas de simplicidade forem encontradas, maior a probabilidade de
n ser primo. De acordo com o teorema de Rabin, a probabilidade de um número escolhido aleatoriamente
a testemunhar a simplicidade do número composto é aproximadamente
.
Portanto, se verificarmos
k números aleatórios
a , então a probabilidade de tomar o número composto como primo
.
A complexidade do algoritmo
onde
k é o número de verificações.
Devido à sua velocidade e alta precisão, o teste de Miller-Rabin é amplamente utilizado na busca de números primos. Muitas bibliotecas criptográficas modernas usam apenas esse teste para verificar a simplicidade de grandes números e, como Martin Albrecht mostrou em seu
trabalho , isso nem sempre é suficiente.
Ele foi capaz de gerar esses números compostos que foram aprovados no teste de simplicidade nas bibliotecas OpenSSL, CryptLib, JavaScript Big Number e muitos outros.
Teste de Luke e Baillie - Teste PSW
Para evitar vulnerabilidades relacionadas a situações em que um número composto gerado por um invasor é apresentado como primo, Martin Albrecht sugere o uso do teste
Baillie - PSW . Apesar do teste Baillie - PSW ser probabilístico, até o momento, não foram encontrados números compostos que passem com êxito nesse teste. Por encontrar esse número em 1980, os autores do algoritmo prometeram uma recompensa de US $ 30. O prêmio ainda não foi reivindicado.
Vários pesquisadores
verificaram todos os números até
e nenhum número composto passou no teste Baillie - PSW. Portanto, para números menos
o teste é considerado determinístico.
A essência do teste é verificar consistentemente o número em um tempo de inatividade por dois métodos diferentes. Um desses métodos é o teste de Miller-Rabin já descrito acima. O segundo é
o teste de Lucas para uma forte pseudo-simplicidade .
Teste de pseudo-simplicidade de Luke StrongSequências de Lucas são pares de sequências de recorrência
\ {U_ {n} (P, Q) \}, \ {V_ {n} (P, Q) \} descrito pelas expressões:
Vamos
e
São sequências de Lucas, onde os números inteiros P e Q satisfazem a condição
Calculamos
o símbolo de Jacobi :
.
Encontre tais
r, s para os quais a igualdade
Para prime
n , uma das seguintes condições é válida:
- n divide
- n divide por algum j <r
Caso contrário,
n é composto.
A probabilidade de um número composto
n ser aprovado no teste Luc para um determinado par de parâmetros P, Q não excede 4/15. Portanto, após a aplicação do teste
k vezes, essa probabilidade é
.
Os testes de Miller-Rabin e Luke produzem conjuntos disjuntos de números pseudo-simples, respectivamente, se o número
p passou nos dois testes, é simples. É nessa propriedade que se baseia o teste Baillie - PSW.
Conclusão
Dependendo da tarefa, vários métodos para encontrar números primos podem ser usados. Por exemplo, ao procurar primos grandes de Mersenne, primeiro, usando a peneira de Eratóstenes ou Atkin, uma lista de primos é determinada até um certo limite, suponha que até
. Em seguida, para cada número
p da lista, usando o teste Luc-Lemer, é verificado se há simplicidade
.
Para gerar um grande número primo para fins criptográficos, um número aleatório
a é selecionado e verificado pelo teste de Miller-Rabin ou pelo Baillie - PSW mais confiável. De acordo
com o teorema da distribuição de números primos , para um número selecionado aleatoriamente de 1 a
n, a chance de ser primo é aproximadamente igual
. Portanto, para encontrar um número primo de 1024 bits, basta classificar cerca de mil opções.
Fontes PS
A implementação de todos os algoritmos descritos no Go pode ser visualizada no
GitHub .