Primzahltest in Polynomialzeit Der Algorithmus von Agrawal, Kayal

Werbung
Primzahltest in Polynomialzeit
Der Algorithmus von Agrawal, Kayal und Saxena
1. Worum geht es?
Das Problem, um das es geht, heißt „PRIMES“. Es entscheidet für eine vorgegebene Zahl
n > 2 die Frage, ob n prim oder zusammengesetzt ist. Algorithmentheoretisch heißt das:
PRIMES = { bin(k) | k ist eine Primzahl }
Die Menge PRIMES enthält also die Binärdarstellungen aller Primzahlen und ist damit eine
Sprache: PRIMES ⊆ {0,1}*.
Zuerst einmal lässt sich feststellen, dass diese Sprache entscheidbar ist, denn man kann sehr
leicht einen (sogar deterministischen) Algorithmus angeben, der die Frage: „n∈ PRIMES?“
für alle natürlichen Zahlen n löst. Man prüft einfach für alle ungeraden Zahlen i mit
2 ≤ i ≤ n , ob n ohne Rest durch i teilbar ist. Wenn der Test für alle i fehlschlägt ist n prim,
und ansonsten zusammengesetzt.
Dieser einfache Algorithmus ist aber für die für Informatiker interessante Frage, ob PRIMES
in der Klasse P, der deterministisch in polynomieller Zeit in der Länge der Eingabe
entscheidbaren Sprachen, liegt, schon nicht mehr zu verwenden, denn als Länge der Eingabe
gilt für PRIMES die Anzahl der Bits der Binärdarstellung von n:
|bin(n)| = log 2 (n + 1)
Ein Polynomialzeitalgorithmus für PRIMES hat also für ein Polynom p eine Laufzeit von
O(p(|bin(n)|)) = O(p(log(n))). Der Algorithmus benötigt aber O( n ) Divisionen. Bisher hatte
man aber auch keinen anderen deterministischen Algorithmus gefunden, der dieses Kriterium
erfüllt.
Der schnellste deterministische Algorithmus, der bis August 2002 bekannt war, lief in
O((log n)c log log log n), was aber leider ganz knapp exponentiell in |bin(n)| ist.
Also musste man an einer anderen Stelle Abstriche machen: Dem Determinismus. Man fand
randomisierte Algorithmen, die das Problem mit einer von n unabhängigen
Fehlerwahrscheinlichkeit in O(log(n)) lösten. Wollte man eine von n abhängige
Fehlerwahrscheinlichkeit, also etwa n-c für eine Konstante c, kostete das eine erhöhte
Laufzeit: O((log n)2) . Unglücklicherweise kann es bei solchen randomisierten Algorithmen
aber vorkommen, dass eine zusammengesetzte Zahl als prim deklariert wird, wenn auch nur
mit einer sehr geringen Wahrscheinlichkeit.
Der neue Algorithmus von Agrawal, Kayal und Saxena, dessen Laufzeit in O~((log n)6) (das
„~“ bedeutet hier, dass Faktoren der Form (loglog n)k für eine Konstante k vernachlässigt
werden) ist, hat verglichen mit den randomisierten Algorithmen, die das Primzahlproblem in
der Praxis gut genug lösen, eine sehr hohe Laufzeit. Deshalb beschränken sich die
1
Auswirkungen der Entdeckung des Algorithmus eher auf den theoretischen Fortschritt als auf
den praktischen Gewinn.
Für die Kryptographie ist der Algorithmus immerhin insofern nützlich, dass er einen
Verifizierer für die Frage, ob das Problem der Primfaktorzerlegung einer gegebenen Zahl m
in der Komplexitätsklasse NP liegt, liefert. Beweis: Man rät eine Menge von Zahlen und zeigt
für diese Zahlen deterministisch in Polynomialzeit, dass sie die Primfaktorzerlegung von m
sind. Die Anzahl dieser Primfaktoren ist höchstens |bin(m)| = log 2 (m + 1) , also im erlaubten
polynomiellen Rahmen, da im schlimmsten Fall m eine Zweierpotenz ist. Für alle geratenen
Zahlen kann man in Polynomialzeit mit dem Algorithmus von Agrawal, Kayal und Saxena
zeigen, dass diese auch wirklich prim sind. Und die Frage, ob diese Zahlen aufmultipliziert m
ergeben lässt sich sogar in logarithmischer Zeit beantworten (dazu später mehr).
2. Die Grundidee
Ausgegangen sind die drei Entdecker des Algorithmus von einem Satz aus der Algebra über
Primzahlen:
Satz 2.1: Sei n
gilt:
2 eine natürliche Zahl und a eine zu n teilerfremde natürliche Zahl. Dann
n ist prim ⇔ (X + a)n ≡ (Xn + a) (mod n).
Beweis siehe [2]
Wenn man also bei der rechten Aussage die linke Seite ausmultipliziert fallen modulo n
gerechnet alle Summanden mit Koeffizienten ≠ 1 weg, weil sie Vielfache von n sind.
Ein Beispiel: Setze n = 2
(X + a)² = X² + 2Xa + a²
Wenn man nun den rechten Ausdruck modulo 2 rechnet fällt der Term 2Xa weg, weil 2 ein
Teiler von 2Xa ist, also ergibt sich X² + a².
Nun stellt sich natürlich die Frage: Wie nützt man diesen Satz in Bezug auf die Frage, ob n
prim ist, aus? Man könnte zum Beispiel a = 1 wählen und dann alle Koeffizienten (mod n) des
Polynoms, das man durch einfaches Ausmultiplizieren von (X + a)n erhält, berechnen. Die
müssten, wenn n prim ist, alle – außer denen bei Xn und an, die natürlich immer 1 sind –
modulo n wegfallen. Wenn einer oder mehr übrig bleiben, ist n zusammengesetzt.
Der Haken dabei ist aber, dass man bei diesem Verfahren noch mehr Operationen hat als bei
dem ganz naiven Algorithmus aus dem ersten Abschnitt: Man muss nämlich n + 1 Terme
berechnen!
Der eigentliche Trick des neuen Algorithmus ist es aber die Äquivalenz
(X + a)n ≡ (Xn + a) (mod n)
2
über einen „Umweg“ zu testen. Man wählt sich nämlich ein Polynom Xr – 1 mit einem
geschickt ausgesuchten r (dazu im nächsten Abschnitt mehr), und vergleicht die beiden Seiten
dann nicht mehr nur noch modulo n sondern auch modulo dem neuen Polynom Xr – 1. Diese
modulo-Operationen sind im Übrigen assoziativ, d.h. es ist egal in welcher Reihenfolge man
sie ausführt, es kommt in beiden Fällen dasselbe heraus. Man berechnet also
(X + a)n mod (n , Xr – 1)
und
(X n + a) mod (n , Xr – 1)
und vergleicht wie bisher die Koeffizienten.
Wenn n prim ist, müssen selbstverständlich nach wie vor alle Summanden außer Xn mod r und a
mod n wegfallen. Das heißt, dass die Äquivalenz für alle r gilt. Nun möchte man aber nicht
für alle r < n alle zu n teilerfremden a durchlaufen, um die Primalität von n zu erreichen,
sondern man geht vom umgekehrten Fall aus. Man möchte also, wenn n zusammengesetzt ist,
ein r finden können, bei dem die Äquivalenz nicht gilt. Und dieses r darf auch nicht zu groß
sein, damit die Grade der Polynome nicht zu groß werden.
Das wichtigste bei diesem Primzahltest ist es also herauszufinden, was ein geeignetes r ist,
und vor allem auch zu zeigen, dass die auftretenden r nicht zu groß sind. Oder genauer: im
erlaubten polynomiellen Rahmen sind.
Aus algebraischen Gründen muss man, wenn man ein „gutes“ r gefunden hat, noch die
erwähnte Äquivalenzbedingung für eine ganze Reihe von a testen, um dann schließen zu
können, dass n Potenz einer Primzahl ist. Dieser Fall ist dann endlich leicht genug zu
behandeln.
3. Der Algorithmus
Input: ungerade Zahl n > 2
1. if ( n hat die Form ab für b > 1 ) then output zusammengesetzt;
2. r ← 2;
3. while ( r < n ) {
4.
if ( ggt(n,r) 1 ) then output zusammengesetzt;
5.
if ( r prim ) then
6.
q ← grösster Primfaktor von r – 1;
7.
if ( q ≥ 4 r log n )
8.
and ( n(r-1)/q ≡/ 1 (mod r) ) then
9.
break;
10. r ← r + 1;
11. }
12. for a = 1 to 2 r log n do
13. if (X + a)n ≡/ (Xn +a) (mod Xr – 1, n) then
14.
output zusammengesetzt;
15. output prim;
3
4. Die Laufzeitanalyse
4.1 Die Einzeloperationen
Die wichtigste Operation im Algorithmus ist die Exponentiation. Sie kommt in den Zeilen 1,
8 und 13 vor. Um den Berechnungsaufwand gering zu halten wird die Exponentiation mit
Hilfe einer rekursiven Funktion realisiert, die sich „schnelle Exponentiation“ nennt (im
Englischen „repeated squaring“ (wiederholtes Quadrieren), oder auch „binary method“):
Seien a > 0 und m 0 beliebige natürliche Zahlen.
für m = 0
1,
am =
a, für m = 1
(a ²) s für m > 1, m gerade, m = 2 s
(a ²) s ⋅ a für m > 1, m ungerade, m = 2 s + 1
Offensichtlich werden für diese Art der Exponentiation maximal 2 log2 m Multiplikationen
benötigt. Die Laufzeit der „schnellen Exponentiation“ ist also in O(log m).
Im ganzen Algorithmus kann an keiner Stelle eine Zahl auftreten, die größer ist als n². Man
beachte dazu insbesondere die Zeile 8 und 13: In Zeile 8 wird bei jedem Einzelschritt der
Exponentiation durch die Operation (mod r) das Zwischenergebnis kleiner als r gemacht.
Dadurch treten in Zeile 8 keine größeren Zahlen als r² auf (=r² nur im letzten Schritt falls r =
n wird). Analog werden die Zahlen in Zeile 13 klein gehalten (hier werden auch die Grade der
Polynome durch die modulo-Operationen klein gehalten).
n ist. Für b kommen
Zeile 1: Hier wird getestet ob n echte Potenz ab einer Zahl 2 a
dann offensichtlich nur Zahlen von 2 bis log2 n in Frage. Für alle diese b stellt man nun mit
Hilfe der „schnellen Exponentiation“ in O(log b) Operationen fest, ob ab < n, oder ab = n, oder
ab > n gilt. Auf diese Weise kann man {1,…,n} binär nach dem richtigen a durchsuchen.
Wenn es ein a gibt für das ab = n gilt, ist man fertig, falls nicht, sucht man mit dem nächsten b
weiter. Die binäre Suche nach dem richtigen a benötigt O(log n) Exponentiationen, jede
Exponentiation noch einmal O(log n) Operationen, macht mit O(log n) zu prüfenden b
zusammen O((log n)³) Operationen für die erste Zeile.
Definition 4.1.1 Sei n eine natürliche Zahl. Wir nennen eine Primzahl r < n „n-gut“, wenn r /|
n und der größte Primfaktor q von r – 1 die beiden folgenden Bedingungen erfüllt:
(i)
(ii)
q ≥ 4 r log n, und
n(r-1)/q ≡/ 1 (mod r)
Die Schleife in den Zeilen 3 – 11 sucht eine Primzahl r, die genau diese beiden Bedingungen
erfüllt. Die Frage, wie oft diese Schleife durchlaufen wird, hängt davon ab, welcher der drei
folgenden Fälle zuerst eintritt:
1.
2.
3.
Fall: ggt(n,r) 1
Fall: r ist n-gut
Fall: r = n
4
Sei p(n) nun das kleinste r, für das einer der drei Fälle eingetreten sei. In Abschnitt 4.2
werden wir sehen, dass p(n) = O((log n)6).
Zeile 4 Die ggt-Berechnung wird mit dem euklidischen Algorithmus erledigt, der für ein r
einen Aufwand von O(log n) hat. Der Aufwand für den ganzen Algorithmus kann also mit
O(p(n) log n) abgeschätzt werden.
Zeile 5 Die Frage, ob r prim ist, ist streng genommen ein rekursiver Aufruf des zugrunde
liegenden Problems. Da wir r aber polynomiell in der Eingabelänge vorliegen haben (siehe
Abschnitt 4.2) dürften wir an dieser Stelle - theoretisch - unseren naiven Algorithmus aus dem
ersten Abschnitt (der an dieser Stelle r auf Teilbarkeit mit allen ungeraden Zahlen von 2 bis
r testen würde) verwenden ohne die Polynomialität des Algorithmus zu verletzen. Aber es
geht schneller: Man führt eine Primzahltabelle mit, die immer alle Primzahlen bis zur
nächsten Zweierpotenz 2 log2 r enthält. Das ist ebenfalls wegen der Polynomialität von r
erlaubt, hat aber einen geringeren Gesamtaufwand von O(p(n) loglog(p(n))) gegenüber
O p(n ) p (n ) .
(
)
Zeile 6 Um zu bestimmen, ob der größte Primteiler von r – 1 mindestens 4 r log n ist, nimmt
man dieselbe Tabelle, und verwendet jetzt endlich doch unseren anfangs eingeführten, naiven
Algorithmus, allerdings für ein anderes Ziel. Man dividiert r – 1 durch alle seine Primfaktoren
zwischen 2 und r , und schaut jedes Mal nach, ob das Ergebnis eine Primzahl ist (die man in
der Tabelle hat). Wenn ja hat man den größten Primteiler gefunden. Wenn nicht, sucht man
weiter Primteiler. Gesamtaufwand: O p(n ) p (n )
(
)
Zeile 8 Hier nimmt man wie schon erwähnt die schnelle Exponentiation, die einen
Gesamtaufwand von O(p(n) log n) verursacht.
Der Gesamtaufwand für alle Schleifendurchläufe ist zusammengerechnet also
O(p(n)3/2 + p(n) log n).
Die Schleife in den Zeilen 12 – 14 prüft für das vorher gefundene r und alle a mit 1 a
2 r log n, ob das Polynom (X + a)n bei Ausmultiplizieren alle seine Summanden außer denen
mit Koeffizienten 1 modulo (Xr – 1,n) verliert, oder nicht. Auch hier verwendet man, wie
erwähnt, die schnelle Exponentiation, wobei nach jeder einzelnen Multiplikation die
Rechnung modulo n und modulo Xr – 1 durchgeführt wird. Auf diese Weise ist während der
ganzen Rechnung sichergestellt, dass keine Polynome mit Grad größer als r – 1 und auch
keine Koeffizienten größer als n – 1 auftauchen. Eine Multiplikation von Polynomen mit Grad
< r hat einen Aufwand von O(r²). Zusammen mit der schnellen Exponentiation ergibt sich für
die Berechnung des gesamten Ausdrucks eine Laufzeit von O(p(n)² log n). Für alle a im
erwähnten Intervall ergibt das einen Gesamtaufwand von
O( p (n) log n . p(n)² log n) = O(p(n)5/2 (log n)²).
Wenn also r nach oben durch ein Polynom p(n) = O((log n)6) abgeschätzt werden kann, dann
liegt die Laufzeit des Algorithmus in O((log n)17). Mit schnelleren PolynomMultiplikationsverfahren kann diese Schranke noch auf O((log n)12) gesenkt werden.
5
Man vermutet sogar, dass sich innerhalb der ersten O((log n)²) Zahlen ein r finden lässt, für
das (r – 1)/2 prim ist (eine sogenannte Sophie-Germain-Primzahl). Dann würde sich die
Laufzeit sogar auf O~((log n)6) verringern[3].
4.2 Schranke für „gute“ r
Um zu zeigen, dass die while-Schleife im Algorithmus nach spätestens O((log n)6)
Durchläufen abbricht, benötigen wir drei Aussagen aus der Zahlentheorie.
Definition: Für eine positive reelle Zahl x sei
(x) = |{ p
x | p ist eine Primzahl}|.
In (x) steht also die Anzahl der Primzahlen, die höchstens so groß wie x sind.
Satz 4.2.1 (Primzahlsatz)
π ( x)
lim x / ln x
=1
x →∞
Der Primzahlsatzes besagt, dass die Anzahl der Primzahlen asymptotisch betrachtet so schnell
wächst wie x/ln x. Wir brauchen aber nur eine abgeschwächte Version:
Fakt 4.2.2 Für alle x
x
6 log x
(x)
2 gilt:
8x
log x
„log“ steht ab hier für den Logarithmus zur Basis 2.
In unserem Algorithmus interessieren uns besonders diejenigen Primzahlen r, bei denen
r – 1 einen sehr großen Primteiler hat.
Definition: Sei a eine natürliche Zahl. Dann bezeichne P(a) die größte Primzahl, die a teilt.
Fakt 4.2.3 Es gibt ein (kleines) c > 0 und ein (großes) x0, so dass für alle x
|{ r | r Primzahl, r
x, P(r – 1) > x3/2}|
c
x0 gilt:
x
.
log x
Zusammen mit 4.2.2 besagt dieses Fakt, dass asymptotisch betrachtet für einen konstanten
Bruchteil der Primzahlen r x gilt, dass der größte Primteiler größer ist als x3/2.
Nun haben wir das Rüstzeug, um das Lemma zu zeigen, welches direkt impliziert, dass die
while-Schleife nach O((log n)6) Durchläufen abbricht.
Lemma 4.2.4 Es gibt Konstanten c1, c2 > 0 und n0 mit folgender Eigenschaft: Für jedes
n n0 gibt es eine Primzahl r mit c1(log n)6 < r c2(log n)6, die entweder Teiler von n ist oder
n-gut.
6
Beweis. Sei c wie in Fakt 4.2.3 gewählt. Wir rechnen zunächst mit Konstanten
c2 c1 1 und bestimmen hinterher wie groß sie sein müssen. Die Zahl n sei beliebig, aber
(auch bezüglich c1 und c2 und x0 aus Fakt 4.2.3) groß genug, um die folgenden
Abschätzungen zu erfüllen.
Definition Wir nennen eine Zahl r < n „n-speziell“, wenn r prim ist und
P(r – 1) > (c2(log n)6)2/3 gilt.
„n-spezielle“ Zahlen sind also gerade solche, die Elemente der in Fakt 4.2.3 beschriebenen
Menge sind. Außerdem genügen n-spezielle Zahlen wie auch n-gute Zahlen (siehe Def.4.1.1)
einer Mindestabschätzung. Dass die Mindestabschätzung für n-spezielle Zahlen, wie wir sie
gewählt haben, für die „n-Gutheit“ genügt, zeigen wir hinterher. Zunächst betrachten wir aber
die Anzahl solcher n-speziellen Zahlen im links offenen und rechts abgeschlossenen Intervall
I := (c1(log n)6,c2(log n)6].
|{ r | r ist n-speziell und c1(log n)6 < r
c2(log n)6 | r ist n-speziell}| – |{r
c2 (log n) 6
8c1 (log n) 6
c⋅
–
log(c2 (log n) 6 ) log(c1 (log n) 6 )
|{r
c ⋅ c2 (log n) 6
8c (log n) 6
– 1
7 log log n
6 log log n
=
c2(log n)6}|
c1(log n)6 | r ist Primzahl}|
(Weil c1, c2 > 0 so gewählt, dass log(c1), log(c2) > 0)
(log n) 6 cc2 8c1
.
⋅
−
log log n
7
6
cc2 8c1
−
positiv ist (wegen Fakt 4.2.3), dann ist die
7
6
c (log n) 6
Anzahl der n-speziellen Zahlen in ((4 log n)6, c2(log n)6] mindestens 3
.
log log n
Wähle nun c1 = 46 und c2 so, dass c3 =
Jetzt müssen wir aber noch den Schritt von n-speziell nach n-gut machen.
Setze dazu y = c2 (log n)6, also auf die rechte Grenze des Intervalls I, und betrachte das
Produkt
=
∏ (n
j
1/ 3
− 1) = (n − 1) ⋅ (n 2 − 1) ⋅ ... ⋅ (n y
− 1)
1≤ j ≤ y1 / 3
Woher kommt dieses Produkt? Die zweite Eigenschaft, die eine „n-gute“ Zahl haben muss ist,
dass n(r-1)/q mod r nicht kongruent 1 sein darf. Wenn also ein r keines der oben aufgeführten
(nj – 1) teilt, ist dieses r „n-gut“.
Beachte nun, dass n! < nn für alle n > 1 gilt. Aus diesem Grund gilt die folgende Ungleichung:
( )
1/ 3
< ny
y1 / 3
2/3
Die größte Anzahl von Primfaktoren erhält man genau dann, wenn n y eine Zweierpotenz ist.
Daraus folgt, dass die Anzahl der Faktoren in der Primfaktorzerlegung von kleiner ist als
7
( )= y
log n y
2/3
2/3
log n = (c2 (log n) 6 ) 2 / 3 log n <
c3 (log n) 6
log log n
(1)
(für n genügend groß). Die letzte Ungleichung ergibt sich aus folgender Überlegung:
c22 / 3
log n
<
c3
log log n
Die rechte Seite ist eine unbeschränkte, ab n > 7 streng monoton steigende Funktion. Die
linke Seite ist eine Konstante. Daraus folgt, dass es eine Stelle n gibt, ab der die Ungleichung
immer gilt. Deshalb hatten wir n am Anfang groß genug gewählt.
(1)
Wir haben also mehr n-spezielle Zahlen in I als Teiler von
6
n) , c2(log n)6] eine n-spezielle Zahl r, die kein Teiler von ist.
. Daher gibt es in ((4 log
Diese Primzahl hat die gesuchten Eigenschaften: Wenn r | n, sind wir fertig. Wenn r /| n, ist r
n-gut, was man wie folgt einsieht:
(i)
Weil r n-speziell ist, hat r – 1 einen Primfaktor q mit
q > (c2(log n)6)2/3;
weil r
(4 log n)6 ist gilt
q > r2/3 =
(ii)
r ⋅ r 1/6
4 r log n
Und weil r das Produkt nicht teilt, gilt für jedes j, 1
r /| (nj – 1), d.h. nj ≡/ 1 mod r. Nach (i) ist aber
(r – 1)/q < r / r2/3 = r1/3
j
y1/3, dass
y1/3;
daher gilt n(r-1)/q ≡/ 1 mod r, wie gewünscht.
5. Der Korrektheitsbeweis
Der Kern des Korrektheitsbeweises des Agrawal/Kayal/Saxena – Tests ist im folgenden Satz
zusammengefasst, dessen Beweis hier nur skizziert wird.
Hauptsatz 5.1 Es sei
(i)
(ii)
n 2 eine natürliche Zahl;
r < n eine Primzahl mit r /| n;
(iii)
(iv)
q eine Primzahl mit q | (r – 1), und q
n(r-1)/q ≡/ 1 (mod r)
4 r log n, und
8
Weiter gelte für L = 2 r log n :
(v)
(vi)
Für alle a, 1
Für alle a, 1
a
a
L: a und n teilerfremd;
L: (X + a)n ≡ (Xn + a) mod (n, Xr – 1).
Dann ist n = pi für eine Primzahl p und ein i
1.
Beweisidee:
Man zeigt für alle a mit 1
( X + a )n p
i
j
(
a
i
j
≡ Xnp +a
L und i,j
)
1, dass gilt:
mod (n, Xr – 1)
Wobei p Primfaktor von n ist (Wenn n = p gilt es offensichtlicherweise)
Daraus folgt aber, dass
( X + a )n p
i
j
i
j
≡ Xnp +a
in
=
p
[x] / h(x)
h(x) sei hier ein irreduzibles Polynom vom Grad d = ordr (p). Man kann beweisen, dass h(x)
existiert. Daraus folgt, dass | | = pd = r gilt. Aber für 0
i,j
r
sind das mehr als r
Kongruenzen. Also muss es modulo r zwei gleiche geben. Daraus kann man dann für Paare
(i,j) und (k,l) zeigen (siehe [2]), dass folgendes gilt: nipj ≡ nkpl (mod r). Und daraus folgt,
dass n eine echte Primpotenz ist.
Mit Hilfe dieses Satzes lässt sich der Korrektheitsbeweis führen:
Satz 5.2 Der Algorithmus gibt „prim“ aus ⇔ n ist eine Primzahl
Beweis. „ ⇐ “: Sei n eine Primzahl. Dann ist n nicht von der Form ab, b > 1, also schlägt der
Test in Zeile 1 immer fehl. Der Test in Zeile 3 ergibt für alle r ggt(n,r) = 1. Die beiden
Möglichkeiten, wie die Schleife in Zeilen 3 – 11 terminieren könnte, nämlich erstens, weil r
prim ist und die Tests in Zeilen 7 und 8 bestanden hat, oder, zweitens, weil r = n ist, können
wegen Satz 2.1 für kein zu n teilerfremdes a die Bedingung in Zeile 13 erfüllen. Für n | a gilt
dies auch, weil dann a ≡ 0 mod n. Also wird Zeile 15 erreicht und „PRIM“ ausgegeben.
„
“: Zu zeigen:Wenn der Algorithmus „PRIM“ ausgibt, dann ist n eine Primzahl.
Fall 1: Die Schleife in den Zeilen 3 – 11 wird über die Bedingung in Zeile 3 verlassen, also
gilt r = n. Dann muss wegen des Tests in Zeile 3 für jedes r < n gelten, dass r und n
teilerfremd sind, insbesondere, dass r /| n, also ist n eine Primzahl.
Fall 2: Die Schleife in den Zeilen 3 – 11 wird über das „break“-Kommando in Zeile 9
verlassen. Der Inhalt von r in diesem Moment sei r’. Dann gilt:
(i)
r’ < n und r’ ist eine Primzahl (wegen Zeile 5);
9
(ii)
(iii)
Für alle a, 1
(iv)
(v)
der größte Primfaktor q von r’ – 1 erfüllt q
n(r’-1)/q ≡/ 1 (mod r’) (wegen Zeile 8);
a
4 r ' log n (wegen Zeile 7);
L = 2 r ' log n gilt:
a und n sind teilerfremd (wegen Zeile 7 ist L < 4 r ' log n q < r’, also wurde
für alle diese a in den vorherigen Schleifendurchläufen in Zeile 4 getestet, ob
ggt(n,a) 1 ist) und
(X + a)n – (Xn + a) ≡ 0
(mod Xr’ – 1,n)
(getestet in der Schleife in den Zeilen 12 – 14).
Damit erfüllen n,r’ und q alle Voraussetzungen des Hauptsatzes 5.1. Nach diesem Satz
ist also n = pi für eine Primzahl p. Wegen des Tests in Zeile 1 kann aber n nicht echte
Potenz irgendeiner Zahl sein, also ist i = 1 und n ist selbst eine Primzahl.
Literatur:
[1] Manindra Agrawal, Neeraj Kayal und Nitin Saxena, PRIMES is in P, Manuscript 2002.
http://www.cse.iitk.ac.in/users/manindra/primality.ps oder
http://www.cse.iitk.ac.in/news/primality.pdf
[2] Primzahltest in Polynomialzeit – Der Algorithmus von Agrawal, Kayal und Saxena
Vorlesungsnotizen von Martin Dietzfelbinger, TU Ilmenau
[3] Stefan Wehmeier: Der AKS - Primzahltest
10
Herunterladen