3. Der AKS–Test
Transcription
3. Der AKS–Test
Feruniversität Hagen im Fachbereich Mathematik Bachelorarbeit über das Thema Der Primzahltest von Agrawal-Kayal-Saxena im Vergleich zum Primzahltest von Rabin-Miller Name und Anschrift: Annabell Berger Mendelssohnweg 7 07743 Jena Matr.-Nr.: 5014697 Betreuerinnen: Frau Professor Dr. Luise Unger Frau Dr. Silke Hartlieb Abgabedatum: 15. Oktober 2004 1 Inhaltsverzeichnis 0. Motivation 3 1. Begriffe aus der Komplexitätstheorie 4 2. Der Rabin–Miller–Test 6 0. Notation 6 1. Idee 7 2. Definitionen und Beweise 8 3. Der Algorithmus und seine Komplexität 10 3. Der AKS–Test 11 0. Notation 11 1. Idee 12 2. Definitionen und Beweise 13 3. Der Algorithmus und seine Komplexität 17 4. Experimente: Untersuchung der durchschnittlichen Laufzeit bei verschiedenen Bitstellenzahlen 20 1. Ansatz 20 2. Durchschnittliche Schnelligkeit des Rabin Miller Tests beim Erkennen von Primzahlen bzw. zusammengesetzten Zahlen 20 3. Durchschnittliche Schnelligkeit des AKS–Tests beim Erkennen von Primzahlen bzw. zusammengesetzten Zahlen 30 5. Vergleich und Zusammenfassung 35 Literatur 37 Anhang: Programme 38 2 0. Motivation Die Suche nach Primzahlen begleitet unsere Kulturgeschichte seit über 2000 Jahren. Die Frage nach den Beweggründen lässt sich je nach Weltanschauung auf unterschiedliche Art und Weise beantworten. Für Pythagoras aus Samos (530 v. Chr.) ist die Welt ein begrenzter, strukturierter in Harmonie befindlicher Kosmos. Prinzip der Harmonie ist die Zahl. 250 Jahre später leben in der wissenschaftlichen und dichterischen Metropole des hellenistischen Systems, Alexandria, bedeutende Gelehrte wie Euklid, sein Schüler Archimedes und der Vorsteher der Bibliothek und Erzieher des Kronprinzen, Eratosthenes. Euklid erbringt den Beweis für die Existenz von unendlich vielen Primzahlen. Eratosthenes entwickelt einen ersten Primzahltest genannt „Das Sieb des Eratosthenes“. Das Prinzip besteht darin, alle Vielfachen der natürlichen Zahlen von 2 bis zu einer gegebenen Zahl n zu streichen. Übrig bleiben alle Primzahlen, die kleiner oder gleich n sind. Somit lässt sich für eine gegebene Zahl n ermitteln, ob es sich um eine Primzahl handelt. Obwohl zu dieser Zeit die traditionelle griechische Religion weitergepflegt wird, gibt es zweifelsfrei die Suche nach einer mathematischen Wahrheit um ihrer selbst willen. Simon Singh erzählt in seinem Buch „Fermats letzter Satz“ eine Anekdote über Euklid, der einen Schüler auszahlte und ausschloss, als dieser ihn nach der Nützlichkeit der Mathematik befragte [SNGH02]. Unsere abendländische Kultur, geprägt von der Antike und ihren geistigen Nachfolgern, beinhaltet unterschwellig so manchen ideellen Gedanken der „alten Gelehrten“. Seit den 70er Jahren des 20. Jahrhunderts kommt jedoch ein neuer, ganz praktischer Grund für die Beschäftigung mit Primzahlen hinzu, nämlich das Verschlüsseln von Informationen. Das ist zwar auch eine sehr alte Idee, neu daran ist jedoch die Größe und Unterschiedlichkeit des Personenkreises, der, bedingt durch die Informationsgesellschaft, Verschlüsselungen benutzt. Damit einher geht eine Renaissance der Kryptographie, die Mitte letzten Jahrhunderts beginnt. In den 70er Jahren gelang durch Withfield Diffie und Martin E. Hellmann ein Durchbruch. Sie erfanden das Prinzip des öffentlichen Schlüssels. Eine erste konkrete Umsetzung gelang den drei Wissenschaftlern Ronald Rivest, Adi Shamir und Leonard M. Adleman mit dem nach ihnen benannten RSA–Kryptosystem [RSA78]. Der öffentliche Schlüssel ist hier das Produkt aus zwei Primzahlen, der wie der Name schon sagt, für jede Person offen gelegt wird. Geheim bleiben jedoch die zwei Primzahlen selber. Möchte man dem Kenner der Primzahlen eine geheime Nachricht übermitteln, so tut man dies mit dem öffentlichen Schlüssel. Die Entschlüsselung der Botschaft ist nur mit Kenntnis der zwei Primzahlen möglich. Damit einher geht eine weitere Forderung. Die Primzahlen müssen so groß sein, dass ein Faktorisierungs–Algorithmus eine Zerlegung des öffentlichen Schlüssels in seine Primfaktoren in absehbarer Zeit unmöglich macht. Mit den heute bekannten nichteffizienten Faktorisierungs–Algorithmen und den Rechenleistungen von modernsten Computern ergeben sich für die Gewährleistung der Sicherheit des RSA–Kryptosystems Forderungen an eine Größe der Primzahlen von 1024 Bitstellen (Stand September 2004). [BSI04] Die Tendenz ist mit verbesserten Rechenkapazitäten steigend. Das RSA–Kryptosystem ist nicht das einzige Kryptosystem, das auf die Kenntnis von Primzahlen angewiesen ist. Beispielsweise benötigt das Massey–Omura–Kryptosystem Primzahlen mit 2000 Bitstellen (Stand 2004), um endliche Körper zu konstruieren. Endliche Körper besitzen immer die Mächtigkeit einer Primpotenz [SW90]. Die Sicherheit dieses Systems beruht auf der Unkenntnis eines effizienten Algorithmus für die Berechnung eines diskreten Logarithmus. Die Primzahlen bestimmt man mit Algorithmen, den so genannten Primzahltests, welche bei einer zufällig gewählten ungeraden Zahl erkennen, ob es sich um eine Primzahl handelt. Doch das alleine reicht für praktische Anwendungen nicht aus. Es geht nicht nur um das Bestimmen von Primzahlen, sondern auch um die dafür benötigte Zeit. Inzwischen benutzen auch private 3 Personen Verschlüsselungen zum Beispiel, um elektronische Post vor „fremden Blicken“ zu schützen. Keiner gibt sich mit einer minuten– oder gar stundenlangen Wartezeit zufrieden. Der Informatiker Donald E. Knuth schreibt: „In practice we not only want algorithms, we want algorithms that are good in some loosely defined aesthetic sense.” [KNU02] Das „Sieb des Eratosthenes“ genügt solchen Ansprüchen nicht. In unserer Arbeit untersuchen wir zwei so genannte effiziente Primzahltests auf ihre praktische Einsatzfähigkeit, den Rabin–Miller–Test und den AKS–Test. Beide erfüllen auf den ersten Blick moderne Ansprüche zumindest per Definition. Bei genauerer Untersuchung kommen jedoch starke Unterschiede zum Vorschein. Es geht in unserer Arbeit nicht darum, die schnellstmöglichen Laufzeiten der Tests zu erreichen. Vielmehr soll die Frage beantwortet werden, welcher Algorithmus für praktische Anwendungen besser geeignet ist. Dazu werden die Laufzeiten für verschiedene mögliche Fälle, die beim Abarbeiten der Algorithmen eintreten können, untersucht. Selbstverständlich werden beide Tests effizient programmiert. Die gemessenen Laufzeiten sind abhängig von den Rechenkapazitäten des verwendeten Computers (in unserem Fall ein Intel Pentium 4 Prozessor 2,6 GHz mit 1 GB RAM) und von der Art der Implementierung. Wir benutzten das Computeralgebrasystem MuPAD, um die beiden Algorithmen zu programmieren. Auf dieser Grundlage führen wir eine Reihe von Experimenten durch. 1. Begriffe aus der Komplexitätstheorie Im 9. Jahrhundert lehrte in Bagdad der Begründer des mathematischen Lehrbetriebs des „Hauses der Weisheit“, Muhammad ibn Musa al-Choresmi, das stellenweise Operieren mit einzelnen Ziffern beim Multiplizieren, Quadratwurzelziehen und Dividieren. Aus der lateinisierten Form seines Namens „Algorismus“ entstand der Begriff Algorithmus mit der Bedeutung „Dezimalkalkül für die Grundrechenarten“. Die heutige Bedeutung des Begriffes ist viel weiter gefasst. Als Algorithmus bezeichnet man eine Anleitung, wie eine Aufgabe oder ein Problem in endlichen Schritten zu lösen ist. In unserer Arbeit handelt es sich bei der Anleitung um ein Computerprogramm. Die Aufgabe besteht darin, für eine gegebene Zahl n in Dezimaldarstellung zu entscheiden, ob sie eine Primzahl ist. Intern wird diese Zahl jedoch in eine Binärzahl verwandelt. Demnach sind die Schritte des Algorithmus elementare Bitoperationen, das heißt Berechnungen, wie Additionen oder Multiplikationen, mit einzelnen Bits. Vergleiche werden in aller Regel nicht als elementare Bitoperation gezählt. Als Alphabet bezeichnet man eine endliche Kollektion von Zeichen. Seine Elemente heißen Buchstaben. Unter einem Wort versteht man eine endliche Folge von Buchstaben. In unserer Implementierung ist das Alphabet {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. Ein Wort ist demnach eine natürliche Zahl in Dezimaldarstellung. Für Komplexitätsberechnungen von Algorithmen bestimmt man die maximale Laufzeit, die ein Algorithmus für feste Bitlängen von Worten benötigt. Dieser am meisten zeitraubende Fall, der „worst case“, tritt insbesondere ein, wenn der Algorithmus vollständig in jedem Schritt abgearbeitet wird. Es ergeben sich folgende Definitionen. 1.1. Definition: Laufzeit Sei A ein Algorithmus, ∑ ein Alphabet, ∑ * die Menge aller Wörter über ∑ , n ∈ ∑* ein Wort. Dann ist die Laufzeit T A(n) die Anzahl der elementaren Bitoperationen, welche A benötigt, um ausgehend von n, zum Stillstand zu kommen. 4 1.2. Definition: Laufzeitfunktion Bezeichne lg(n) die Länge der Binärdarstellung des Wortes n. Sei TA: 0 → 0 mit TA(B):= max { T A(n) | y ∈ ∑* , lg (n) ≤ B}. TA(B) ist die größtmögliche Laufzeit, die für den Algorithmus A, bei Eingabe eines Wortes n der Bit-Länge lg(n) kleiner oder gleich B, auftreten kann. Die Länge der Binärdarstellung einer natürlichen Zahl n in Dezimaldarstellung beträgt log2(n). Somit ist in unserem Fall lg(n) = log2(n)=:log(n). Für die Lösung eines Problems existieren häufig verschiedene Algorithmen. Man benötigt für die Bewertung der Schnelligkeit eines Algorithmus ein vernünftiges Kriterium. Hier ein Beispiel. Seien A und C verschiedene Algorithmen für das gleiche Problem mit TA(B):=100B und TB(B):=10B2. Für B = 2 ist offenbar C schneller als A, während für B = 200 A schneller als C ist. Es erweist sich als sinnvoll, den asymptotisch schnellsten Algorithmus zu suchen. 1.3. Definition: asymptotisch schneller Seien A und C Algorithmen. A ist asymptotisch schneller als C, wenn lim B →∞ TA ( B ) TC ( B ) = 0 ist. Im obigen Beispiel ist also A asymptotisch schneller als C. Um eine Klassifizierung von Algorithmen bezüglich ihrer Laufzeit vorzunehmen, wird das Landausche Symbol benutzt. 1.4. Definition: Landausches Symbol Seien f, g : 0 → Abbildungen. Dann ist O(f):= { g | Es gibt ein c∈ und ein B0 ∈ mit g(B) ≤ c f(B) für alle B ≥ B0. } das Landausche Symbol bzw. die Ordnung von f. Ist TA ∈ O(f) und f ein Polynom, dann ist die Laufzeitfunktion TA polynomial beschränkt. Ist 2p(B) ∈ O(TA), wobei p(B) ein Polynom vom Grad m ≥ 1 ist, dann ist die Laufzeitfunktion TA exponentiell wachsend. Für eine polynomial beschränkte Laufzeitfunktion eines Algorithmus schreibt man häufig TA ∈ O(Bm). Der Grund dafür findet sich in folgendem Satz. 1.4. Satz: Sei f ein Polynom vom Grad m, dessen maximaler Koeffizient eine positive reelle Zahl ist. Dann folgt f ∈ O(Bm). Beweis: m Sei f(B):= ∑ ci Bi mit ci ∈ i =0 für 0 ≤ i ≤ m und cm > 0 . Dann existiert ein B0 ∈ mit cmBm ≥ cm-1Bm-1 + …+ c1B + c0 für alle B ≥ B0. Es folgt, dass f(B) ≤ 2 cmBm für alle B ≥ B0 gilt. Also ist f∈ O(Bm). Aus der Definition 1.2. folgt, dass die Bildmenge der Laufzeitfunktion TA nur aus positiven reellen Zahlen bestehen kann. Somit muss für ein Polynom f, das TA nach oben beschränkt, der maximale Koeffizient eine positive reelle Zahl sein. Die Anwendung von Satz 1.4. auf dieses Polynom f ergibt für eine polynomial beschränkte Laufzeitfunktion TA, dass TA ∈O(Bm) ist. 5 Einen Algorithmus mit polynomial beschränkter Laufzeitfunktion bezeichnet man als effizient. Diese Einteilung erscheint sehr theoretisch und es stellt sich die Frage, wann ein effizienter Algorithmus auch „praktisch effizient“ ist. Genau mit diesem Problem beschäftigt sich unsere Arbeit und zwar in Bezug auf zwei Algorithmen, die bei Eingabe einer beliebigen natürlichen Zahl n mit n > 1 entscheiden, ob es sich um eine zusammengesetzte oder eine Primzahl handelt. Der Rabin-Miller Test ist ein effizienter probabilistischer Test. Seine Ergebnisse unterliegen einer gewissen Unsicherheit. Der Algorithmus kann bei unabhängig durchgeführten Versuchen mit der gleichen Eingabezahl n einen unterschiedlichen Verlauf nehmen. Eine präzise Erklärung des Begriffs probabilistisch wird in 2.1. gegeben. Beim AKS–Test handelt es sich um einen deterministischen effizienten Algorithmus. Seine Ergebnisse sind sicher. Der Algorithmus nimmt bei einer festen Eingabezahl immer den gleichen Verlauf. Der Rabin-Miller-Algorithmus ist asymptotisch schneller als der AKSAlgorithmus (siehe 2.3.2. und 3.3.2.). 2. Der Rabin–Miller–Test 1980 entwickelte Michael O. Rabin einen der ersten nichtdeterministischen, dafür aber effizienten Tests für Primzahlen, der auf einigen Ideen von Gary L. Miller von 1975 aufbaute. Dieser Test wird in der Praxis gern benutzt, denn er lässt sich leicht umsetzen und ist relativ schnell [RAB80]. 2.0. Notation Sei n∈ und ( /n ) der Restklassenring über dem Ring der ganzen Zahlen modulo dem Ideal n :={nz | z ∈ }. Die Elemente von /n sind die Nebenklassen 0,…, n-1. (Wir vermeiden hier bewusst eine nähere Kennzeichnung der Nebenklassen beispielsweise durch eckige Klammern, da zu einem späteren Zeitpunkt unserer Arbeit durch erneute Bildung eines Restklassenringes über dem Restklassenring ( /n [T] Verwirrung durch eine Vielzahl von Klammern auftreten würde.) Elemente einer Restklasse nennt man Repräsentanten. Zwei Elemente a, b ∈ heißen kongruent modulo n wenn a ≡ b(mod n ). Das heißt die Repräsentanten a und b liegen in derselben Restklasse, wenn (a–b) ∈ n gilt. Äquivalent dazu ist a = b mit meiner Schreibweise. Das heißt die zwei Restklassen von a und b sind gleich. Bezeichne a mod n die Funktion, die einer ganzen Zahl a nach Division mit n einen Rest zuordnet, der betragsmäßig kleiner als n ist. Dann ist (a–a mod n) ∈ n , wobei a ∈ ist. Daraus folgt, dass die Repräsentanten a und a mod n in der gleichen Restklasse liegen. Also gilt a = a mod n. Ob ich im weiteren Repräsentanten oder ihre Nebenklassen betrachte, ist somit an den Zeichen ≡ und = erkennbar. Mit ( /n ) × bezeichnet man die Menge der invertierbaren Elemente in ( /n ) bezüglich der Multiplikation. Sei a∈ , dann ist die Restklasse des Repräsentanten a genau dann invertierbar in ( /n ), wenn ggT(a,n)=1 ist [SW90]. Ist n eine Primzahl, dann gilt das offensichtlich für alle Elemente von ( /n ) außer dem Nullelement. In diesem Fall ist ( /n ) ein Körper. 6 2.1. Idee Der Rabin Miller Test beruht auf zwei Grundideen. Erstens dem kleinen Satz von Fermat. 2.1.1. Satz (Fermat):[SW90] Sei n eine Primzahl und b ∈ ( /n ) × . Dann folgt bn-1 mod n = 1. Leider gilt die Umkehrung des Satzes nicht und tatsächlich gibt es die zusammengesetzten Carmichael-Zahlen, bei denen bn-1mod n =1 für alle b ∈ ( /n ) × ist. Somit kann diese Bedingung in dieser Form nicht zur Beantwortung der Frage, ob eine gegebene Zahl n eine Primzahl ist, herangezogen werden. Die zweite Idee des Tests beruht auf der Tatsache, dass /n genau dann ein Körper ist, wenn n eine Primzahl ist [SW90]. In einem Polynomring über einem Körper kann ein Polynom zweiten Grades höchstens zwei Nullstellen besitzen [SW90]. Also existieren für f ∈ ( /n [T] mit f = T2-1 höchstens zwei Nullstellen. Diese sind offensichtlich 1 und n-1=-1modn. (Für n=2 hat f nur die doppelte Nullstelle 1 = -1mod 2.) Da n als Primzahl für n > 2 ungerade ist, folgt mit dem kleinen Satz von Fermat ,dass für b ∈ ( /n ) × n −1 0 = (b n −1 − 1) mod n = ((b 2 ) 2 − 1) mod n ist. Somit muss im Körper /n für das Element n −1 n −1 n −1 (b 2 ) mod n ∈ ( /n ) × entweder (b 2 ) mod n = 1 oder (b 2 ) mod n = n − 1 sein. Falls 4 ein Teiler von n-1 und wenn (b n −1 2 ) mod n = 1 ist, können wiederum nur die Fälle (b n −1 4 ) mod n = 1 n −1 4 und (b ) mod n = n − 1 eintreten. Das Prinzip lässt sich für jede Potenz von 2, die n–1 teilt, verallgemeinern. Sei also n-1 = 2r s, wobei r, s ∈ sind und s ungerade ist. Erfüllt ein i mit 1 ≤ i ≤ r die Bedingung (b n −1 2 i +1 n −1 2i ) mod n = 1 , so können für i < r nur die Fälle ( n −1 2 i +1 (b ) mod n = 1 und (b ) mod n = n − 1 ) und für i = r nur die Fälle ( (b s ) mod n = 1 und (b s ) mod n = n − 1 ) eintreten. Ist das nicht gegeben, dann kann n keine Primzahl sein. Es stellt sich nun die Frage, ob es zusammengesetzte Zahlen n gibt, bei denen diese Bedingungen auch für alle b∈ ( /n ) × erfüllt werden. Ist n keine Primzahl, dann handelt es sich bei /n nicht um einen Körper sondern um einen Ring [SW90]. In einem Polynomring über einem Ring kann es mehr als zwei Nullstellen von f geben. Erfüllt also ein i mit 1<=i<= r die Bedingung n −1 n −1 n −1 (b 2i ) mod n = 1 , so kann für ein i < r auch der Fall ( (b 2 i +1 ) mod n ≠ 1 und (b 2i +1 ) mod n ≠ n − 1 ) beziehungsweise für i = r auch der Fall ( (b s ) mod n ≠ 1 und (b s ) mod n ≠ n − 1 ) eintreten. Erfreulicherweise trifft das für mindestens die Hälfte aller Elemente von ( /n ) × zu (siehe 2.2.3.). Für die restlichen Elemente b aus ( /n ) × nennt sich n starke Pseudoprimzahl zur Basis b. Im Gegensatz zum kleinen Satz von Fermat könnte man durch einen Test aller Elemente b aus ( /n ) × zweifelsfrei Primzahlen von zusammengesetzten Zahlen unterscheiden. Das dauert aber leider zu lange. Deshalb geht man folgendermaßen vor. Man wählt zufällig ein b∈{1,…, n-1}. Liegt b nicht in ( /n ) × , dann ist der ggT(b,n) >1. Also ist n zusammengesetzt. Liegt b in ( /n ) × , so untersucht man die „Nullstellen“ für dieses b. Wird n vom Test als Primzahl erkannt, dann besteht die Möglichkeit, dass n eine starke Pseudoprimzahl zur Basis b und damit eine zusammengesetzte Zahl ist. Somit „irrt“ sich der Test beim Erkennen einer Primzahl mit einer Wahrscheinlichkeit, die kleiner als ½ ist. Denn eine Zahl n kann für höchstens die Hälfte aller Elemente b aus ( /n ) × eine starke Pseudoprimzahl sein (siehe 2.2.3.). Demnach entscheidet die zufällige Wahl von b über das Ergebnis des Tests, wenn n eine zusammengesetzte Zahl ist. Daher stammt die Bezeichnung probabilistischer Test. Verringern lässt sich die Irrtumswahrscheinlichkeit für das Erkennen 7 einer zusammengesetzten Zahl als Primzahl auf Wiederholungen des Tests. 1 2k , durch k-malige, unabhängige 2.2. Definitionen und Beweise 2.2.1. Definition: starke Pseudoprimzahl Eine zusammengesetzte, ungerade Zahl n heißt starke Pseudoprimzahl zur Basis b ∈ ( /n ) × , falls für eine ungerade Zahl s und ein r∈ mit n-1 = 2 r s entweder b s mod n = 1 gilt oder wenn es ein i mit 0 ≤ i< r gibt, so dass b 2 s mod n = n-1 gilt. i 2.2.2. Lemma Sei P := { b ∈ ( /n ) × | b n−1 mod n = 1}. Ist n eine starke Pseudoprimzahl zur Basis b, dann liegen alle Basen b aus ( /n ) × in P. Beweis: Sei n eine starke Pseudoprimzahl zur Basis b. Mit 2.2.1. gibt es zwei mögliche Fälle. r Fall 1: Aus b s mod n = 1 folgt b n−1 mod n = (b s ) 2 mod n = 1 . Fall 2: Aus b 2 s mod n = n-1 mit 0 ≤ i< r folgt, dass ( b 2 s )2mod n =1 ist. Dann ist b n−1 mod n = 1. i i 2.2.3. Satz: Sei n zusammengesetzte ungerade Zahl. Dann gilt für höchstens die Hälfte aller b ∈ ( /n ) × , dass n eine starke Pseudoprimzahl zur Basis b ist. Beweis: Fall 1: Es gibt ein b∈ ( /n ) × mit b n−1 mod n ≠ 1. Sei P := { b∈ ( /n ) × | b n−1 mod n = 1}. Wegen Lemma 2.2.2. enthält P alle Basen b, für die n eine starke Pseudoprimzahl ist. Die Menge P ist eine Untergruppe von ( /n ) × . Denn P ist eine Teilmenge von ( /n ) × . Seien a,c ∈P. Dann ist (a ⋅ c −1 ) n −1 mod n = (a n −1 mod n) ⋅ ((c n −1 ) −1 mod n) = (1 mod n) ⋅ (1−1 mod n) = 1 . Daraus folgt, dass a ⋅ c −1 ∈ P ist. Mit dem Untergruppenkriterium ist demnach P eine Untergruppe von ( /n ) × . Da nach Vorraussetzung P ≠ ( /n ) × ist und weil die Ordnung von P ein Teiler der Ordnung von ( /n ) × ist (Satz von Lagrange [SW90]), folgt, dass P höchstens die Hälfte der Elemente von ( /n ) × enthalten kann. Das heißt, für höchstens die Hälfte aller b ∈ ( /n ) × ist n eine starke Pseudoprimzahl zur Basis b. Fall 2: Für alle b ∈ ( /n ) × gilt, dass b n−1 mod n = 1 ist. Eine zusammengesetzte Zahl n, die diese Bedingungen erfüllt, heißt Carmichael–Zahl. Eine Folgerung aus dem Satz von Korselt (1899) besagt, dass solch eine Zahl das Produkt von mindestens drei Primzahlen und das Quadrat einer Primzahl kein Teiler einer CarmichaelZahl ist [B99]. 8 k Somit gilt n = ∏p i ,wobei pi verschiedene Primzahlen sind und k ≥ 3 ist. i =1 Wir unterteilen den Beweis in einige Teilbehauptungen: Behauptung (i): i Sei I:={ i ∈ 0 | 0 ≤ i ≤ r und für alle b ∈ ( /n ) × gilt b 2 s mod n = 1 }. Dann gilt: (a) r ∈Ι. (b) Sei i ∈Ι mit 0 ≤ i< r. Dann folgt i +1 ∈ I. (c) Es existiert ein j ∈ mit 0 ≤ j< r für das j ∉ I ist, aber für das (j+1) ∈ I gilt. Beweis (Behauptung (i)) (a) Klar wegen Voraussetzung. i (b) Sei i ∈ I mit 0 ≤ i <r. Dann ist b 2 s = 1 mod n für alle b ∈ ( /n ) × . i i +1 Somit folgt für alle b ∈ ( /n ) × , dass ( b 2 s )2 mod n = b 2 s = 1 mod n ist. Dann ist i+1 ∈ I. (c) Sei g ∈ und sei g(mod p1) ein primitives Element von ( /p1 ) × . Das heißt die Ordnung von g in ( /p1 ) × ist gerade, denn ord(g) = p1-1. Dann ist p1-1 kein Teiler von s, denn s ist nach Voraussetzung ungerade. Daraus folgt, dass gsmod p1 ≠ 1 ist. Somit existiert wegen des chinesischen Restsatzes ein b∈ mit bsmod n ≠ 1. Daraus folgt, dass 0 ∉ I ist. Das heißt es gibt ein j ∈ mit 0 ≤ j< r für das j ∉ I ist, aber für das (j+1) ∈ I gilt. Behauptung (ii) Wegen Behauptung (i) existiert ein j∈ mit 0 ≤ j< r für das j ∉ I ist, aber für das (j+1) ∈ I gilt. j Setze G:={ b ∈ ( /n ) × | b 2 s = ± 1 mod n}. Dann ist G eine Untergruppe der multiplikativen Gruppe ( /n ) × . Dabei ist G eine echte Teilmenge von ( /n ) × . Beweis (Behauptung (ii)) G ist eine Teilmenge von ( /n ) × . Seien a, c ∈ G. Dann ist j j j (a ⋅ c −1 ) 2 s mod n = (a 2 s mod n) ⋅ (c 2 s mod n) −1 mod n = (±1 mod n) ⋅ (±1 mod n) −1 = ±1 mod n . Denn ( 1 mod n ) und ( − 1 = (n − 1) mod n ) sind in ( /n ) × jeweils zu sich selbst invers. Daraus folgt, dass a ⋅ c −1 ∈ G ist. Mit dem Untergruppenkriterium ist demnach G eine Untergruppe von ( /n ) × . Des Weiteren folgt: j Da j ∉I ist, gibt es ein a ∈ ( /n ) × mit a 2 s mod n ≠ 1. j Dann existiert ein i0 ∈ mit 0 ≤ i0 ≤ k und a 2 s mod pi0 ≠ 1. Mit dem chinesischen Restsatz folgt, dass es ein b ∈ gibt, für das b = a mod pi0 und b= 1 mod pi gilt, wobei i ≠ i0 ist. j j Dann folgt, dass b 2 s =mod pi0 ≠ 1 und b 2 s ≠ -1mod pi gilt. Daraus folgt b 2 s ≠ ± 1(mod n). Das heißt aber (b mod n)∉G und somit ist G eine echte Teilmenge von ( /n ) × . j 9 Behauptung (iii) ( /n ) × \G enthält keine Basis b, für die n starke Pseudoprimzahl ist. Beweis (Behauptung (iii)) j Sei b∈ ( /n ) × \G. Dann ist b 2 s ≠ ± 1(mod n). Weil j+1∈I ist (siehe (i)(c)), j +1 folgt, dass b 2 s =1 mod n gilt. Das heißt n ist keine starke Pseudoprimzahl zur Basis b. Aus (iii) folgt, dass in G alle Basen liegen, für die n starke Pseudoprimzahl ist. Da G eine Untergruppe von ( /n ) × ist und mit (ii) eine echte Teilmenge, folgt mit dem Satz von Lagrange [SW90], dass die Ordnung von G ein echter Teiler der Ordnung von ( /n ) × sein muss. Damit kann G höchstens die Hälfte der Elemente von ( /n ) × enthalten. Weil G alle Basen enthält, für die n eine starke Pseudoprimzahl ist, liegt der Anteil an Basen in ( /n ) × bei höchstens ½. In 2.1. wurde bereits erklärt, dass die zufällige Wahl von b in ( /n ) × darüber entscheidet, ob eine zusammengesetzte Zahl n eine starke Pseudoprimzahl zur Basis b ist. Die Wahrscheinlichkeit, dass deswegen n fälschlicherweise als Primzahl erkannt wird, liegt mit 2.2.3. bei höchstens ½. Da b nicht zufällig aus ( /n ) × sondern aus {1,…, n-1}gewählt wird (siehe 2.1. und 2.3.1.), liegt die Irrtumswahrscheinlichkeit für das Erkennen einer zusammengesetzten Zahl als Primzahl sogar unter ½, denn die Ordnung von ( /n ) × ist kleiner als n-1, wenn n zusammengesetzt ist (siehe Eulersche Funktion [SW90]). Die Irrtumswahrscheinlichkeit ist sogar nur kleiner oder gleich ( 14 ) k , wenn k die Anzahl der Durchläufe des Rabin-Miller-Algorithmus bezeichnet. Michel O. Rabin zeigte in einem Ergebnis von 1980, dass höchstens ein Viertel aller Elemente von ( /n ) × Basen für n als starke Pseudoprimzahl sein können. [RAB80] 2.3. Der Algorithmus und seine Komplexität 2.3.1. Der Algorithmus Sei n ∈ ungerade. Wähle zufällig b ∈ mit 0 <b< n. 1.) Ist ggT(b,n) ≠ 1, dann ist n zusammengesetzt. Ist ggT(b,n) = 1, berechne r, s ∈ , so dass n-1 = 2rs gilt, wobei s eine ungerade Zahl ist. 2.) Berechne die Folge r (x0, …,xr) :=( b s mod n, b 2 s mod n ,…, b 2 s mod n = b n −1 mod n ). Gilt (x0, …,xr) = (#,…,#), (x0, …,xr) = (#,..,#,1,…,1) oder (x0, …,xr) = (#,…,#,-1) mit # ≠ ± 1 mod n , dann ist n zusammengesetzt. Gilt (x0, …,xr) = (1,…,1) oder (x0, …,xr) = (#,…,#,-1,1,…,1), dann ist n entweder prim oder n ist zusammengesetzt und die Wahrscheinlichkeit eine solche Zahl b zu wählen, war höchstens ½. 2.3.2. Die Komplexität Die Komplexität eines Algorithmus` hängt erheblich von der Umsetzung der einzelnen Schritte ab. Deshalb gebe ich kurz einen Überblick der Grundideen. Die Komplexitäten berechne ich nicht im Einzelnen, sondern zitiere sie. 10 Sei ∑ :={0,1,2,3,4,5,6,7,8,9} das Alphabet und n∈ ∑* ein Wort, das aus dem Alphabet gebildet wurde. Weiterhin bezeichne B die Länge der Binärdarstellung von n. Mit den Begriffen aus 1. ergeben sich folgende Komplexitäten. Schritt 1.) von 2.3.1. Der größte gemeinsame Teiler zweier natürlicher Zahlen wird mit dem Euklidischen Algorithmus berechnet. Bezeichne TEuklid die Laufzeitfunktion des Euklidischen Algorithmus. Dann ist TEuklid ∈ O(B2). [KNU02] Für das Faktorisieren von n-1 in eine Potenz von 2 und eine ungerade Zahl finden r Divisionen mit je einer Laufzeitfunktion O(B2) statt [KNU02]. Wegen n-1= 2rs folgt, dass r<log n ist. Bezeichne TFaktor die Laufzeitfunktion dieses Algorithmus. Dann ist TFaktor ∈ O(B3). Schritt 2.) von 2.3.1. r Das erste Folgenglied der Folge (x0, …, xr):=( b s mod n, b 2 s mod n ,…, b 2 s mod n = b n −1 mod n ) wird mit der Methode des wiederholten Quadrierens berechnet. Die Idee beruht auf der Darstellung von s als s = k020+…+km2m mit k0,…, km ∈ {0,1} und km=1. Weil 0 1 m 0 1 m (b mod n) s = b s mod n = b ( k0 ⋅2 + k1 ⋅2 +...+ k m ⋅2 ) mod n = ((b 2 ) k0 mod n) ⋅ ((b 2 ) k1 mod n) ⋅ ... ⋅ ((b 2 ) k m mod n) gilt, wird statt s-maliger Multiplikation von ( b mod n ) mit sich selber eine m-malige Multiplikation der jeweiligen Quadrate vorgenommen. Da log s < m ≤ log s + 1 ist, entsteht ein wesentlich geringerer Aufwand. Bezeichne TQuad die Laufzeitfunktion des Algorithmus vom wiederholten Quadrieren, dann ist TQuad ∈ O(B3). [HMU] Des Weiteren müssen noch die restlichen r Folgenglieder durch Quadrieren berechnet werden. Da r < log n ist (siehe Schritt 1), folgt, dass die Laufzeitfunktion für das r-malige Quadrieren ein Element von O(B3) ist. Insgesamt ergibt sich für die Laufzeitfunktion des Rabin-Miller-Algorithmus TRabin ∈ O(B3). Mit der Definition von 1. ist der Rabin–Miller–Test ein effizienter Algorithmus. 2.3.3. Bemerkungen In unserer Implementierung wird der Rabin–Miller–Test 20 mal durchgeführt. Damit beträgt die Irrtumswahrscheinlichkeit beim Erkennen einer zusammengesetzten Zahl als Primzahl höchstens (½ )20 (siehe 2.1.). 3. Der AKS–Test Im August 2002 überraschten drei indische Informatiker mit dem ersten deterministischen, effizienten Primzahltest. M. Agrawal, der Professor, der diesen Traum nie aus seinen Augen verlor, entwickelte mit Studenten schrittweise wichtige Details. N. Kayal und N. Saxena leisteten in ihrer Bachelorarbeit im April 2002 mit dem Titel „ Towards a deterministic polynomial-time primality test“ einen entscheidenden Beitrag. Inzwischen haben einige Wissenschaftler Verbesserungsvorschläge innerhalb des Algorithmus beziehungsweise der Beweise eingebracht. Wir benutzen deshalb in unserer Arbeit die augenblicklich neueste Version (Stand August 2004). [AKS04] 3.0. Notation Sei R:=(( /n )[T])/(Tr-1). Dann ist R der Restklassenring über dem Polynomring ( /n )[T] modulo dem Ideal (Tr-1):={q(Tr-1) | q ∈ ( /n )[T] }, wobei Tr-1 ∈ ( /n )[T] gilt. Die 11 Elemente von R sind dann die Nebenklassen [p] = p +(Tr-1) mit p ∈ ( /n )[T], wobei der Grad von p kleiner als r ist. Liegen zwei Elemente p1, p2 ∈ ( /n )[T] in der gleichen Nebenklasse, so ist p1 ≡ p2 mod (Tr-1). Also liegen die zwei Repräsentanten p1 und p2 in der gleichen Restklasse. Äquivalent dazu ist [p1] = [p2]. Das bedeutet die Nebenklassen von p1 und p2 sind gleich [SW90]. Bezeichne (p mod Tr-1) die Funktion, die einem Polynom p aus ( /n )[T] nach Division mit Tr-1 einen polynomialen Rest zuordnet, dessen maximaler Grad kleiner als r ist. Dann ist (p– p mod Tr-1) ∈ (Tr-1). Daraus folgt, dass die Repräsentanten p und (p mod Tr-1) in der gleichen Restklasse liegen. Also gilt p ≡ p mod (Tr-1) beziehungsweise [p] = [p mod Tr-1]. Insgesamt folgt, es gibt ein f ∈ [T], so dass [p]=[(f mod n) mod Tr-1)] =:[f mod (Tr-1, n)] ist. 3.1. Idee Eine entscheidende Idee des Algorithmus findet sich in der binomischen Formel für kommutative Ringe der Charakteristik p, wobei p eine Primzahl ist. 3.1.1. Satz: binomische Formel für endliche Ringe der Charakteristik p [SW90]. Sei p eine Primzahl und R ein kommutativer Ring der Charakteristik p. Dann gilt: k k k (c + d ) p = c p + d p für alle c, d ∈ R und alle k ∈ . Angewandt auf den Restklassenring R wie in 3.0. definiert, ergibt das Folgendes: Seien T, b= bT0 Elemente von ( /n )[T]. Dann sind [T] und [b] Nebenklassen von R und n ist die Charakteristik von R. Außerdem handelt es sich bei R um einen kommutativen Ring. Ist n eine Primzahl, dann sind die Vorraussetzungen von 3.1.1. erfüllt und es gilt: [T ]n + [b]n = ([T ] + [b]) n für alle k ∈ . k k k Insbesondere gilt die Gleichheit für k=1, also [T ]n + [b]n = ([T ] + [b]) n . Oder anders ausgedrückt: (T + b) n ≡ (T n + b n ) mod(T r − 1) . Sei nun b invertierbar in ( /n )[T], also b ∈ ( /n ) × . Dann folgt mit 2.1.1.: (T + b) n ≡ (T n + b ) mod(T r − 1) . Ist a ∈ ein Repräsentant von b und damit ggT(a,n) = 1 (siehe 2.0.), dann ist dazu äquivalent (siehe 3.0.): [T + a] n = [T n + a mod(T r − 1, n)] . Ist diese Bedingung für ein b ∈ ( /n ) × nicht erfüllt, dann ist n keine Primzahl. 12 Was ist aber mit der Umkehrung des Satzes? Die drei fanden eine Antwort und zwar für ein spezielles r<n (siehe 3.2.1.) und für b’s in gewissen Schranken (siehe 3.2.). Wird die Bedingung (T + b) n ≡ (T n + b ) mod(T r − 1) für alle b ∈ ( /n ) × in speziellen Schranken erfüllt, dann zeigten sie, dass n eine Primpotenz sein muss. Daraus ergibt sich folgender Algorithmus. Zuerst testet der Algorithmus, ob die eingegebene Zahl n eine Primpotenz ist. Kann die Antwort verneint werden, sucht er ein spezielles r. Welche Eigenschaften dieses r besitzt und dass es existiert, wird noch gezeigt. Jetzt können zwei verschiedene Fälle eintreten. Entweder ist r >= n oder r < n. In beiden Fällen testet man, ob ggT(a,n) = 1 oder ggT(a,n) >= n für alle a <= r mit a ∈ ist. Das bedeutet (siehe 2.0), dass die Nebenklasse von a in ( /n ) invertierbar ist. Ist diese Bedingung erfüllt, dann gibt es für r >= n keinen Teiler von n und damit ist n eine Primzahl. Ansonsten ist für diesen Fall n zusammengesetzt. Im Gegensatz dazu besteht für r < n die Möglichkeit, dass natürliche Zahlen a mit r < a < n existieren, für die ggT(a,n) >1 ist. An dieser Stelle kommt die Hauptidee, die wir oben erläutert haben, zum Tragen. Wird die Bedingung [T + b] n = [T n + b mod(T r − 1, n)] für alle b’s in gewissen Schranken erfüllt, dann ist n eine Primpotenz. Da Primpotenzen für Exponenten mit k >= 2 mit effizienten Algorithmen bestimmt werden können [KN02], testet man diese Eigenschaft im ersten Schritt des AKS-Algorithmus. Genauer gesagt, überprüft man, ob die Zahl n eine Potenz einer natürlichen Zahl ist und beantwortet so auch die Frage, ob n eine Primpotenz ist (siehe 3.3.1. und 3.3.2.). Ist n keine Primpotenz und wird [T + b] n = [T n + b mod(T r − 1, n)] für alle b in gewissen Schranken erfüllt, so muss die Zahl n demnach eine Primzahl sein. 3.2. Definitionen und Beweise 3.2.1. Satz Sei n ∈ mit n>1. Dann existiert ein r ∈ mit r ≤ ⎡16 log 5 n ⎤ , so dass für alle k ∈ mit k ≤ 4 log 2 n gilt: n k ≠ 1 mod r. Beweis: Seien r1, r2,…, rt alle natürlichen Zahlen ri ≤ ⎡16 log 5 n ⎤ für die es ein ki ∈ mit ki ≤ 4 log 2 n gibt, so dass n ki mod ri = 1 gilt. Dabei sei ki jeweils die kleinste natürliche Zahl, die dieser Bedingung genügt. Dann folgt ri | (n ki − 1) . ⎣4 log2 n ⎦ Sei P := ∏ (n l − 1) . l =1 Daraus folgt ri | P . Dann folgt kgV (r1 ,..., rt ) | P . ⎣4 log2 n ⎦ Sei Q := ∏ (nl ) . Dann ist P ≤ Q . l =1 ⎣4 log2 n ⎦ 2 2 Für den höchsten Grad m des Polynoms Q gilt: m = ∑ l = ⎣4 log ⎦⋅( ⎣42log n ⎦−1) . l =1 Weil n∈ mit n>1 ist, muss ⎣4 log 2 n ⎦ > 1 und damit ⎣4 log 2 n ⎦ − 1 > 0 sein. 13 Somit folgt, dass − ⎣4 log 2 n ⎦( ⎣4 log 2 n ⎦ − 1) < 0 ist. Daraus ergibt sich − ( ⎣4 log 2 n ⎦) 2 + 4 log 2 n < 0 . Dann folgt, dass ⎣4 log 2 n ⎦ + 4 log 2 n < 2 ⋅ ⎣4 log 2 n ⎦ ist. 2 2 Damit gilt für den höchsten Grad m des Polynoms P: m < ⎣4 log 2 n ⎦ ≤ 16 log 4 n . 5 4 4 5 Insgesamt folgt, dass kgV (r ,..., r ) ≤ P < n16 log n ≤ (2 log n )16 log n = 216 log n ≤ 2 ⎡16 log n ⎤ ist. 2 1 t Sei kgV (1,..., m) das kleinste gemeinsame Vielfache der ersten m natürlichen Zahlen. Ein Ergebnis von M.Nair [NAI82] besagt, dass mit m ≥ 7 das kgV (1,..., m) größer oder gleich 5 2m ist. Für m := 16 log 5 n ist demnach 2 ⎡16 log n ⎤ ≤ kgV (1,..., 16 log 5 n ). ⎡ ⎤ ⎡ ⎤ Daraus folgt kgV (r1 ,..., rt ) < kgV (1,..., ⎡16 log 5 n ⎤ ) . Das heißt es existiert eine natürliche Zahl r ≤ ⎡16 log 5 n ⎤ , für die n k ≠ 1 mod r für alle k ≤ 4 log 2 n ist. 3.2.2. Folgerung Seien n und r wie in 3.2.1. i) Ist ggT (n, r ) ≠ 1 , dann gilt n k ≠ 1 mod r für alle k ∈ . ii) Ist ggT(n,r)=1, dann gibt es k > 4 log 2 n mit n k = 1 mod r . Die folgende Definition spielt für den Beweis des kommenden Hauptsatzes eine tragende Rolle. 3.2.3. Definition: introspektiv Seien f ∈ [T], m∈ und p eine Primzahl. Die Zahl m ist introspektiv zu f, wenn [ f (T )]m = [ f (T m )](mod T r − 1, p ) gilt. 3.2.4. Lemma: [AKS04] Sind m und m ′ introspektiv zu f, dann ist auch m ⋅ m′ introspektiv zu f. 3.2.5. Lemma: [AKS04] Ist m introspektiv zu f und g , dann ist m auch introspektiv zu f ⋅ g . 3.2.6. Folgerung Sei p ein Primteiler von n, p > r und l := 2 ϕ (r ) log(n) . ⎣ ⎦ l Seien I := {n i p j | i, j ≥ 0} und P := { f := ∏ (T + a ) ea | ea ≥ 0, 1 ≤ a ≤ l} . a =1 Sei [T + a ] n = [T ] n + a mod(T r − 1, n) für alle 1 ≤ a ≤ l . Ist m ∈ I , so ist m introspektiv zu jedem f ∈ P . Beweis: Nach Voraussetzung ist [T + a ] n = [T ] n + a mod(T r − 1, n) für alle 1 ≤ a ≤ l . Daraus folgt [T + a] n = [T ] n + a mod(T r − 1, p) , denn p teilt n. Wegen 3.1.1. gilt außerdem [T + a] p = [T p + a mod(T r − 1, p )] . Dann sind p und n introspektiv zu (T+a) (siehe 3.2.3.). Also ist m introspektiv zu (T+a) für alle m ∈ I (siehe 3.2.4.). 14 Daraus folgt, dass m introspektiv zu jedem f ∈ P ist (siehe 3.2.5.). Für folgende wichtige Lemmata ist es notwendig, noch einige Bemerkungen zu speziellen Begriffen zu geben. Sei Qr das r-te Kreisteilungspolynom über Fp:= ( /p ) [LN86]. Dann ist T r − 1 = ∏ Qd . d |r r Daraus folgt, dass Qr das Polynom T -1 teilt. Außerdem zerfällt Qr in irreduzible Faktoren vom Grad k mit pkmod r = 1, wobei k minimal ist. Sei h solch ein irreduzibler Faktor. Dann ist F := ( Fp [T ] /( h(T )) ein Körper und [T] eine primitive r-te Einheitswurzel in F, denn h(T) teilt Tr-1. 3.2.7. Lemma: [LEN02] Seien n und r wie in 3.2.1.. Sei p ein Primteiler von n mit p > r und ggT(i, n) = 1 für alle i∈ Seien G:={ (nipj)mod r | i, j∈ 0 } mit |G|=:t und l Γ:={[ f ] = [∏ (T + a ) ea mit 1 < i ≤ r . mod(h(T ), p)] |(ea ≥ 0) für alle 1 ≤ a ≤ l und [ f ] ∈ F × }. a =1 ⎛t + l − 2⎞ ⎟⎟ . Dann ist | Γ |≥ ⎜⎜ ⎝t −1 ⎠ Beweis: Nach Voraussetzung ist ggT(n,r) = ggT(p,r) = 1, denn es gilt p > r und p ist eine Primzahl. Wegen Folgerung 3.2.2.(ii) gibt es ein k > 4 log 2 n mit n k = 1 mod r . Dann ist G eine Untergruppe der multiplikativen Gruppe ( /r ) × . Die Menge Γ ist Untergruppe der multiplikativen Gruppe F × . Denn Γ ist eine Teilmenge von F × . Des Weiteren ist das Einselement in Γ enthalten. Seien k der maximale Grad von h, ea > 0 und (T + a) ea mod(h(T ), p) ∈ F × . Dann ist (T + a) k −ea mod(h(T ), p) ∈ F × sein inverses Element. Somit sind beide Elemente in Γ enthalten, woraus folgt, dass jedes Element in Γ invertierbar ist. Sei P wie in 3.2.6. und seien f , g ∈ P mit f ≠ g und grad ( f ), grad ( g ) < t . Dann sind [ f ], [ g ] ∈ F . Denn angenommen es gilt [ f ] = [ g ] in F. Dann ist [ f (T )]m = [ g (T )]m mit m ∈ I . Mit Folgerung 3.2.6.und weil h(T) das Polynom Tr-1 teilt, folgt dass [ f (T m )] = [ g (T m )] in F ist. Daraus folgt, dass [ T m ] für alle m ∈ I eine Wurzel von [Q] := [ f ] − [ g ] ist. Weil G eine Untergruppe von ( /r ) × ist (siehe oben), folgt, dass ggT (m, r ) = 1 für alle m ∈ I ist. Das heißt alle [ T m ] sind primitive r-te Einheitswurzeln, denn [T] ist primitive r-te Einheitswurzel (siehe (i)). Somit folgt für alle i ∈ G , dass [T i ] eine primitive r-te Einheitswurzel ist. Nun gilt nach Voraussetzung |G|=t. Deswegen existieren t verschiedene Wurzeln für [Q]. Weil nach Definition aber grad([Q]) < t und [Q] ein Element vom Körper F ist, ergibt das einen Widerspruch. Das heißt die Annahme war falsch und es folgt [ f ] ≠ [ g ] in F. Wegen l = 2 ϕ (r ) log(n) < 2 r log(n) < r < p müssen alle [T + a] ∈ Γ verschieden voneinander sind. Somit gibt es mindestens (l-1) verschiedene Polynome vom Grad 1 in Γ, denn höchstens ein Polynom [T+a] kann gleich h sein und ist somit kein Element von Γ. ⎣ ⎦ 15 Alle Polynome vom Grad t-1 in Γ ergeben sich dann aus den Kombinationen der l-1 ⎛t + l − 2⎞ ⎟⎟ verschiedenen Polynome ersten Grades in Γ. Daraus folgt, es gibt mindestens ⎜⎜ ⎝t −1 ⎠ verschiedene Polynome vom Grad t-1 in Γ. Wegen obigem Widerspruchsbeweis gibt es in ⎛t + l − 2⎞ ⎟⎟ unterschiedliche Polynome, die einen Höchstgrad, der kleiner als t Γ mindestens ⎜⎜ ⎝t −1 ⎠ ist, besitzen. 3.2.8. Lemma: [AKS04] Es gelten die Voraussetzungen von 3.2.7. Sei p ein Primteiler von n. Ist n keine Potenz von p, dann ist | Γ |< 12 n 2 t . Beweis: Setze Iˆ := {n i p j | 0 ≤ i, j ≤ t } . Damit ist Iˆ ⊆ I . Es folgt, dass | Iˆ |= ( t + 1) 2 > t ist. Sei Gˆ :={ (n i p j ) mod r | 0 ≤ i, j ≤ t }. Da Gˆ ⊆ G und | G |= t (siehe (i)) ist, existieren ⎣ ⎦ ⎣ ⎦ ⎣ ⎦ m1 , m2 ∈ Iˆ mit m1 > m2 aber ( m1 mod r ) = (m2 mod r ) in Ĝ . Daraus folgt [T m1 ] = [T m2 (mod T r − 1, p )] . Sei f ∈ P . Dann gilt [ f (T )]m1 = [ f (T m1 )(mod T r − 1, p )] = [ f (T m2 )(modT r −1)] = [ f (T )]m2 (wegen 3.2.6.). Somit ist jedes [ f ] ∈ Γ eine Wurzel von [Qˆ ] := [T m1 − T m2 ] mit [Qˆ ] ∈ F . Dann existieren mindestens | Γ | verschiedene Wurzeln von Qˆ in F [KSS02]. Nun ist Grad (Q) = m1 ≤ (np) ⎣ t ⎦ < 12 n 2 t , denn es gilt p|n und p < n nach Voraussetzung. Daraus folgt, dass | Γ |< 12 n 2 t gilt. 3.2.9. Hauptsatz Seien n, r ∈ , r < n, r ≤ ⎡16 log 5 n ⎤ und sei ggT(i, n) = 1 für alle i ∈ mit 1 < i ≤ r . Sei p ein Primteiler von n. Für T, a=aT0 ∈ [T] mit 1 ≤ a ≤ l := 2 φ (r ) log n sei weiterhin ⎣ ⎦ [T + a] = [T + a mod(T − 1, n)] . Dann ist n = pm mit m ∈ 0. n n r Beweis: Vorbemerkung: Nach Voraussetzung ist ggT(n,r) = ggT(p,r) = 1. Denn es ist p > r und p ist eine Primzahl. Wegen Folgerung 3.2.2. (ii) gibt es ein k > 4 log 2 n mit n k = 1 mod r , wobei k minimal ist. Da nach dem Satz von Lagrange [SW90] die Ordnung von n in G, also k, ein Teiler von |G| ist, folgt, dass | G |= t ≥ 4 log 2 n ist. Wegen t = t ⋅ t > t ⋅ 2 log n ist dann | G |> 2 t log n . 16 Insgesamt ergibt sich: ⎛t + l − 2⎞ ⎟⎟ | Γ |≥ ⎜⎜ ⎝t −1 ⎠ ⎣ (wegen 3.2.7.) ⎦ ⎛ l − 1 + 2 t log(n) ⎞ ⎟ (wegen der Vorbemerkung) ≥⎜ ⎜ 2 t log(n) ⎟ ⎝ ⎠ ⎛ 2 ⋅ 2 t log(n) − 1⎞ ⎟ (Das folgt wegen der Definition von l und weil G eine ≥⎜ ⎜ 2 t log(n) ⎟ ⎝ ⎠ Untergruppe von ( /r ) × ist und damit t ≤ ϕ (r ) gilt.) ⎣ ⎣ ≥ 2 ⎣2 ⎦ ⎣ t log( n ) ⎦ ⎦ ⎦ (für 2 t log(n) ≥ 3 ) ≥ 12 n 2 t . Daraus folgt mit der Kontraposition von 3.2.8., dass n ist eine Primpotenz von p ist. 3.3. Der Algorithmus und seine Komplexität 3.3.1. Der Algorithmus Sei n∈ eine Zahl mit n > 1. 1.) Ist n = mb mit m, b∈ , dann ist n zusammengesetzt. 2.) Ist n keine Potenz, dann suche ein r ∈ , für das n k ≠ 1(mod r ) für alle k ≤ 4 log 2 (n) ist. 3.) Ist 1<ggT(i,n)<n für ein i ≤ r , dann ist n zusammengesetzt. 4.) Ist n ≤ r , dann folgt: Ist ( ggT (i, n) = 1 für alle i < n ) oder ist ( ggT (i, n) ≥ n für alle r ≥ i ≥ n ), dann ist n eine Primzahl. 5.) Ist n > r und ist ( ggT (i, n) = 1 für alle i ≤ r ), dann teste für a=1 bis 2 ϕ (r ) log(n) : ⎣ ⎦ Gibt es ein a mit [T + a ] ≠ [T + a(mod T − 1, n)] , dann ist n zusammengesetzt. Gibt es kein a mit [T + a ] n ≠ [T n + a(mod T r − 1, n)] , dann ist n eine Primzahl. n n r 3.3.2. Die Komplexität Auch hier gebe ich wie in 2.3.2. einen Überblick der Grundideen einzelner Schritte. Die Komplexitäten berechne ich nicht im Einzelnen, sondern zitiere sie. Sei ∑ :={0,1,2,3,4,5,6,7,8,9} das Alphabet und n∈ ∑* ein Wort, das aus dem Alphabet gebildet wurde. Weiterhin bezeichne B die Länge der Binärdarstellung von n. Mit den Begriffen aus 1. ergeben sich folgende Komplexitäten. Schritt 1.) von 3.3.1. Wenn n eine Potenz ist, dann ist die kleinstmögliche Basis m = 2 Somit gilt für den Exponenten b ≤ log n . Der Algorithmus sucht für einen festen Exponenten b ab der Zahl b = 2 eine mögliche Basis m nach folgendem Prinzip. Seien a: = 1 und c: = n und m = (a+c) div 2. Dann wird m2 berechnet. Ist m2 = n, dann ist n eine Potenz. Ist m2 < n, dann setzt man a:= m beziehungsweise ist m2 > n, dann setzt man c:=m und überprüft wieder, ob das neue 17 m2 gleich n, ob es kleiner als n oder größer als n ist. Das kann man solange fortsetzen bis c–a < 2 ist. Man setzt also durch Intervallhalbierungen der jeweiligen Intervalle [a, c] die Anzahl der in Frage kommenden Basen immer mehr herab. Ergibt sich für den Exponenten b =2 keine Basis, dann wird das gleiche Prinzip für b = {3 ,…, log n } fortgeführt. Gibt es für keinen dieser Exponenten b eine Basis, so ist n keine Potenz. Die Laufzeitfunktion des Algorithmus für Schritt 1 ist TPotenz ∈ O(B2logB) [D04]. Schritt 2.) von 3.3.1. Für alle natürlichen Zahlen ab r=2, wird getestet, ob n k ≠ 1(mod r ) für alle k ≤ 4 log 2 (n) ist. Satz 3.2.1. zeigt die Existenz von einem r ≤ ⎡16 log 5 n ⎤ . Daraus ergibt sich für die Laufzeitfunktion des Algorithmus TTestr ∈ O(B7) [D04]. Schritt 3.) von 3.3.1. Mit dem Euklidischen Algorithmus wird r mal der größte gemeinsame Teiler bestimmt. Daraus ergibt sich für die Laufzeitfunktion des Algorithmus TrEuklid ∈ O(B5B2)=O(B7) [KNU02]. Schritt 5.) von 3.3.1. Zur Umsetzung dieses Schrittes gibt es verschiedene Möglichkeiten. Wir wählten die Methode des wiederholten Quadrierens. Ihr Prinzip haben wir bereits in 2.3.2. beschrieben. Berücksichtigt man die Ausführung der Operation für 1 ≤ a ≤ l := 2 φ (r ) log n (siehe ⎣ ⎦ 3.2.9.), dann ist die Laufzeitfunktion TPolynom ∈ O(B ) für ein ε > 0 [AKS04]. Schritt 5 dominiert alle anderen Schritte. Die Laufzeitfunktion des AKS-Algorithmus ist TAKS ∈ O(B10.5+ε) . Das heißt der AKS-Algorithmus ist ein effizienter Algorithmus. 10.5+ε 3.3.3. Bemerkung In unserer Implementierung haben wir Schritt 2.) erst ab einer natürlichen Zahl r mit r > 4 log 2 (n) durchgeführt. Die Laufzeiten von Schritt 2 werden damit geringer. Eine Rechtfertigung der Existenz eines solchen r, geben wir durch folgendes Lemma. 3.3.3.1. Lemma Sei n ∈ . Dann existiert ein r ∈ mit 4 log 2 n < r ≤ ⎡16 log 5 n ⎤ , so dass für alle k ≤ 4 log 2 n mit k ∈ gilt: n k ≠ 1 mod r. Beweis: Wegen Satz 3.2.1. existiert ein r ≤ ⎡16 log 5 n ⎤ mit n k ≠ 1 mod r für alle k ≤ 4 log 2 n mit k∈ . Fall 1: Sei n eine Primzahl und n > 4 log 2 (n) . Ist r ein Vielfaches von n, dann gilt r > 4 log 2 (n) . Ist r kein Vielfaches von n, dann gibt es ein minimales k0 ∈ , so dass n k0 = 1 mod r und k 0 > 4 log 2 (n) ist (3.2.2). Somit bezeichnet k0 die Ordnung von n in ( /r ) × . Angenommen, es gibt ein r ≤ 4 log 2 (n) . Dann ist k die Ordnung von n in ( /r ) × . 0 Mit dem Satz von Lagrange folgt, dass k ein Teiler der Gruppenordnung von ( /r ) × ist [SW90]. Mit der Eulerschen Funktion ϕ gilt | ( /r ) × |= ϕ (r ) < r , und 18 daraus folgt, dass k 0 ≤ r ≤ 4 log 2 n ist. Widerspruch ! Somit gilt r > 4 log 2 (n) . Fall 2: Sei n eine Primzahl und n ≤ 4 log 2 (n) . Dann ist n das kleinste r mit n k ≠ 1 mod r für alle k ≤ 4 log 2 n , denn es gilt n k = 0 mod n für alle k ∈ . Setze r := n ⋅ ⎡4 log 2 n ⎤ . Dann ist n ein echter Teiler von r. Somit gilt n k mod r ≠ 1 für alle k ∈ . Da für alle n>1 4 log 2 n < r ≤ ⎡16 log 4 n ⎤ ≤ ⎡16 log 5 n ⎤ ist, existiert somit ein r > 4 log 2 (n) , so dass für alle k ≤ 4 log 2 n mit k ∈ gilt: n k ≠ 1 mod r. Fall 3: Sei n eine zusammengesetzte Zahl. Sei r0 ∈ die kleinste natürliche Zahl für die n k ≠ 1 mod r0 für alle k ≤ 4 log 2 n mit k ∈ gilt. Behauptung: Ist ro ≤ 4 log 2 (n) , dann ist der ggT(n, r0)>1. Beweis: Angenommen ggT(n, r0)=1. Dann existiert ein minimales k0 ∈ , so dass n k0 mod r0 = 1 und k 0 > 4 log 2 (n) ist. Mit dem Satz von Lagrange folgt, dass k0 ein Teiler der Gruppenordnung von ( /r0 ) × ist [SW90]. Da mit der Eulerschen Funktion ϕ folgt, dass | ( /r ) × |= ϕ (r ) < r ist, gilt k ≤ r ≤ 4 log 2 n . Widerspruch ! 0 0 0 Also ist ggT(n, r0) > 1. Aus ggT(n, r0) > 1 folgt, dass n k mod r0 ≠ 1 für alle k ∈ ist (3.2.2.). Setze r := r0 ⎡4 log 2 n ⎤ . Dann ist r0 ein echter Teiler von r. Daraus folgt, dass ggT(n, r) > 1 ist. Somit gilt n k mod r ≠ 1 für alle k ∈ . Da für alle n < 1 folgt, dass 4 log 2 n < r ≤ ⎡16 log 4 n ⎤ ≤ ⎡16 log 5 n ⎤ ist, existiert somit ein r > 4 log 2 (n) , so dass für alle k ≤ 4 log 2 n mit k ∈ gilt: n k ≠ 1 mod r. Aus den Fallunterscheidungen folgt die Behauptung. Für unsere Implementierung ergeben sich folgende praktische Auswirkungen. Für eine Zahl n wird nicht in jedem Fall der kleinstmögliche Wert von r ermittelt (siehe Beweis Fall 2 und Fall 3). Dadurch kann es vorkommen, dass in unserer Implementierung ein zu n bestimmtes r größer als n ist, während es in der Implementierung, die r ab einem Wert von 2 sucht, kleiner als n sein kann. In unserer Implementierung wird daher diese zusammengesetzte Zahl in Schritt 3 oder eine Primzahl in Schritt 4 erkannt, während sie sonst den Schritt 5 durchlaufen müsste. Wie man später noch sehen wird (4.3.1., 4.3.2) ist die Laufzeit für unsere Implementierung in diesen Fällen schneller. Ein weiterer Vorteil ist, dass im Fall einer Primzahl n mit n > 4 log 2 n der Schritt 2 schneller wird, denn r existiert erst für r > 4 log 2 n (siehe Beweis Fall 1) und die unnötigen Fälle des Tests werden nicht durchgeführt. Ein Nachteil entsteht durch eine Verlängerung der Laufzeit von Schritt 2 für einige Zahlen. Dort wird nicht das kleinstmögliche r bestimmt. Das betrifft zum einen zusammengesetzte Zahlen mit kleinen Teilern. Durch ein größeres r wird dann aber in Schritt 3 des Algorithmus dieses kleinste r0 als größter gemeinsamer Teiler erkannt und demnach endet der Algorithmus auch in Schritt 3. Zum anderen ergibt sich ein Nachteil für kleine Primzahlen. Ist n ≤ 4 log 2 n so folgt daraus n < r (siehe Beweis Fall 2). Somit werden diese Primzahlen in Schritt 4 erkannt, was sich auch als ein Vorteil erweisen wird. Unserer 19 Meinung nach würde es sich für die Schnelligkeit des Algorithmus als günstig erweisen, wenn man die Existenz eines r in einem möglichst kleinen Intervall zeigen könnte. Das heißt, nicht nur die Abschätzung nach oben von r mit r ≤ ⎡16 log 5 n ⎤ ist wichtig für die Laufzeit, sondern auch eine Abschätzung nach unten. Die kleinste ungerade Zahl, für die n > r gilt, ist in unserer Implementierung die zusammengesetzte Zahl n = 28+11 mit r = 28+2. Die kleinste ungerade Zahl, für die n > r gilt, ist in der ursprünglichen Fassung n = 9 mit r =3. In unserer Implementierung beträgt für n= 9 der Wert r=42. 4. Experimente – Untersuchung der durchschnittlichen Laufzeit bei verschiedenen Bitstellenzahlen 4.1. Ansatz Beide Algorithmen sind effizient (siehe 2.3.2.und 3.3.2.). Der Rabin–Miller–Test ist offensichtlich asymptotisch schneller als der AKS–Test. Wie groß der Unterschied der Laufzeiten in der Praxis ist, zeigen folgende Experimente. Die Komplexitätsberechnungen beziehen sich ausschließlich auf den „worst case“. Der tritt in beiden Tests ein, wenn eine natürliche Zahl n als Primzahl erkannt wird. Der Rabin-MillerTest wird dann 20mal durchgeführt (siehe 2.4.). Aufgrund der Sicherheit beim Erkennen einer zusammengesetzten Zahl bricht der Test ab, sobald n als zusammengesetzt erkannt wurde. Uns interessierte deswegen die Frage, wie oft der Test bei zusammengesetztem n ausgeführt wird. Wie sieht es mit seiner Schnelligkeit aus? Auch der AKS–Test führt nicht jede Schleife vollständig durch, wenn n zusammengesetzt oder eine Primzahl ist. Hier interessierte uns die Frage, wie oft Schritt 5 des Algorithmus durchlaufen wird und wie schnell eine Auswertung stattfindet. Insgesamt ergeben sich vier zu untersuchende Fälle. Die Korrektheit der Ergebnisse unserer Primzahltests überprüften wir zur Sicherheit mit der Prozedur isprime in MuPAD. Es ergaben sich keine Unterschiede. 4.2. Durchschnittliche Schnelligkeit des Rabin Miller Tests beim Erkennen von Primzahlen und zusammengesetzten Zahlen 4.2.1. Experiment 1: Durchschnittliche Schnelligkeit des Rabin Miller Tests beim Erkennen von Primzahlen und zusammengesetzten Zahlen von 2-22 Bitstellen Im Intervall ]2k,2k+1[ , k ∈ {2,…,22}, werden alle ungeraden Zahlen gesucht, die Primzahlen oder zusammengesetzte Zahlen sind. Bei fester Bitstellenanzahl werden getrennt die jeweiligen Laufzeiten von Primzahlen und zusammengesetzten Zahlen gemessen und gemittelt. Als Ergebnis erhält man die mittleren Laufzeiten für das Erkennen von 2 Bit, 3 Bit,…, 22 Bit Primzahlen und zusammengesetzten Zahlen beim Rabin Miller Test. 20 Des Weiteren untersuchten wir für feste Bitstellenanzahl die durchschnittliche Anzahl der Runden, die der Test bei zusammengesetzten Zahlen ausführt. Dabei ließen wir uns auch den jeweils größten Wert ausgeben. 4.2.2. Messergebnisse von Experiment 1 Bitstellen 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Durchschnittliche Mittlere Anzahl Mittlere Anzahl Anzahl der Zeit Zeit Zusammeng. Primzahlen ausgeführten Erkennen Zahlen n p Erkennen Runden bei von von zusammeng. zusammengesetzten Primzahl Zahlen Zahl n in in msec msec 2 15.0 0 ----2 20.0 2 0 1 5 18.0 3 3.3333 1 7 15.86 9 0 1 13 13.08 19 1.0526 1.0526 23 15.26 41 0 1.0244 43 14.67 85 0.3529 1 75 15.79 181 0.5028 1 137 14.89 375 0.5333 1.0053 255 16.10 769 0.7125 1 464 16.13 1584 0.6572 1.0013 872 16.22 3224 0.6659 1.0022 1612 16.60 6580 0.6807 1.0014 3030 17.06 13354 0.6989 1.0006 5709 17.52 27059 0.7008 1.0003 10749 17.80 54787 0.7485 1.0003 20390 18.20 110682 0.7336 1.0002 38635 18.43 223509 0.7605 1.0001 73586 18.60 450702 0.7642 1.0001 140336 18.72 908240 0.7815 1.0001 268216 19.21 1828936 0.7924 1.0000 21 Maximale Rundenzahl bei zusammeng. Zahlen --1 1 1 2 2 1 1 2 1 2 4 3 2 2 2 2 2 3 4 3 mittlere Zeit zum Erkennen von p in msec 20 19 18 17 16 15 14 mittlere Zeit zum Erkennen von n in msec 13 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Anzahl der Bitstellen 3 2 1 0 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Anzahl der Bitstellen 22 mittlere Anzahl Schleifendurchläufe 1.05 1.04 1.03 1.02 1.01 1.00 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Anzahl der Bitstellen Auf den ersten Blick fallen sofort zwei Dinge auf. Erstens ist erwartungsgemäß der Test für zusammengesetzte Zahlen wesentlich schneller. Zweitens wurde eine zusammengesetzte Zahl nach maximal vier Durchläufen des Rabin– Miller–Tests erkannt – und das bei über zwei Millionen Zahlen. In den meisten Fällen endet der Algorithmus sogar nach einem Durchlauf. Die Werte sind trotz alledem mit Vorsicht zu betrachten, da der Rabin Miller Test vom Zufall abhängig ist. 4.2.3. Experiment 2: Durchschnittliche Schnelligkeit des Rabin–Miller–Tests beim Erkennen von Primzahlen und zusammengesetzten Zahlen (Bitstellen von 100, 200,…,2100, 2200) Im Intervall ]2k,2k+1[ ,k ∈ {100, 200, …, 2100,2200}, werden zufällig 20000 ungerade Zahlen gewählt. Im Gegensatz zu Experiment 1 konnten wir aus „Zeitgründen“ nicht alle ungeraden Zahlen einer festen Bitstellenanzahl untersuchen. Wie viele Primzahlen beziehungsweise zusammengesetzte Zahlen jeweils gefunden wurden, kann in den Ergebnissen des Experiments unten nachgelesen werden. Die ungeraden Zahlen werden hinsichtlich Zusammengesetztheit und Primzahleigenschaft untersucht und die jeweiligen Laufzeiten gemessen und gemittelt. Als Ergebnis erhält man die mittleren Laufzeiten für das Erkennen von 100 Bit, 200 Bit,…, 2200 Bit zusammengesetzten, ungeraden Zahlen beziehungsweise Primzahlen beim Rabin–Miller–Test. Des Weiteren untersuchten wir für feste Bitstellenanzahl bei zusammengesetzten Zahlen die durchschnittliche Anzahl der Runden, die der Test ausgeführt wurde. Dabei ließen wir uns auch die jeweils maximale Rundenzahl ausgeben. 4.2.4. Messergebnisse von Experiment 2 Bitstellen Maximale Mittlere Zeit Durchschnittliche Anzahl Mittlere Anzahl Rundenzahl bei Anzahl der Erkennen Zusammeng. Zeit Primzahlen zusammeng. ausgeführten von Zahlen n Erkennen p Zahlen Runden bei Zusammeng. von zusammng. Zahl n in sec Primzahl 23 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 562 260 108 222 0 112 62 41 93 20 60 37 27 70 0 36 32 20 53 21 31 31 p in sec 0.05 0.101 0.177 0.282 ---0.614 0.847 1.149 1.55 2.00 2.516 3.142 3.867 4.681 ---6.667 7.950 9.258 10.703 12.344 14.140 16.03 Zahlen n 19438 19740 19892 19778 20000 19888 19938 19952 19907 19980 19940 19963 19973 19930 20000 19964 19968 19980 19947 19979 19969 19969 24 0.002 0.002 0.004 0.013 0.008 0.025 0.019 0.024 0.071 0.041 0.102 0.072 0.081 0.213 0.107 0.271 0.185 0.196 0.508 0.260 0.603 0.379 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 mittlere Zeit zum Erkennen von n in sec 0.6 0.5 0.4 0.3 0.2 0.1 mittlere Zeit zum Erkennen von p in sec 0.0 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 Anzahl der Bitstellen 16 14 12 10 8 6 4 2 0 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 Anzahl der Bitstellen Für die Messwerte dieses Tests rechnete der Computer eine ganze Nacht. Das erstaunlichste Ergebnis dieses Experimentes ist die Tatsache, dass der Rabin Miller Test bei zusammengesetzten Zahlen in über 400000 Tests nie mehr als einmal durchlaufen wurde. 25 In Experiment 1 zeigte sich auch schon diese Tendenz, dort wurde der Test aber in wenigen Fällen noch maximal viermal durchlaufen (siehe 4.1.1.2). Wie zu erwarten war, werden zusammengesetzte Zahlen schneller erkannt als Primzahlen. Je größer die Bitstellenanzahl ist, desto länger dauert der Test in beiden Fällen. 4.2.5. Experiment 3: Durchschnittliche Schnelligkeit des Rabin–Miller–Tests beim Erkennen einer zusammengesetzten Zahl (Bitstellen von 5200, 10200,…,30200, 35200) Im Intervall ]2k,2k+1[, k ∈ {5200, 10200, …, 30200, 35200}, werden zufällig 200 ungerade Zahlen gewählt. Im Gegensatz zu den Experimenten 1 und 2 mussten wir uns aus „Zeitgründen“ auf wesentlich weniger ungerade Zahlen einer festen Bitstellenanzahl beschränken. Die ungeraden Zahlen werden hinsichtlich Zusammengesetztheit untersucht und die jeweiligen Laufzeiten gemessen und gemittelt. Als Ergebnis erhält man die mittleren Laufzeiten für das Erkennen von 5200 Bit, 10200 Bit,…, 35200 Bit zusammengesetzten, ungeraden Zahlen beim Rabin–Miller–Test. Des Weiteren untersuchten wir für feste Bitstellenzahl bei zusammengesetzten Zahlen die durchschnittliche Anzahl der Runden, die während des Tests ausgeführt wurden. Dabei ließen wir uns auch die jeweils maximale Rundenzahl ausgeben. 4.2.6. Messergebnisse von Experiment 3 Bitstellen Anzahl zusammeng. Zahlen n 5200 10200 15200 20200 25200 30200 35200 200 200 200 200 200 200 200 Mittlere Zeit Erkennen von n in min. 0.145 1.102 3.490 8.370 16.353 27.271 43.543 Durchschnittliche Anzahl der ausgeführten Runden bei n 1.0 1.0 1.0 1.0 1.0 1.0 1.0 26 Maximale Rundenzahl bei zusammeng.Zahlen n 1 1 1 1 1 1 1 mittlere Zeit zum Erkennen von n in min 40 30 20 10 0 5200 10200 15200 20200 25200 30200 35200 Anzahl der Binärstellen Für dieses Experiment rechnete der Computer 2 Wochen lang während der Urlaubszeit. Die Erkennungszeiten rücken nun in Bereiche, wo man „sehr lange warten muss“, zumal, wenn man bedenkt, dass zusammengesetzte Zahlen viel schneller erkannt werden als Primzahlen. Die erstaunlichen Beobachtungen aus Experiment 3 setzten sich fort. Auch hier wurde der Rabin–Miller–Test nur ein einziges Mal durchlaufen. 4.2.7. Experiment 4: Schnelligkeit beim Erkennen von bekannten Primzahlen (Mersenne – Primzahlen) (Bitstellen 9688, 9940, 11212, 19936, 21700, 23208, 44496) Durch zufällige Suche konnten wir in der Größenordnung von Experiment 3 keine Primzahlen finden. Aus Zeitgründen entschlossen wir uns deshalb, eine Liste von bekannten Mersenne Zahlen (Primzahlen), die der Größenordnung von Experiment 3 entsprechen, abarbeiten zu lassen und die Zeit zur Berechnung zu bestimmen. Aufgrund der Beobachtung in obigen Experimenten, dass zusammengesetzte Zahlen nach einer Runde erkannt werden, setzten wir die Anzahl der zu durchlaufenden Runden des Rabin–Miller–Tests auf 10 herunter. Auch in MuPAD wird der Rabin–Miller–Test 10 Runden ausgeführt. Um die Erkennungszeiten von Primzahlen des Experiments 4 mit den Experimenten 1 – 3 vergleichen zu können, müssten diese also ungefähr verdoppelt werden. 4.2.8. Messergebnisse von Experiment 4 Mersennsche Primzahl 29689-1 29941-1 211213-1 219937-1 221701-1 223209-1 244497-1 Zeit zum Erkennen in min. 10,13 10.96 15.65 86.77 112.10 137.30 974.66 27 Zeit zum Erkennen von p in min 120 100 80 60 40 20 9689 11213 19937 21701 23209 Exponenten m der Mersennschen Primzahlen (2^m)-1 In dieser Größenordnung ist die Wartezeit sehr lang. Das eigentliche Problem für die Praxis liegt unserer Meinung nach aber eher in der Tatsache, dass es immer schwieriger wird, große Primzahlen durch zufällige Suche zu finden, denn dazu wäre es notwendig sehr viele „große“ Zahlen zu testen, was zuviel Zeit in Anspruch nimmt. Die Verteilungen der Primzahlen sind zwar bekannt, erweist es sich aber beispielsweise als notwendig, 10 Zahlen zu testen, um eine Primzahl mit 20000 Bitstellen zu finden, dann dauert das über 3 Stunden. Bei Primzahlen mit 40000 Bitstellen sind in diesem Fall 17 Stunden notwendig (siehe 4.2.6. und 4.2.7.). Die Suche nach einer Primzahl nimmt mehr Zeit in Anspruch als die Laufzeit, die zum Testen einer Primzahl benötigt wird. 4.2.9. Experiment 5: Untersuchung der relativen Häufigkeiten von Basen, für die n eine starke Pseudoprimzahl ist Die Experimente 1-3 hinterließen bei uns die Frage, wieso der Rabin–Miller–Test für große Größenordnungen bei zusammengesetzten Zahlen ausschließlich nur einmal ausgeführt wurde. Eine Vermutung von uns ist, dass der Anteil der Basen bei „großen Größenordnungen“, für die eine zusammengesetzte Zahl n eine starke Pseudoprimzahl ist, wesentlich kleiner sein könnte als im Beweis von M.O. Rabin angegeben (siehe 2.2. und [RAB80]). Hinzu kommt, dass sich der Satz 2.2.2. auf die multiplikative Gruppe ( /n ) × bezieht. Ihre Ordnung ist aber (siehe Eulersche Funktion) bei zusammengesetzten Zahlen kleiner als n-1. Im Algorithmus jedoch werden natürlichen Zahlen zwischen 1 und n-1 zufällig gewählt. Deswegen liegt die Wahrscheinlichkeit, zufällig eine Basis zu wählen, für die n eine starke Pseudoprimzahl ist, unter dem angegebenen Wert von ½ bzw. ¼ (mit dem Ergebnis von Rabin [RAB80]). Eine andere Vermutung von uns ist, dass es nur sehr wenige starke Pseudoprimzahlen n gibt, deren Basenanteil an die ¼ heranreicht. Bei größeren Zahlen konnten wir aus Zeitgründen (siehe oben) nicht mehr alle Zahlen mit konstanter Bitstellenanzahl absuchen und fanden vielleicht deswegen die möglicherweise wenigen starken Pseudoprimzahlen, die einen großen Anteil an Basen besitzen, nicht. Wir bestimmten deswegen für alle zusammengesetzten Zahlen n mit 3 bis 14 Bitstellen die Anzahl der starken Pseudoprimzahlen und berechneten ihren Anteil an der multiplikativen Gruppe ( /n ) × . Den maximalen und den gemittelten Wert für jeweils feste 28 Bitstellenanzahl ließen wir uns ausgeben. Des Weiteren berechneten wir den Anteil dieser Basen an den Zahlen 1 bis n-1, also die relative Häufigkeit der Basen. Hier ließen wir uns die durchschnittlichen und die maximalen relativen Häufigkeiten bei fester Bitzahl berechnen. Damit erhält man einen Eindruck davon, wie viele starke Pseudoprimzahlen mit einem großen Anteil an Basen (also um die ¼) bei fester Bitstellenzahl existieren. Für eine größere Anzahl an Bitstellen konnten wir leider die Tests nicht durchführen. Das Überprüfen jeder natürlichen Zahl in der Menge {1,…, n-1} auf eine mögliche Baseneigenschaft ist nicht effizient und das machte sich schnell bemerkbar. 4.2.10. Messergebnisse von Experiment 5 Anzahl der Bitstellen der zusammengesetzten Zahl n 3 4 5 6 7 8 9 10 11 12 13 14 Maximaler Anteil der Basen in ( /n ) × für die n starke Pseudoprimzahl 0.333 0.2 0.143 0.25 0.167 0.167 0.25 0.25 0.188 0.167 0.25 0.167 Maximale relative Häufigkeit der Basen in {1,…,n-1} 0.25 0.167 0.125 0.2 0.136 0.147 0.231 0.238 0.18 0.162 0.245 0.165 29 Durchschnittl. Anteil der Basen in ( /n ) × für die n starke Pseudoprimzahl 0.1167 0.0531 0.0421 0.0322 0.0200 0.0135 0.0076 0.0057 0.0032 0.0021 0.0015 0.0009 Durchschnittliche relative Häufigkeit der Basen in {1,…,n-1} 0.0786 0.0382 0.0288 0.0237 0.0140 0.0106 0.0061 0.0047 0.0027 0.0018 0.0013 0.0008 Die Ergebnisse dieses Experiments zeigen, dass eine Abschätzung der Irrtumswahrscheinlichkeit unter dem angegebenen Wert von ¼ durch M. O. Rabin nicht zu erreichen ist. Andererseits besteht die Möglichkeit einer besseren Abschätzung bei sehr großen Zahlen. Diese muss jedoch auf theoretischer Ebene stattfinden. Das Experiment zeigt eine weitere Tendenz. Der Anteil an starken Pseudoprimzahlen, deren Basenanteil in ( /n ) × in der Nähe von ¼ liegt, wird mit steigender Bitstellenanzahl geringer. Vielleicht wird es möglich auf der Grundlage weiterer Beobachtungen eine 30 Spezialform des Satzes 2.2.2. zu geben. (Etwa: Die Wahrscheinlichkeit, dass eine starke Pseudoprimzahl der Bitstellenzahl größer gleich x einen Basenanteil in ( /n ) × besitzt, der größer als der Wert y ist, liegt unter dem Wert z. y und z sollten dabei sehr klein sein.) Mit solch einem Satz wäre es möglich die Anzahl der zu durchlaufenden Runden für spezielle Größenordnungen im Rabin–Miller–Test herabzusetzen. Damit würde sich die Berechnungszeit für große Primzahlen deutlich verringern. 4.3. Durchschnittliche Schnelligkeit des AKS –Tests beim Erkennen von Primzahlen und zusammengesetzten Zahlen 4.3.0. Vorbemerkung Bereits nach den ersten Testreihen vom AKS-Algorithmus wurde uns klar, dass einige Unterschiede zum Rabin-Miller–Algorithmus andere Herangehensweisen zur Ermittlung der Schnelligkeit erfordern. Es treten vier verschiedene Möglichkeiten für das Erkennen von zusammengesetzten Zahlen beziehungsweise Primzahlen auf. Das Erkennen der entsprechenden Zahlen ohne Schritt 5 (ohne den Polynomvergleich des Hauptsatzes) beziehungsweise mit Schritt 5 (siehe 3.3.). Die gemessenen Zeiten hängen erheblich davon ab, welcher dieser Fälle eintritt. Beim Erkennen von Primzahlen erscheint alles noch sehr einfach. Ab der Primzahl 28+15 wird immer der Schritt 5 durchgeführt. Der Grund dafür liegt darin, dass r ab dieser Zahl immer kleiner als n ist (siehe 3.3. Schritt 5). Allerdings zeigte sich schnell ein anderes Problem. Das Erkennen einer Primzahl dauert sehr lange. Beispielsweise benötigte der AKS für die Primzahl 213-1 fast eine halbe Stunde und bei der Zahl 219-1 gaben wir nach zweitägiger Wartezeit auf. Deshalb bestimmten wir die Laufzeit, die der Schritt 5 zur Berechnung des ersten Polynoms [T + 1] n im Restklassenring R benötigt. Betrachtet man weiter die Anzahl der zu berechnenden Polynome, dann erhält man eine Vorstellung von der Größenordnung der benötigten Laufzeit in Schritt 5. Beim Erkennen von zusammengesetzten Zahlen erscheint vieles komplizierter. Die kleinste zusammengesetzte Zahl, bei der Schritt 5 ausgeführt wird, ist 221+1835121. Die Durchführung von Schritt 5 ist abhängig von der Größe des kleinsten Teilers von n. Ist dieser größer als r (siehe Schritt 3 von 3.3.), dann wird immer Schritt 5 ausgeführt. Das heißt, sollte es jemandem gelingen ein r mit kleinerer Größenordnung zu finden, bedeutete dies für zusammengesetzte Zahlen kleiner Größenordnung, dass sich der Test verlangsamt, da diese dann auch den Schritt 5 durchlaufen müssen. Da die kleinsten Teiler einer Zahl nicht von ihrer Größenordnung abhängen, gibt es somit Zahlen jeder Größenordnung für deren Test der Schritt 5 durchlaufen bzw. nicht durchlaufen wird. In unserer Implementierung spielt auch der etwas veränderte Schritt 2 eine Rolle (siehe 3.3.3.). Trotz dieser Unterschiede zum Rabin Miller Test versuchten wir äußere Randbedingungen wie Messergebnisse zu Bitstellen von 2-22 zu erhalten, um einen Vergleich zu ermöglichen. 31 4.3.1. Experiment 1: Durchschnittliche Schnelligkeit des AKS–Tests beim Erkennen zusammengesetzter Zahlen von 2-20 Bitstellen Innerhalb dieser Größenordnung durchläuft keine einzige zusammengesetzte Zahl den Schritt 5 des AKS–Tests. Das ermöglichte uns, die Laufzeiten aller zusammengesetzten Zahlen zu bestimmen und zu mitteln. 4.3.2. Messergebnisse von Experiment 1 Anzahl der Bitstellen Anzahl der zus. Zahlen Zeit zum Erkennen von n in msec 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 3 9 19 41 85 181 375 769 1583 3224 6580 13354 27059 54787 110682 223509 450702 Mittlere Laufzeit in sec. 0.000 0.000 0.0067 0.004 0.007 0.007 0.010 0.010 0.011 0.013 0.015 0.017 0.019 0.022 0.024 0.028 0.030 0.040 0.04 0.03 0.02 0.01 0.00 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Anzahl der Bitstellen von n 32 4.3.3. Experiment 2: Schnelligkeit der ersten 20 zusammengesetzten Zahlen, die Schritt 5 des AKS –Tests durchlaufen (21 Bitstellen) Die ersten 20 zusammengesetzten Zahlen, die Schritt 5 durchlaufen, besitzen 21 Bitstellen. Alle werden bereits nach der Berechnung des ersten Polynoms als zusammengesetzt erkannt. (Alle Koeffizienten sind ungleich 0.) Leider hatten wir nicht die Möglichkeit einen Vergleich der Schnelligkeit von zusammengesetzten Zahlen von 21 Bitstellen mit einer größeren Anzahl von Bitstellen vorzunehmen. Die Suche nach solchen Zahlen nimmt erhebliche Zeit in Anspruch. Hinzu kommt, dass auch die Berechnungszeiten der Polynome immer größer werden. Die Zahl 241-1 ist auch eine zusammengesetzte Zahl, die Schritt 5 durchläuft. Bereits für die Berechnung des ersten Polynoms [T + 1] n im Restklassenring R benötigte der Rechner 83,21 Minuten. Damit war der Algorithmus aber noch nicht beendet, denn der Vergleich zeigte Gleichheit. So entschlossen wir uns, die Laufzeiten für das Erkennen der ersten 20 zusammengesetzten Zahlen, die in Schritt 5 erkannt werden, zu messen. Die maximalen Polynomgrade dieser Polynome entsprechen dem Wert von n mod r. Oft ähneln sich die verschiedenen Werte von n mod r und auch die theoretische Anzahl der zu berechnenden Polynome. Deswegen haben wir interessehalber, ohne eine Interpretation, diese Werte aufgenommen. 4.3.4. Messergebnisse von Experiment 2 Zusammengesetzte Zahl n der Form 221+i , i 1752171 1755317 1759919 1763877 1779485 1787205 1790111 1798995 1802897 1807415 1810701 1822287 1823199 1826309 1835037 1835121 1838015 1842929 1846875 1846995 Maximaler Polynomgrad, r Anzahl der zu berechnenden Polynome 1922 1922 1922 1931 1923 1923 1923 1923 1923 1933 1924 1924 1933 1933 1924 1924 1924 1934 1934 1934 1930 1930 1930 1948 1930 1930 1930 1930 1930 1950 1930 1930 1948 1948 1930 1930 1930 1948 1948 1948 33 Schnelligkeit in min. 0.96 1.52 1.79 1.23 1.92 2.25 2.44 2.55 2.59 2.66 2.71 2.64 2.63 2.74 2.74 2.77 2.70 2.72 2.68 2.70 Zufällig machte ich eine weitere Beobachtung, die ich nicht unerwähnt lassen möchte. Die Zahlen der Form 2p-1 sind entweder Mersennsche Primzahlen oder zusammengesetzte Zahlen. Der Schritt 5 wurde bei meinen Tests nur von zusammengesetzten Zahlen bei denen p Primzahl ist, ausgeführt. Alle anderen wurden vorher entdeckt. Hier folgt eine Liste der entsprechenden Zahlen. (241-1, 259-1, 267-1,271-1, 2101-1, 2103-1, 2109-1, 2523-1, 2541-1,2563-1, 2569-1, 2599-1) 4.3.5. Experiment 3: Schnelligkeit des AKS- Tests beim Erkennen von Primzahlen von 2-22 Bitstellen Wie wir bereits weiter oben erwähnt haben, wird im AKS-Algorithmus ab der Primzahl 28+15, der Schritt 5 bei allen größeren Primzahlen durchlaufen. Wir hatten nicht die Möglichkeit, die Laufzeit für eine Zahl wie 217-1 zu bestimmen. Der Grund findet sich in der Berechnung des Polynoms [T + a] n im Restklassenring R (siehe 3.0.). Dieses wird mittels wiederholten Quadrierens (siehe 3.3.2.) ausmultipliziert. Das beansprucht in diesem Fall für ein a eine viertel Minute. Das erscheint nicht lange. Allerdings beträgt hier die Anzahl der zu berechnenden Polynome 1170, nämlich von a = 1 bis a = 1170. Das bedeutet, allein der Schritt 5 erfordert mehr als einen Tag Berechnungszeit. Deshalb sind wir in unserem Versuch folgendermaßen vorgegangen. Für je eine Primzahl der Bitstellenlängen 2 bis 10 stellten wir die Laufzeit des Algorithmus fest. Für je eine Primzahl der Bitstellenlänge von 8 bis 22 stoppten wir die Zeit zur Berechnung des Polynoms [T + 1] n im Restklassenring R und die Gesamtzeit vom Start des AKS–Algorithmus bis nach der Berechnung dieses Polynoms. Das fanden wir wichtig, weil es zeigt, dass einzig der Schritt 5 „viel“ Zeit in Anspruch nimmt (siehe 4.3.3.). Auch die Anzahl der zu berechnenden Polynome ließen wir uns ausgeben. Damit wird es möglich, eine sehr grobe Abschätzung über die Größenordnung der gesamten Rechenzeit zu geben, da der Algorithmus im Falle einer Primzahl alle Polynome berechnen muss. Man könnte also die Laufzeit zur Berechnung eines Polynoms mit der Anzahl der zu berechnenden Polynome multiplizieren und erhält eine Vorstellung davon, in welcher Größenordnung sich die Laufzeit des gesamten Algorithmus bewegen wird. 4.3.6. Messergebnisse von Experiment 3 Tabelle 1: Primzahl n 22+1 23+3 24+1 25+5 26+3 27+3 28+1 28+15 29+9 210+7 Berechnungszeit in msec. 0 0 0 0 16 16 16 6797 30985 139359 34 Zeit zum Erkennen von n in sec 30 20 10 0 2 3 4 5 6 7 8 9 Anzahl der Bitstellen Wie zu erwarten war, lassen sich die Primzahlen von 2 bis 28+1 innerhalb kürzester Zeit testen. Darüber steigt die Laufzeit bei Primzahlen rasant an. Tabelle 2: Primzahl p Berechnungszeit von [T + 1] n in R in min. 28+15 29+9 210+7 211+21 212+3 213+17 214+27 215+3 216+1 217+29 218+3 219+21 220+7 221+17 222+15 0.0003 0.002 0.004 0.009 0.027 0.053 0.101 0.184 0.280 0.424 0.628 0.870 1.211 0.883 1.162 Berechnungszeit von Beginn des Algorithmus bis nach [T + 1] n Berechnung in min. 0.0003 0.002 0.004 0.107 0.027 0.054 0.101 0.184 0.281 0.424 0.628 0.870 1.212 0.884 1.164 35 Anzahl der zu prüfenden Polynome im Algorithmus 264 327 409 493 581 679 785 904 1027 1167 1307 1445 1603 1775 1963 Zeit zum Berechnen von [T+1]^p in min. 1.2 1.0 0.8 0.6 0.4 0.2 0.0 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Anzahl der Bitstellen von p Die Ergebnisse dieses Experiments zeigen, dass der AKS-Algorithmus bereits bei Primzahlen der Größenordnung von 15 Bitstellen keinen praktischen Anforderungen genügt. Wenn man außerdem bedenkt, was wir in der Einleitung über die Größenordnung von heute in der Praxis gebräuchlichen Primzahlen geschrieben habe, wird klar, dass der AKS-Algorithmus nicht annähernd an die Schnelligkeit des Rabin–Miller–Tests heranreicht. Dabei ist der am meisten zeitraubende Schritt offensichtlich die Berechnung der Polynome [T + a] n in R. Selbst wenn die Anzahl der zu berechnenden Polynome durch entsprechende Beweise auf ein einziges gesenkt werden könnte (wie unter der Überschrift „6 Future Work“ in [AKS04] vermutet), die Berechnung mit der Methode des wiederholten Quadrierens dauert zu lange. Für die Primzahl 241+27 benötigte dieser Schritt bereits 83,22 Minuten. Diese Verbesserung würde zwar die Laufzeit des AKS–Tests wesentlich verringern, praxisrelevant wäre er aber trotz alledem nicht. Es sei denn, es gelingt, einen effizienteren Algorithmus als das wiederholte Quadrieren zu finden (siehe 3.3.2.). 5. Vergleich und Zusammenfassung Der Rabin–Miller–Test schneidet in unsren Experimenten bezüglich der praxisorientierten Anwendung nicht nur wesentlich besser ab, sondern er scheint auch als einziger von beiden dafür in Frage zu kommen. Ob es sich um das Erkennen von Primzahlen oder zusammengesetzten Zahlen handelt, er ist nicht nur asymptotisch schneller als der AKS–Test, sondern in jedem Einzelfall schneller. Der AKS–Test ist in dieser Form für praktische Anwendungen wie in der Kryptographie nicht geeignet. Bereits bei Primzahlen mit 15 Bitstellen befindet sich die Laufzeit für Benutzer in inakzeptablen Bereichen. Auch eine Verbesserung von Schritt 5, wie in [AKS04] vorgeschlagen wird, führt mit der Methode des wiederholten Quadrierens nicht zur Praxistauglichkeit. Möglicherweise können an dieser Stelle aber theoretische Untersuchungen über das Vorhandensein einzelner Koeffizienten des Polynoms im Restklassenring R bei zusammengesetzten Zahlen weiterhelfen. Bisher geben die Sätze für Zusammengesetztheit keine konstruktive Auskunft (siehe 3.3.). Sollten solche Ergebnisse gelingen, dann kann möglicherweise auf die Berechnung des gesamten Polynoms verzichtet werden, weil man sich auf einzelne Koeffizienten beschränken kann. Das würde die Situation ändern. 36 Der Rabin–Miller–Test ist für heutige Ansprüche außerordentlich gut für praktische Anwendungen geeignet. Eine Primzahl mit 2200 Bitstellen wird bei unserer Programmierung mit 20 unabhängig gewählten Basen in 16 Sekunden erkannt. In 4.2.10 haben wir die Vermutung geäußert, dass sich die Anzahl der unabhängigen Versuche drastisch verringern lässt. Unsere Annahme basiert auf der Beobachtung, dass der Rabin-Miller-Algorithmus für heute in der Praxis relevante Größenordnungen nur einmal durchlaufen wird, um eine zusammengesetzte Zahl zu erkennen. Werden in Zukunft für die Sicherheit von Kryptosystemen höhere Größenordnungen von Primzahlen notwendig, muss man sich sicherlich mit der Frage auseinandersetzen, welcher theoretische Hintergrund dieser Beobachtung zugrunde liegt. In 4.2.10. haben wir eine Vermutung darüber geäußert, in welcher Hinsicht eine Auseinandersetzung stattfinden könnte. Trotz der Schlussfolgerungen aus unseren Experimenten bleibt die besondere Bedeutung des AKS–Tests als erster deterministischer effizienter Primzahltest, der noch in den Kinderschuhen steckt und dem vielleicht einige Kapazitäten zur Verbesserung innewohnen. Für theoretische Informatiker ist allein diese Tatsache von großer Bedeutung. Beenden möchten wir deswegen unsere Arbeit mit einem Zitat des Mathematikers G. H. Hardy [SNGH02]. „… Gemessen an allen praktischen Kriterien ist der Wert meines Mathematikerlebens gleich null; und außerhalb der Mathematik ist es ohnehin belanglos. Ich habe nur eine Chance, dem Urteil völliger Belanglosigkeit zu entkommen, nämlich wenn es heißt, ich hätte etwas geschaffen, das schaffenswert war. Und dass ich etwas geschaffen habe, ist unbestreitbar: in Frage steht nur dessen Wert.“ Danksagung Mein allergrößter Dank gilt meiner Schwiegermutter Frau Dr. Ursula Berger, die in den schwierig zu organisierenden Wochen von Vorlesungszeit und Schulferien ihren Jahresurlaub opferte, um meine Kinder nicht nur zu betreuen, sondern ihnen eine unvergessliche Zeit zu bereiten. Mein herzlicher Dank gilt auch Frau Dr. Silke Hartlieb, die mir mit zahlreichen nützlichen Ratschlägen zu Seite stand und Frau Prof. Luise Unger, die mir durch die Art ihrer Lehre das Denken beigebracht hat. Vielen Dank auch an Herrn Kai Gehrs vom MuPad–Team. Die unkomplizierte und freundliche Bereitstellung einer Lizenz hat mir sehr geholfen. 37 Literatur [AKS04] M. Agrawal, N. Kayal, N. Saxena. PRIMES is in P, 2004. [B99] J. Buchmann. Einführung in die Kryptographie. Springer, 1999. [BSI04] Webseite http://www.bsi.de. Bundesamt für Sicherheit in der Informationstechnik. [D04] M. Dietzfelbinger. Primality Testing in Polynomial Time. Lecture Notes in Computer Science 3000. Springer, 2004. [DI04] M. Dietzfelbinger. Primality testing in polynomial time. Lecture Notes in Computer Science 3000. Springer-Verlag, 2004. [HMU] J.E. Hopcroft, R. Motwani. Einführung in die Automatentheorie. Formale Sprachen und Komplexität. Pearson Studium 2003. [KNU02] D. E. Knuth. The art of computer programming. Volume 2, 285, 337, AddisonWesley, 2002. [KR98] R. Kumanduri, C. Romero. Number theory with computer applications. Prentice Hall, 1998. [LEN02] H. W. Lenstra, Jr. Primality testing with cyclotomic rings. Unpublished (http://cr.yp.to/papers.html#aks has an exposition of Lenstras argument), August 2004 [LN86] R. Lidl and H. Niederreiter. Introduction to finite fields and their applications. Cambridge University Press, 1986. [NAI82] M. Nair. On Chebyshev-type inequalities for primes. Amer. Math. Monthly. 89:126-129, 1982. [PLO98] Der große Ploetz. Verlag Herder, 1998. [RAB80] M. O. Rabin. Probalistic algorithm for testing primality. J. Number Theory, 12:128-138, 1980. [RSA78] R. Rivest, A. Shamir, L. Adleman. A method for obtaining digital signatures and public key kryptosystems, Communication of ACM 21, 2, 1978, S. 120-126. [SCH02] P. Schreiber. Algorithmen. Spektrum der Wissenschaft Spezial - Forschung und Technik im Mittelalter, Februar 2002. [SNGH02] S. Singh. Fermats letzter Satz. Deutscher Taschenbuchverlag, 2002. [SW90] U. Storch, H. Wiebe. Lehrbuch der Mathematik, Band 2: Lineare Algebra. BIWiss.-Verlag, 1990. 38 Anhang A Programm des Rabin-Miller-Algorithmus in MuPAD RabinMiller:=proc(n:Type::PosInt) begin Ende:=FALSE; j:=1; s:=n-1; r:=0; while (_mod(s,2)=0) do s:=_div(s,2); r:=r+1 end_while; //Programmierung des Rabin-Miller-Algorithmus, siehe 2.3. //Laufvariable //n-1 wird in das Produkt von einer geraden und ungeraden Zahl(2^r und s)zerlegt. while (not Ende and j<21) //Der Rabin Miller Test endet, wenn n als zusammengesetzt erkannt wurde. do //Insgesamt sind 20 unabhängige Durchläufe möglich. if (_mod(n,2)=0) then //Wenn n gerade ist, dann ist n keine Primzahl. primzahl:=FALSE else myRnd:=random(2..(n-2)); Basis:=myRnd(); //Zufällige Erzeugung einer potentiellen Basis.n ist für 1 und n-1 immer starke Pseudoprimzahl. ggT:=igcd(Basis,n); //Deswegen werden 1 und n-1 nicht berücksichtigt. if (ggT>1) then //Schritt 1. in 2.3.1.: Der ggT von potentieller Basis und n wird bestimmt. primzahl:=FALSE; //Ist der ggt>1, dann ist n keine Primzahl. else //Sonst erfolgt Schritt 2. in 2.3.1. b:=Basis; //Dieser testet, ob n starke Pseudoprimzahl zur potentiellen Basis b ist. xxx:=Basishochs(b,s,n); //Die Prozedur Basishochs erfolgt mir wiederholtem Quadrieren (siehe weiter Anhang A). if (xxx=1 or xxx=n-1) then //Ist das 1.Folgenglied 1 oder -1, dann ist n starke Pseudoprimzahl zur Basis (siehe 2.2.1.). primzahl:=TRUE else //Sonst wird b^s wiederholt quadriert. k:=0; while (xxx<>1 and xxx<>n-1 and k<>r)//Solange eines der Folgenglieder nicht 1 oder -1 oder bis b^n-1 erreicht wird, wird quadriert. do xxx:=_mod(xxx^2,n); k:=k+1 end_while; if (k=r) then //Wurde bis b^n-1 quadriert, dann kann n keine starke Pseudoprimzahl zur Basis b sein. primzahl:=FALSE //Denn dann ist das vorletzte Folgenglied weder 1 noch n-1. else if (xxx=n-1) then //Wurde nicht bis zum Schluss quadriert und ist xxx=n-1, primzahl:=TRUE //dann ist n starke Pseudoprimzahl zur Basis b. else primzahl:=FALSE //Wurde nicht bis zum Schluss quadriert und ist xxx<>n-1, 39 end_if end_if end_if end_if end_if; Ende:=not primzahl; j:=j+1 end_while; RabinMiller():=[primzahl,j-1] end_proc; //dann kann n keine starke Pseudoprimzahl zur Basis b sein. //Ist n eine starke Pseudoprimzahl zur Basis b, so wird der Test für eine weitere //potentielle und zufällig gewählte Basis durchgeführt. //Rückgabe:[n ist Primzahl TRUE oder FALSE, Anzahl der Durchläufe des Tests] Prozedur Basishochs Basishochs:=proc(b,s,n) begin y:=matrix(numlib::g_adic(s,2)); z:=1; Zeilenzahl:=linalg::matdim(y); l:=Zeilenzahl[1]; for i from 1 to l do if (y[i]=1) then z:=_mod(z*b,n); end_if; b:=_mod(b^2,n); end_for; Basishochs():=z end_proc //Berechnet die s-te Potenz der Zahl b im Restklassenring Z/nZ mit dem Prinzip //des wiederholten Quadrierens siehe 2.3.2. //Binärdarstellung von des Exponenten s. //Hilfsvariable //Bestimmt die Anzahl der Bitstellen von s. //Ist die jeweilige ite Bitstelle vom Exponenten s eine 1, //dann wird die 2^i te Potenz von b multipliziert. //Berechnet die 2^i te Potenz von b. 40 Anhang B Programm des AKS-Algorithmus in MuPAD AKS:=proc(n:Type::PosInt) begin vielleichtPrimzahl:=TRUE; if ((n=1) or _mod(n,2)=0) then vielleichtPrimzahl:=FALSE else aa:=numlib::ispower(n); if (aa<>FALSE) then vielleichtPrimzahl:=FALSE end_if end_if; if (vielleichtPrimzahl)then r:=SucheR(n); for i from 2 to r do ggT:=(igcd(i,n)); if ((ggT>1) and (ggT<n))then vielleichtPrimzahl:=FALSE end_if end_for end_if; wardrinnen:=FALSE; if vielleichtPrimzahl then if (n<=r) then else wardrinnen:=TRUE; vielleichtPrimzahl:=HaupttestAnna(n,r) end_if end_if; AKS():=[vielleichtPrimzahl,wardrinnen] end_proc; //Berechnet deterministisch, ob eine Zahl n eine Primzahl ist siehe 3.3.1.. //Hilfsvariable //Wenn n gerade ist oder gleich 1, //dann ist n keine Primzahl. //Schritt 1 von 3.3.1. Ist n Potenzzahl mit Potenz >= 2 ? //Wenn n eine Potenzzahl ist, dann ist n keine Primzahl. //Schritt 2 von 3.3.1. Sucht ein kleinstes r //mit der Prozedur SucheR. //Schritt 3 von 3.3.1. mit euklidischem Algorithmus. //Die Hilfsvariable kontrolliert, ob Schritt 5 von 3.3.1.durchlaufen wurde. //Schritt 4 von 3.3.1. //Schritt 5 von 3.3.1. wird durchlaufen mit der Prozedur HaupttestAnna. //Rückgabe:[ist n Primzahl TRUE oder FALSE, Schritt 5 durchlaufen TRUE oder FALSE] 41 Prozedur SucheR SucheR:=proc(n) begin mini:=trunc(4*(log(2,n))^2)+1; fertig:=FALSE; r:=mini; while (not fertig) do ungleicheins:=TRUE; kk:=1; xx:=1; m:=_mod(n,r); while (ungleicheins and (kk<mini)) do xx:=_mod(xx*m,r); if (xx=1) then ungleicheins:=FALSE else kk:=kk+1 end_if; end_while; if ((kk=mini) and ungleicheins) then fertig:=TRUE else r:=r+1 end_if end_while; SucheR():=r end_proc; //Schritt 2 von 3.3.1. //Kleinstmöglicher Wert von r, siehe 3.3.3. //Entscheidungsvariable der ersten while-Schleife. //Laufvariable r. //Zählt r hoch und überprüft, ob n^k(modr)<>1 für alle k<mini. //Entscheidungsvariable der zweiten while-Schleife. //kk steht für k siehe 3.3.1. //Hilfsvariable. //Berechnet kte Potenz von (n mod r) bis maximal k=mini. //Ist das Produkt für k<mini 1, dann wird wird für r+1 getestet. //r ist gefunden, wenn x^k mod r für alle k <>1 ist. //sonst r+1 testen 42 Prozedur HaupttestAnna HaupttestAnna:=proc(n,r) begin a:=1; Schranke:=trunc(sqrt(numlib::phi(r))*log(2,n)*2); zuEnde:=FALSE; while not zuEnde and (a<=Schranke) do q:=poly(x+a,[x],IntMod(n)); VergleichsPolynom:=poly(x^(_mod(n,r))+_mod(a,n),[x],IntMod(n)); qhochn:=powermod(q,n,poly(x^r-1,[x],IntMod(n))); if (qhochn=VergleichsPolynom) then a:=a+1; else zuEnde:=TRUE end_if; end_while; HaupttestAnna():=(not zuEnde) end_proc //3.3.1. Schritt 5. Bestimmt für n>r, ob n prim oder n zusammengesetzt ist. //Laufvariable a im Polynom ((X+a)^n)(mod X^r-1,n). //Obere Schranke von a. //Abbruchbedingung der While-Schleife. //Initialisierung des Polynomfaktors (X+a). //Initialisierung des Vergleichspolynoms (X^n+a)mod(X^r-1,n). //Berechnet (X+a)^n im Ring mit wiederholtem Quadrieren. //Vergleich der beiden Polynome für ein a. //Bei Gleichheit weiter mit Vergleich für a+1. //Bei Nichtübereinstimmung Ende der While-Schleife,n keine Primzahl. //Wenn n zusammengesetzt ist, dann Rückgabe False sonst TRUE. 43