La génération de nombres premiers, un problème de P ?
SAID EMILIO
Etudiant Grenoble-INP
ENSIMAG
TROCLET PHILLIPE
Etudiant Grenoble-INP
ENSIMAG
ESSNOUSSI REDA
Etudiant Grenoble-INP
ENSIMAG
Résumé
Dans ce document nous nous intéressons au problème de
génération des nombres premiers en temps polynomial. Il a
été donc naturellement nécessaire d’étudier le test de prima-
lité AKS, qui est le seul à s’exécuter en temps polynomial
tout en étant déterministe. On s’est attaché à établir, sans
outil théorique poussé, la validité de l’algorithme qui est
primordiale d’un point de vue théorique pour établir que la
génération de nombres premiers est dans P. Il apparaîtra as-
sez rapidement que l’algorithme AKS [4] [3] est un excellent
résultat théorique mais sans réelle utilisation pratique.
Aucun résultat ne permet à ce jour de statuer sur la classe
de complexité du problème de génération des nombres pre-
miers. Toutefois, nous dressons un état de l’art en matière
de génération de nombres premiers. Il s’agira d’introduire au
lecteur les diérentes méthodes utilisées en pratique, mais
aussi les diérentes pistes considérées par la recherche. et
mettre en place notre propre algorithme de génération de
nombres premiers.
Mots clés
AKS, génération de nombres premiers
1. INTRODUCTION
Les nombres premiers sont étudiés depuis l’antiquité, pour-
tant, ils sont loin d’avoir livré tous leurs secrets. De nos
jours, ils ont une importance capitale en mathématiques mo-
dernes. On pourra citer la théorie des nombres, ou encore la
cryptographie qui sont des domaines où les propriétés des
nombres premiers sont d’une importance capitale.
À l’heure actuelle, les nombres premiers sont au cœur de la
sécurité informatique. En eet, des protocoles visant à éta-
blir une communication sécurisée, se basent sur leurs pro-
priétés connues. On pourra par exemple citer le protocole
RSA, DSA ou encore Die-Hellman. De ce fait, il est capi-
tal de pouvoir générer des nombres premiers en un temps
raisonnable an que ces protocoles soient utilisables en pra-
tique. Pour pouvoir générer de tels nombres, encore faut-il
pouvoir les reconnaître. Aussi, dans la suite de ce document,
avant de présenter les résultats obtenus en matières de géné-
ration de nombres premiers, nous allons présenter un célèbre
algorithme de test de primalité : l’algorithme AKS.
2. ÉTAT DE L’ART
En matière de tests de primalité, les diérentes méthodes
utilisées par les principales librairies, ou encore par les prin-
cipaux langages de programmation, reposent sur le même
schéma :
1. appliquer un crible (on vérie que le nombre n’est pas
divisible par tous les nombres premiers jusqu’à une
certaine borne B).
Dans les faits, en utilisant les nombres premiers jusqu’à
256, on arrive à éliminer 87,5% [1] des nombres testés
sans exécuter l’étape 2
2. appliquer un ou plusieurs tests de primalité rapides
mais probabilistes
Voici un rapide récapitulatif des diérentes méthodes utili-
sées par les bibliothèques standards :
bibliothèque : algorithme : plus grand
nombre pre-
mier du crible
Java Miller-Rabin
Lucas-Lehmer
0
openssl Miller-Rabin 17863 (op-
tionnel)
cryptopp Miller-Rabin
Lucas-lehmer
32719
pycrypto Miller-Rabin 32719
La plupart, des tests de primalité utilisés sont des modèle
probabiliste de type Monte-Carlo. Il est judicieux de noter
qu’en pratique les algorithmes utilisés ne peuvent pas dé-
clarer composé un nombre premier. Toutefois, l’inverse est
possible. C’est pour cette raison qu’ils sont appelés nombres
premiers probables. De plus, il est souhaitable de connaître
la probabilité d’erreur ou à défaut une majoration de cette
dernière. Ainsi, parmi les tests rapides de primalité cités pré-
cédemment, il est d’usage qu’au moins un des tests soit pro-
babiliste (on connaît une majoration de la probabilité d’er-
reur). Ce test pourra être combiné éventuellement à d’autres
tests, probabilistes ou non, pour améliorer la abilité du test.
(Il s’agit en général d’arguments heuristiques, se basant sur
l’idée que si les nombres pour lesquels les tests répondent
vrai à tord sont disjoints, alors la combinaison des tests per-
met d’améliorer la qualité de la réponse).
Nous allons maintenant présenter le test de Miller-Rabin,
qui est l’algorithme de test de primalité le plus utilisé par
les diérentes bibliothéques. Il se base sur la propriété sui-
vante :
Dénition 1 (témoin [de composition]) Soit un entier
impair et entier impair tel que avec entier.
On appelle témoin [de composition] de tout entier  
 tel que :

 et   

Théorème 1 (propriété de Miller) Soit un entier im-
pair et soit  l’ensemble des témoins de . Alors
iest premier ssi ;
ii si n’est pas premier alors Card
.
La puissance de ce résultat découle du fait qu’il fournit une
bonne estimation de la probabilité de réussite de notre al-
gorithme :
Procédons à k tirages aléatoires et vérions à chaque fois
si l’élément est un témoin pour un entier n dont on teste la
primalité. On obtient immédiatement par le théorème précé-
dent que si n passe tout les tests, la probabilité de se tromper
en armant qu’il est premier est inférieure à . Inverse-
ment, si un des tests échoue, c’est à dire qu’on a trouvé un
témoin pour n, alors on est assuré que n est composé.
Le tableau ci-dessous fournit le nombre de tests eectués par
Openssl pour garantir une probabilité d’erreur inférieure en
fonction de la taille du nombre à tester.
taille Nombre d’ité-
rations
> 1300 2
> 850 3
> 650 4
> 550 5
> 450 6
> 400 7
> 350 8
> 300 9
> 250 12
> 200 15
> 150 18
> 100 27
Notons que la formule proposée semble donc très grossière
pour les grands nombres[2]. Dans les faits, il existe une autre
formule, liant la taille du nombre à la probabilité d’erreur.
Par ailleurs, openssl précise que les nombres de taille infé-
rieure à 100 bits ne sont pas pris en compte.
3. AKS
3.1 Enjeu historique et théorique
L’importance de l’algorithme AKS réside principalement dans
le fait que c’est le premier algorithme publié qui soit simul-
tanément polynomial, déterministe et inconditionnel, autre-
ment dit qu’il est apte à répondre de façon catégorique avec
une complexité (temps de calcul) polynomiale en  sur
l’éventuelle primalité d’un nombre donné et que de plus
la validité de l’algorithme ne repose sur aucune hypothèse-
conjecture comme c’est le cas par exemple du test de Miller-
Rabin présenté précédemment qui repose notamment sur
l’hypothèse de Riemann.
On résume dans le tableau ci-dessous l’état de l’art avant
2002.
D : déterministe
P : polynomial
I : inconditionnel
Algorithme : Année : D : P : I : Principe
Crible
d’ERATOSTHENE -240 33Division de
par tous les
nombres pre-
miers inférieurs
à
MILLER 1975 3 3 Recherche de
témoins de
non-primalité
RABIN 1976 3 3
SOLOVAY 1977 3 3 Résidus qua-
dratiques
et STRASSEN 3 3
ADLEMAN,
POMERANCE et
RUMELY
1983 33Test de prima-
lité (d’après
Miller) à base
de réciprocité
quadratique
GOLDWASSER et
KILIAN
1986 3Courbes ellip-
tiques
ATKIN 3 3
ADLEMAN et
HUANG
1992 3 3 Courbes hyper-
elliptiques
AGRAWAL, KAYAL
et SAXENA
2002 3 3 3 Polynômes
cyclotomiques
sur des corps
nis - en
(log)
Bien que des progrès aient été réalisés au l des années, il
a fallu attendre 2002 et l’algorithme AKS an de pouvoir
armer que ”Prime is in P”.
3.2 Principe d’AKS
L’intérêt de l’algorithme AKS réside essentiellement dans
la beauté du résultat théorique établi, car comme nous le
verrons dans les sections suivantes, malgré une complexité
polynomiale, l’algorithme demeure majoritairement inutili-
sable en pratique et on lui préfère des algorithmes bien plus
simples et plus ecaces en pratique comme celui notamment
de Rabin-Miller.
La validité de l’algorithme repose essentiellement sur le ré-
sultat suivant, encore appelé identité AKS :
Théorème 2 (identité AKS) Soit  ,,tels
que .
Alors si, et seulement si   .
Autrement dit l’identité AKS n’est que la traduction sous
forme polynomiale du fait qu’un entier naturel n est premier
si, et seulement si, il divise les
, pour variant de 1
à.
3.3 Description de l’algorithme
Soit un entier donné.
1. si pour et , alors est composé.
2. Déterminer le plus petit entier tel que  
.
3. Si      pour un entier   , alors est
composé.
4. Si , alors est premier.
5. Pour à   :
si 
 , alors est composé.
6. est premier.
3.4 Schéma descriptif de la preuve de la vali-
dité de l’algorithme
La validité de l’algorithme repose essentiellement sur l’exis-
tence d’un tel exhibé à l’étape 2. de l’algorithme et au fait
que celui-ci est connu à un encadrement près. Ainsi l’éva-
luation des polynômes lors de l’étape 5. de l’algorithme est
rendue possible avec une complexité polynomiale par le fait
de réductions modulo . La recherche de et le
nombre de vérications à accomplir ensuite avec les déter-
minés s’eectuent en un temps polynomial en log(n), si bien
que l’on obtient eectivement un algorithme déterministe en
temps polynomial pour des tests de primalité. On renverra le
lecteur intéressé à l’annexe pour une démonstration exhaus-
tive et élémentaire de tous ces résultats. Nous proposons
toutefois un résumé des diérents coûts ci-dessous :
1. étape 1 :
 on calcul le , puis, pour
chaque   , on applique un algorithme di-
chotomique sur  an de trouver un tel que  
. recherche dichotomique sur 
2. étape 2, le calcul de r :
 pour tout , on
teste si l’ordre de est supérieur à cela requiert
multiplications modulo , qui est borné par

3. étape 3, calcul pgcd(,), :
. Un calcul
de pgcd coûte  avec l’algorithme d’Euclide.
En utilisant la borne sur on a le résultat.
4. étape 4, comparaison de r et n :  (comparai-
son de nombres de longueur )
5. étape 5, test des congruences. on utilise un algorithme
d’élévation au carré type square and multiply, on doit
donc faire multiplications sur des polynômes
de degré dont les coecients sont codés sur 
bits, un polynôme fait donc : . Une mul-
tiplication coûte alors
, d’où vérier une
congruence coûte
, on obtient, en majo-
rant les indices de boucles :

3.5 Résultats expérimentaux
Dans cette partie, nous décrivons l’implémentation de l’al-
gorithme AKS précédent (dans sa version en

et nous analysons expérimentalement son coût. Il est donc
question de mettre en lumière les avantages ou au contraire
les inconvénients que présentent l’implémentation et l’utili-
sation de cet algorithme. l’implémentation principale, c’est-
à-dire celle sur laquelle se base l’ensemble de nos résultats
expérimentaux, a été réalisée via la librairie pari GP. Ce
choix a été motivé par le fait que cette librairie possède de
nombreuses fonctions relatives à la théorie des nombres dont
nous avions l’utilité. De plus, cette librairie est connue pour
sa rapidité, ce qui nous permettait d’obtenir en un temps
raisonnable un algorithme fonctionnel.
Commençons par décrire comment nous obtenons le de
l’algorithme. L’idée est simple, on teste tous les à partir
de  . Pour un xé, on multiplie  fois n
par lui-même et on regarde, à chaque étape, si le résultat
est égal à 1. Si c’est le cas, on teste un autre . Sinon, le
courant est le bon. Pour les opérations de base sur les int
modulo, ou sur les polynômes, nous utilisons les types natifs
de pari GP. Cela permet de limiter la place en mémoire.
Pour le calcul du pgcd on utilise l’algorithme d’Euclide. Les
calculs de puissance se font via un algorithme type ”square
and multiply”. Voici nos résultats :
L
Figure 1 : évolution du temps de calcul en fonction
de la taille du nombre exprimée en bits
Avant de commenter ces résultats, nous allons décrire com-
ment nous les avons obtenus. Nous avons généré des nombres
premiers aléatoires (5 dans le cas présent) de diérentes
tailles via openssl. Puis pour chaque taille, nous avons cal-
culé la moyenne des temps obtenus. Il est important de pré-
ciser que les nombres testés sont tous premiers. En eet,
un nombre composé risque d’être détecté composé avant
qu’il n’ait subi toutes les étapes de l’algorithme. C’est le
cas si, par exemple, le nombre considéré est une puissance
de nombres premiers ou encore s’il admet un petit diviseur.
Aussi, tester des nombres composés de plus en plus grands
ne serait pas forcément révélateur de l’évolution du temps
de calcul.
Intéressons-nous maintenant à la courbe. Une première re-
marque évidente est que le temps de calcul devient vite très
grand. En eet, si un nombre premier codé sur 70 bits peut
paraître très grand pour un être humain, il est en réalité
très petit d’un point de vue cryptographique. A titre indica-
tif,il est recommandé que les clés rsa soient codées sur 2048
bits, ce qui impose la création de nombres premiers de 1024
bits. Or s’il nous faut près d’une demie-heure pour tester la
primalité d’un nombre premier de 70 bits, on peut armer
que le test d’un nombre premier de 1024 bits n’est pas fai-
sable en pratique, surtout au regard de la forte croissance
de la courbe expérimentale. On peut même se demander si
notre programme a réellement un coût polynomial, en ef-
fet la courbe ressemble à une courbe de type exponentielle.
Toutefois, il est dicile de répondre à cette question. En
eet, il a été prouvé que l’algorithme a un coût en :

Or, il est dicile de faire la diérence entre une exponen-
tielle et un polynôme de haut degré pour des petites valeurs.
De plus, de par la longueur des tests (en termes de temps)
sur des nombres plus grands, tracer plus de points serait très
long, voire impossible. On ne peut donc pas immédiatement
conclure si oui ou non les résultats obtenus correspondent à
ceux attendus.
An de répondre à cette question, nous avons tracé la courbe

, cette courbe devrait être bornée si le coût est po-
lynomial en .
Figure 2 : évolution de 
 en fonction du
nombre de bits
La courbe obtenue semble se stabiliser pour une taille de bits
supérieure à 50 autour d’une valeur légèrement inférieure à
deux. Toutefois si elle c’était le cas, cela voudrait dire que
le coût serait moins que quadratique par rapport au nombre
de bits. Ce qui est improbable. De plus, la courbe semble
alterner entre une phase de faible croissance et une phase
de forte croissance. Nous allons tenter d’expliquer ce dernier
point, pour cela nous allons étudier l’évolution du paramètre
de l’algorithme en fonction du nombre premier en entrée.
Figure 3 : évolution de en fonction de p (nombre
premier)
Il apparaît sur la gure que le semble progresser par pa-
lier, ce qui explique les phases de faible croissance observées
sur 2. Ce graphe n’a donc rien d’anormal, le problème est
que nous n’avons pas assez de points pour pouvoir conclure.
Par ailleurs, la gure 3 semble suggérer que que évolue en
. Nous allons étudier cette intuition par la suite.
Commençons par justier l’impact d’une telle étude.
On rappelle que l’algorithme AKS se base sur des compa-
raisons de polynômes de degré . Ces polynômes doivent
être denses , car sinon au cours du calcul de puissance du
polynôme, c’est-à-dire à chaque apparition d’une nouvelle
puissance dans le polynôme, il faudrait rajouter un maillon
à la liste des coecients. De même, à chaque suppression
d’une puissance, il faudrait retirer un maillon. Ce qui en-
gendrerait un surcoût prohibitif. Ajoutant à cela le fait que
chaque opération via la librairie pari GP crée un nouvel ob-
jet dans sa pile interne (propre à pari GP, allouée au début
du programme), on conçoit aisément qu’un overow puisse
se produire dans cette pile. Ce qui causerait une sortie su-
bite du programme. Pour remédier à ce problème d’overow
, nous avons implémenté une version d’AKS via la librairie
NTL. En eet, celle-ci à la diérence de la librairie pari GP,
ne crée pas de pile interne. Nous en avons également proté
pour implémenter un modulo pour les polynômes spéciale-
ment dédiés à AKS : pour tout polynôme on calcule son
résidu modulo en remplaçant tous les par .
Nous avons également implémenté des méthodes de multipli-
cations et d’exponentiation en place an de limiter l’impact
sur la mémoire, et donc les coûts de gestion de mémoire.
Pourtant malgré tous nos eorts, l’algorithme n’est pas uti-
lisable en pratique.
De manière plus générale, AKS est un algorithme très gour-
mand en mémoire, cela vient des polynômes denses qu’il
manipule. En eet, supposons que l’on veuille tester la pri-
malité d’un nombre de 1024 bits, la seule limite que l’on
ait sur le est que   . Or la comparaison des po-
lynômes (étape 5 de l’algorithme) impliquerait la création
d’un polynôme de degré dont tous les coecients sont
sur 1024 bits. Ce qui au pire demanderait de réserver 
bits en mémoire, soit plusieurs téraoctets. Or la majorité
des pc sur le marché n’ont pas cette capacité mémoire. Et
quand bien même, ils l’auraient, les coûts de gestion de la
mémoire seraient très élevés. De ce fait, à moins de pou-
voir justier que le est en réalité beaucoup plus petit que
sa borne, Il faut abandonner l’idée d’utiliser cet algorithme.
On peut par ailleurs exprimer la complexité l’algorithme en
fonction de . Si les opérations sur les polynômes se font
en place, via un buer de taille      bits et
d’un buer de taille    bits(comme notre implé-
mentation via NTL). (où est une constante). On a alors
besoin de . De plus, comme  ,
on a 
    . Donc la complexité devient


.
De plus, il faut souligner que le est plus petit que sa borne
alors le coût global de l’algorithme diminue. Car, si on ob-
tenait une nouvelle borne sur , alors on pourrait armer
que les polynômes sont plus petits et donc que les opéra-
tions sur ces derniers seraient moins coûteuses. De même, la
taille de la boucle où se font ces opérations serait également
plus petite. An d’en savoir plus, nous allons tracer pour
de petites valeurs de , ce qui nous permettra d’observer le
comportement général de .
Figure 4 : évolution de r en fonction de n
Commençons par une remarque préliminaire : on a nécessai-
rement 
car 
On remarque alors la très forte ressemblance entre la courbe
tracée et . An de valider cette ressemblance, nous avons
tracé la courbe 
:
La courbe conrme clairement l’intuition, pour de petites
Figure 5 : évolution de
 en fonction de n
valeurs, on a , on aurait même .
De plus, pour des grandes valeurs de , on obtient :
Figure 6 : évolution de r en fonction de n
Les abscisses sont illisibles de part la taille des nombres
considérés, la courbe est tracée sur l’intervalle

On remarque alors que pour de grandes valeurs ,semble
avoir une croissance faible, (on sait de part l’inégalité avec
le log que la suite ne peut être constante). Cela reste cohé-
rent avec l’hypothèse émise : en moyenne les sont proches
de  (car . En fait, ce ré-
sultat n’a rien de nouveau, s’il n’est pas démontré, il existe
des conjectures qui, si elles étaient vraies, montreraient ce
résultat.
1 / 25 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans l'interface ou les textes ? Ou savez-vous comment améliorer l'interface utilisateur de StudyLib ? N'hésitez pas à envoyer vos suggestions. C'est très important pour nous!