Algoritmes voor Priemgetallen Tom van der Zanden Projectje Security, juni 2013 1 Introductie Voor cryptograe zijn priemgetallen erg belangrijk. Veel encryptiesystemen maken gebruik van hun eigenschappen en vaak hangt de veiligheid van het cryptosysteem af van de moeilijkheid van priemfactorisatie. Bij RSA bestaat bijvoorbeeld de privésleutel uit een paar priemgetallen p, q en de publieke sleutel is hun product pq . Het grootst bekende priemgetal is 257885161 −1.[3] Hoewel een langere sleutel in het algemeen een betere beveiliging biedt is dit specieke getal vanwege zijn bekendheid natuurlijk een heel slechte keuze voor de privésleutel. Hoe kun je dan wèl op een goede manier een sleutel voor RSA genereren? In dit paper beantwoord ik deze vraag en bekijk ik een aantal algoritmen en technieken voor priemtesten en het genereren van priemgetallen. Ook behandel ik een aantal wiskundige stellingen die betrekking hebben tot dit onderwerp. 2 Priemgetallen genereren Voor sommige toepassingen is het nodig om een lijst van alle priemgetallen onder een zeker getal n te genereren. Het is natuurlijk mogelijk om van ieder getal onder n afzonderlijk te testen of het priem is. Gebruikmakend van de MillerRabin test (zie 3.3) zou zo'n algoritme Ω(n log n3 ) tijd kosten. Dit is echter niet erg eciënt. Voor het maken van een lijst van priemgetallen worden meestal "zeven" gebruikt. De meest bekende is de zeef van Eratosthenes. 2.1 De zeef van Eratosthenes De zeef van Eratosthenes maakt een lijst van kandidaatpriemgetallen 2 . . . n. Het algoritme pakt het kleinste getal uit de lijst en markeert dit als priem en verwijdert het uit de lijst. Vervolgens worden ook alle veelvouden van dit getal verwijderd. Het kleinste getal dat nu nog over is is het volgende priem. Voor ieder priemgetal p ∈ [2, . . . n] moeten np veelvouden bekeken worden, ieder in P O(log n) tijd (voor de optelling). De sommatie p∈[2,...,n],priem p1 staat bekend als de harmonische reeks van priemgetallen[11] en is O(log log n). De zeef van 1 Eratosthenes gebruikt dus O(n log log n∗log n) tijd en is dus sneller dan herhaald priemtesten (en veel makkelijker te implementeren). 2.2 Wielzeven Een logische verbetering op de zeef van Eratosthenes is om op te merken dat we onnodig veel tijd en ruimte kwijt zijn met even getallen. Behalve 2 is geen enkel even getal priem. Als we 2 als speciaal geval behandelen kunnen we het geheugengebruik halveren. Een slim persoon zou kunnen opmerken dat we nóg meer tijd kunnen besparen als we ook 3 als speciaal geval nemen en alle drievouden uitzonderen. We hoeven dan alleen getallen van de vorm 6k ± 1, k ∈ N te bekijken. Hiermee besparen we een factor 32 . Als we nog verder gaan kunnen we ook alle vijfvouden elimineren: we bekijken dan alleen getallen van de vorm 30k + a, k ∈ N, a ∈ {7, 11, 13, 17, 19, 23, 29}., dit levert een besparing van ongeveer 76%. De besparing blijft echter constant √ en neemt niet snel toe. Er bestaat een variant op deze techniek die slechts O( n) geheugen en O(n log n) tijd gebruikt.[9] 2.3 Zeef van Atkins De zeef van Eratosthenes is nog ineciënt omdat veel samengestelde getallen meerdere keren bekeken worden. De zeef van Atkins maakt gebruik van kwadratische vormen. Voor een kwadraatvrij getal n ≡ 1 (mod 4) geldt n priem is dan en slechts dan als 4x2 + y 2 = n een oneven aantal oplossingen heeft met x, y > 0. Het blijkt dat het mogelijk is om de oplossingen eciënt te enumereren. Door gebruik te maken√van een aantal van dit soort relaties kan Atkins n log n in O( log log n ) tijd en met O( n) geheugen de lijst van priemgetallen onder n vinden.[2] 3 Priemtesten Terug naar de vraag over het sleutelpaar van RSA: we zouden een grote lijst van priemgetallen kunnen genereren met een zeefalgoritme en vervolgens een willekeurig priemgetal uit die lijst kunnen pakken. Helaas is het zo dat als zo'n lijst berekend kan worden, een aanvaller in dezelfde tijd de lijst kan berekenen en alle getallen kan uitproberen. Het zou verleidelijk zijn om een willekeurig getal i ∈ N te kiezen en vervolgens het ie priemgetal pi te berekenen maar het is niet bekend of dit in redelijke tijd kan. Op het moment is de meest gebruikte methode om een sleutelpaar voor RSA te maken om willekeurige getallen te genereren en te testen of deze getallen toevallig priem zijn. Dit geeft aanleiding tot het beslisprobleem P RIM ES : voor een gegeven getal bepalen of het priem is. 2 3.1 Trial division k De meest naïeve manier om √ van een getal n ≈ 2 te bepalen of het priem is, is om simpelweg alle getallen ≤ n te proberen en te kijken of n door dit getal deelbaar is. Dit is voor de getallen die we in de cryptograe willen gebruiken natuurlijk ondoenlijk dus aan deze techniek besteden we verder geen aandacht. Omdat één √ deling O(log2 n) tijd kost, gebruikt deze methode in totaal O( n log2 n) tijd. 3.2 Stelling van Fermat (de kleine) De kleine stelling van Fermat zegt dat voor een priemgetal p en ieder getal a ∈ N geldt dat ap−1 ≡ 1 (mod p). Dit geeft aanleiding tot een simpele priemtest (eigenlijk samengesteldheidstest): kies een willekeurig getal a. Als an−1 6≡ 1 (mod n) dan is n niet priem (samengesteld). Als an−1 ≡ 1 (mod n) dan is n misschien priem. Het aantal samengestelde getallen waarvoor an−1 ≡ 1 (mod n) is erg klein. Voor a = n − 1 zijn er slechts 22 samengestelde getallen onder de 10.000 waarvoor de conditie waar is.[4] Door de test een aantal maal te herhalen met verschillende a kan de betrouwbaarheid verbeterd worden. Voor de meeste getallen werkt de Fermat-test goed maar er bestaan getallen n waarvoor toch voor iedere a ∈ Z∗n geldt dat an−1 ≡ 1 (mod n) ondanks dat n niet priem is. Dit zijn de zogenaamde Carmichaelgetallen, dit zijn de getallen die door de Fermat-test nooit als samengesteld gezien zullen worden. Als n niet Carmichael is (er bestaat ten minste één a0 met a0n−1 6≡ (mod n)) dan is de kans dat een willekeurige a bewijst dat n samengesteld is ten minste 21 . Dit is omdat als a de samengesteldheid niet bewijst, aao het wel doet. Als we dus k verschillende waarden voor a proberen en voor allemaal geldt dat an−1 ≡ 1 (mod n) dan is de kans dat n priem is ten minste 1 − ( 12 )k (gegeven dat n niet Carmichael is, maar Carmichaelgetallen zijn zeer zeldzaam). 3.3 Miller-Rabin-test De Miller-Rabin-test gebruikt een iets andere eigenschap van priemgetallen dan de test van Fermat. Voor een oneven getal N (schrijf N − 1 = 2k m, k ≥ 0, m oneven) en a ∈ Z, N - a geldt dat N composiet is als am 6≡ 1 (mod N ) en i als voor alle 0 ≤ i ≤ k − 1 geldt dat a(2 ) 6≡ −1 (mod N ).[4] De test bestaat uit het kiezen van een willekeurige a en het proberen van alle bijbehorende i. Het leuke van de Miller-Rabin-test is dat er geen Carmichaelachtige getallen zijn zoals die voor de Fermat-test wél bestaan: als n samengesteld is tonen ten minste 43 van de getallen uit [1, . . . , n] de samengesteldheid van het getal n aan. Toch is de Miller-Rabin-test net als de Fermat-test een Monte-Carlo-algoritme. Als de uitkomst "samengesteld" is dan is het getal ook daadwerkelijk samengesteld, maar als de uitkomst "priem" is dan is het getal slechts waarschijnlijk priem. Afhankelijk van het aantal gebruikte iteraties k heeft de Miller-Rabin-test een looptijd van O(k log n3 ) (log log-factoren zijn weggelaten). 3 Het gebruik van Miller-Rabin om priemgetallen voor RSA te genereren is gestandaardiseerd door het Amerikaanse "National Institute of Standards and Technology" (NIST).[7] Het NIST beveelt (afhankelijk van de sleutellengte) een minimum van 40 tot 64 iteraties aan. 3.4 Complexiteit van priemtesten We hebben tot nu toe twee probabilistische priemtesten gezien maar het is nog niet duidelijk of we ook in redelijke tijd deterministisch kunnen bepalen of een getal priem is. We kunnen ons afvragen of P RIM ES ∈ N P . Als een probleem in N P zit dan is het nodig om in polynomiale tijd te kunnen bewijzen dat een ja-antwoord correct is. Voor het omgekeerde probleem (COM P OSIT ES ) kan dat makkelijk: als we de factoren weten kunnen we in polynomiale tijd veriëren dat een getal samengesteld is. Hieruit volgt dat P RIM ES ∈ co − N P . Het is ook waar dat P RIM ES ∈ N P . Het is in 1975 aangetoond dat ieder priemgetal een "certicaat" heeft dat in polynomiale tijd bewijst dat het priem is. [8] Het is sinds 2006 ook bekend dat P RIM ES ∈ P door de publicatie van de AKSpriemtest.[1] Deze bepaalt in O(log12 n) of een getal priem is. Ook hier heb ik de loglog -factoren weggelaten maar het is waarschijnlijk dat de test nog veel sneller is (O(log n6 )). Het is dus mogelijk om deterministisch en in polynomiale tijd te testen of een getal priem is. 3.5 AKS-test De AKS-test (naar de uitvinders Agrawal-Kayal-Saxena) is de eerste deterministische en polynomiale priemtest. De Miller-Rabin-test zou onder aanname van de Riemannhypothese ook deterministisch en polynomiaal zijn maar dit is nog niet bewezen. De AKS-test gebruikt de stelling dat een getal n priem is dan en slechts dan als [1] (x − a)n ≡ xn − a (mod N ) waarbij x een vrije variabele in het polynoom is en a ∈ Z met gcd(a, n) = 1. Nu is het evalueren van zo'n polynoom niet haalbaar (dat kost Ω(n) - exponentieel veel tijd). Het blijkt dat het voldoende is om het polynoom te evalueren modulo het polynoom xr − 1. Als de gelijkheid waar is voor een aantal (logaritmisch veel) a's en r's dan is het getal n priem. Het AKS-algoritme is uiteindelijk versassend simpel en heeft de volgende stappen: 1. Als n = ab voor zekere a ∈ N, b > 1 dan is n SAMENGESTELD 2. Bepaal de kleinste r ∈ N zodat de orde van r in Zn groter is dan 4(log n)2 3. Als er een a ≤ r is met 1 < gcd(a, n) < n dan is n SAMENGESTELD 4. Als n ≤ r dan is n PRIEM p 5. Voor a = 1 tot x2 φ(r) log ny 4 Als (x + a)n 6= xn + a (mod xr − 1, n) dan is n SAMENGESTELD 6. n is PRIEM Als n priem is dan zal het algoritme altijd priem teruggeven. Het is namelijk niet mogelijk dat in één van de stappen 1,3,5 voor samengesteld wordt gekozen. Het is lastiger te zien dat een samengesteld getal ook altijd zo wordt aangemerkt. Als het algoritme in stap 4 voor priem zou kiezen dan en n is samengesteld dan zou in stap 3 al een factor zijn gevonden. Dit kan dus niet. Het is nu nog nodig om aan te tonen dat stap 5 voor een samengesteld getal ook altijd samengesteld kiest maar dit bewijs is te lastig om te behandelen ("bewijs door kantlijn"). 4 Priemgetallen genereren voor RSA 4.1 Met behulp van Miller-Rabin Gerard Tel schrijft in [10] dat "er zijn geen formules of algoritmen bekend die rechtstreeks vanuit random bits een priemgetal kunnen berekenen". Dit is niet helemaal waar (zoals zal blijken uit de volgende sectie) maar de Amerikaanse overheid [7] raadt inderdaad het volgende aan: genereer een reeks random getallen die ongeveer van de gewenste grootte zijn, en gebruik vervolgens Miller-Rabin om de priemgetallen er uit te lteren. De priemgetalstelling zegt dat de kans dat een getal n priem is daalt als 1 log n . Als we met deze methode een priemgetal dat ongeveer n groot is willen genereren moeten we dus verwacht O(log n) getallen genereren en testen. In totaal kost het maken van een random priemgetal van k bits O(k 4 ). 4.2 Maurer's Algoritme [5][6] Het genereren van priemgetallen met de Miller-Rabin-test heeft een nadeel: het algoritme is Monte-Carlo, het uitvoergetal kán incorrect zijn. Het is mogelijk om de uitvoer van Miller-Rabin met AKS te testen en eventueel een nieuw priemgetal te genereren, maar dit is langzaam. Maurer's algoritme genereert een random priemgetal (dat bijna uniform verdeeld is over de range waaruit het wordt gekozen) dat ook bewijsbaar correct is. Maurer's algoritme werkt met behulp van recursie en is iets mooier (slimmer) dan een stel willekeurige getallen genereren en hopen dat er een priemgetal tussen zit. MAURER(k) - genereert een priemgetal van k bits 1. Als k klein (≤ 20) is, kies dan random een priemgetal uit een voorberekende tabel 2. Kies c en m (experimenteel bepaald, hangt af van de computerarchitectuur. bijvoorbeeld c = 0.1, m = 20) 5 3. Bepaal de verhouding tussen het recursief te genereren priemgetal en het getal dat we nu genereren. (a) als k ≤ 2m maak dan r = 0.5. (b) anders (k > 2m) kies s ∈ [0, 1] random zodat k(1 − 2s−1 ) > m. Maak r = 2s−1 . 4. Recursiestap: q = M AU RER(xrky + 1) 5. Bereken I = 2k−1 2q 6. Herhaal tot een priemgetal is gevonden: (a) Genereer kandidaat: kies R ∈ [I + 1, 2I] en maak kandidaat n = 2Rq + 1 (b) Test: kijk of n deelbaar is door een getal < ck 2 - indien ja: ga terug naar (a) (c) Kies a ∈ [2, n − 2] en bepaal b = an−1 d = gcd(a2R − 1, n). (mod n) als b = 1 bepaal dan (d) Als d = 1 RETURN n De correctheid van het algoritme berust op de stelling van Pocklington. Deze stelling zegt iets zien p over de factoren van een getal n door te kijken naar een priem van grootte (n). Als n = q k R + 1, q priem en q - R en er bestaat een a ∈ N met de eigenschappen: 1. an−1 ≡ 1 2. gcd(a n−1 q (mod n) − 1, n) = 1 k dan is iedere priemfactor √ p van n van de vorm p = q r + 1, waarbij r ∈ [1, ..., R]. dat n priem is aangezien iedere Als q nu groter dan n is, dan volgt hieruit √ priemfactor p = q k r + 1 dan ook groter dan n moet zijn maar een getal n √ kan√alleen een (echte) priemdeler > n hebben als dat getal ook een priemdeler < n heeft. Maurer bewijst ook dat de kans dat in stap (6c) een geschikte a wordt gekozen minstens 1 − 1q is. Deze kans nadert dus tot 1 als q groot wordt. De 4 k looptijd van het algoritme is O( log k ) en dus is Maurer ook asymptotisch iets sneller dan de methode met Miller-Rabin.[5] 5 Conclusie In dit paper hebben we een aantal verschillende zeven gezien om priemgetallen te genereren. Deze zeef-algoritmen zijn echter niet geschikt om priemgetallen voor cryptograsche toepassingen te genereren omdat het draaien van de zeef even duur is als een eventuele aanval. Vervolgens hebben we een aantal priemtesten 6 bekeken. De Fermat-test is eenvoudig maar heeft last van Carmichael-getallen die door de Fermat-test nooit als samengesteld zullen worden aangewezen. De Miller-Rabin-test is een verbetering op de Fermat-test en kan in O(log n3 ) tijd van ieder getal met grote zekerheid zeggen of het priem is. Als de Riemannhypothese waar blijkt te zijn, dan is de Miller-Rabin-test deterministisch te maken in O(log n5 ) tijd. Tot slot hebben we de AKS-priemtest gezien, die bewezen deterministisch werkt en waarschijnlijk slechts O(log n6 ) tijd gebruikt. Vervolgens hebben we gekeken naar manieren om priemgetallen te genereren die geschikt zijn voor gebruik in RSA. Het meest gebruikt is een techniek die herhaald getallen genereert en die met Miller-Rabin op priemheid test. Zo wordt in O(log n4 ) tijd een getal gegenereerd dat waarschijnlijk priem is. Tot slot hebben we het algoritme van Maurer bekeken, dat een getal genereert dat k4 gegarandeerd priem is en dit doet in O( log k ) tijd. Referenties [1] Manindra Agrawal, Neeraj Kayal, and Nitin Saxena. Primes is in p. of Math, 2:781793, 2002. Ann. [2] A. O. L. Atkin and D. J. Bernstein. Prime sieves using binary quadratic forms. Mathematics of Computation, 73:2004, 1999. [3] Chris Caldwell. The largest known primesa summary, June 2013. [4] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction to algorithms. chapter 31. The MIT Press, 3rd edition, 2009. [5] Ueli M. Maurer. Fast generation of prime numbers and secure public-key cryptographic parameters. Journal of Cryptology, 8:123155, 1995. [6] Alfred J. Menezes, Paul C. Van Oorschot, Scott A. Vanstone, and R. L. Rivest. Handbook of applied cryptography. chapter 4. CRC Press, 1997. [7] National Institute of Standards and Technology. Digital signature standard (dss), June 2009. [8] Vaughan R. Pratt. Every prime has a succinct certicate. put., 4(3):214220, 1975. SIAM J. Com- [9] Paul Pritchard. Fast compact prime number sieves (among others). Algorithms, 4(4):332344, February 1984. J. [10] Gerard Tel. Cryptograe. chapter 6. 2006. [11] Eric Weisstein. "harmonic series of primes."from mathworlda wolfram web resource., June 2013. 7