web-dev-qa-db-fra.com

Comment OpenSSL génère-t-il un grand nombre premier si rapidement?

Afin de générer une paire de clés RSA de 2048 bits, vous devez générer deux grands nombres premiers d'une longueur de 1024 bits. Autant que je sache, OpenSSL choisit un nombre aléatoire de 1024 bits et commence à rechercher un nombre premier autour de lui. Comment OpenSSL peut-il vérifier si le nombre est premier ou pas si rapidement?

34
user167246

Le test de primalité est beaucoup plus facile que d'effectuer une factorisation entière.

Il existe plusieurs façons de tester la primauté, telles que le déterministe Tamis d'Eratosthène et le probabiliste tests de primalité Miller-Rabin . OpenSSL utilise plusieurs tests pour vérifier la primauté. Ils soumettent d'abord le nombre aux vérifications déterministes, tentant de diviser le candidat avec un certain nombre de petits nombres premiers, puis une série de tests de primalité de Miller-Rabin. La grande majorité des nombres premiers candidats sont rejetés avec le tout premier test de primalité. Tous les candidats qui les réussissent sont soumis à d'autres cycles de tests, chacun augmentant la certitude qu'il s'agit d'un premier choix.

Lors de l'utilisation des tests de Miller – Rabin, un nombre composite a 75% de chances d'être détecté comme tel à chaque cycle, donc après seulement 64 cycles de test, la probabilité qu'un nombre composite ne soit pas détecté est stupéfiante 2-128. En d'autres termes, le test a un 4-n chance d'un faux négatif, où n est le nombre de tours de test. Il existe également un certain nombre de façons beaucoup plus lentes de tester si un nombre est premier avec certitude complète , comme le test de primalité Agrawal – Kayal – Saxena , mais à des fins cryptographiques, être vraiment, vraiment sûr est suffisant, donc ils ont tendance à ne pas être utilisés.

Par défaut, OpenSSL a tendance à être paranoïaque supplémentaire et effectue d'autres tests, en particulier pour un prime prime . Ainsi, lorsqu'un nombre premier, p, est trouvé, il vérifie également si (p - 1)/2 est premier. Ceci est important pour des applications spécifiques de nombres premiers tels que Diffie – Hellman où des nombres premiers sûrs empêchent certaines attaques.

Ceci est possible à grande vitesse car vérifier qu'un entier est un nombre premier avec une marge d'erreur extrêmement faible est beaucoup plus facile que de le factoriser, et parce que les nombres premiers ne sont pas ça peu courant (il est facile de trouver un grand nombre de nombres premiers en incrémentant un nombre et en testant la primalité). Le test de primalité Miller-Rabin est très efficace. Le test prouve la composition si xn - 1 ≢ 1 (mod n) (le test de Fermat ), et en testant si x(n - 1)/2e (mod n) est une non triviale racine carrée de 1 mod n n est l'entier testé et x est un aléatoire témoin satisfaisant l'intervalle 1 <x <n.

L'implémentation pseudocode du test tiré de Wikipédia est:

 Entrée: n> 3, un entier impair à tester pour la primauté; 
 K, un paramètre qui détermine la précision du test 
 Sortie: composite si n est composite, sinon probablement premier 
 écrivez n - 1 comme 2r· D avec d impair en factorisant les puissances de 2 de n - 1 
 WitnessLoop: répéter k fois: 
 Choisir un entier aléatoire a dans la plage [2, n - 2] 
 X ← a mod n 
 si x = 1 ou x = n - 1 alors 
 continuer WitnessLoop 
 répéter r - 1 fois: 
 x ← x2 mod n 
 si x = 1 alors 
 retourne composite 
 si x = n - 1 alors 
 continue WitnessLoop 
 retourne composite 
 retour probablement premier 

Voir cette réponse Crypto.SE sur la génération de clés RSA et la norme FIPS 186-4 , section 5.1.

42
forest