Algoritmes voor Priemgetallen

advertisement
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
Download