Der Miller-Rabin-Test ist eine Verschärfung des Fermat-Tests und dient ebenfalls der Bestimmung von Primzahlen (). Dieser hat allerdings im Vergleich zum Fermat-Test eine wesentlich höhere Trefferwahrscheinlichkeit in Bezug auf die Bestimmung von Primzahlen.
Beim Miller-Rabin-Test handelt es sich um einen probilistischen Primzahltest. Dies bedeutet, dass die Basis auf welcher die Exponentation durchgeführt wird zufällig innerhalb des Intervalls gewählt wird. Anders als beim Fermat-Test werden beim Miller-Rabin-Test mehrere Basen als sogenannte Zeugen verwendet.
Eine Basis gilt als Belastungszeuge für , wenn ist, aber und .
Die Begründung hierfür ist folgende:
Ist eine Primzahl, dann ist ein Körper. In einem mathematischen Körper hat jede quadratische Gleichung höchstens zwei unterschiedliche Lösungen. Nun hat aber in die quadratische Gleichung schon die beiden Lösungen und . Da vorausgesetzt werden kann, sind diese auch verschieden. Gibt es nun noch eine weitere Lösung, dann kann kein Körper sein. Dann kann auch keine Primzahl sein.
Beispiel:
Vermutete Primzahl
Ausgehend vom Satz von Fermat:
wird solange durch zwei dividiert bis ein ungerader Wert entsteht:
36 : 2 = 18
18 : 2 = 9
Diese Werte werden anschleißend in eine Tabelle eingetragen und die Berechnungen durchgeführt. Die Basis für die Exponentation liegt im Intervall .
5 | 6 | 36 | 1 |
12 | 1 | 1 | 1 |
15 | 31 | 36 | 1 |
Aus den 1-sen in der letzten Spalte kann nun geschlossen werden, dass es sich bei mit hoher Wahrscheinlichkeit um eine Primzahl handelt.
Mit Hilfe der Programmiersprache Python, kann der Miller-Rabin-Test wie folgt beschrieben werden:
from random import randint
def millerRabin(prim):
tmp = prim - 1
wPrim = True
i = 0
while i < 20:
basis = randNumber(tmp)
while tmp % 2 == 0:
if basis**tmp % prim == 1:
wPrim = True
break
else:
wPrim = False
tmp = tmp // 2
if not wPrim:
break
i += 1
if wPrim:
print("wahrscheinlich Primzahl.")
else:
print("Keine Primzahl.")
def randNumber(wert):
return randint(2, wert)
def isgerade(zahl):
if zahl == 2:
print("wahrscheinlich Primzahl.")
elif zahl % 2 == 0 and zahl > 2:
print("Keine Primzahl.")
else:
if millerRabin(zahl):
print("wahrscheinlich Primzahl.")
else:
print("Keine Primzahl")
if __name__ == '__main__':
prim = 561
isgerade(prim)
Im obigen Programm wird, anders als beim Fermat-Test, die 561 (Pseudoprimzahl) als nicht Primzahl durch den Miller-Rabin-Test erkannt. Um ein besseres Laufzeitverhalten zu gewährleisten, kann die Anzahl der Schleifendurchläufe und die Anzahl der zu testenden Basen reduziert werden. Dies geht allerdings auf Kosten der Treffergenauigkeit. Man sollte demzufolge eine gute Balance zwischen Treffergenauigkeit und Laufzeitverhalten finden.