אלגוריתם מילר-רבין

אלגוריתם מילר-רבין (או 'רבין-מילר') Miller-Rabin, הוא אלגוריתם לבדיקת ראשוניות של מספר טבעי. הוא דומה למבחן פרמה לבדיקת ראשוניות אשר מבוסס על ההיפוך הלוגי של המשפט הקטן של פרמה, אך מרחיב אותו בצורה שמתגברת על מספרי קרמייקל - מקרי הקצה עבורם מבחן פרמה אינו עובד. הוכחת הנכונות של האלגוריתם דורשת את השערת רימן המוכללת. יש לאלגוריתם גרסה הסתברותית מהירה יחסית, שמזהה כל מספר ראשוני ככזה, אבל עשויה, בהסתברות נמוכה ככל שנרצה, להכריז כך גם על מספר פריק. גרסה זו, שפותחה על ידי פרופ' מיכאל רבין מן האוניברסיטה העברית, היא המבחן המקובל לבדיקת ראשוניות (תפקיד אותו מילא קודם מבחן סולוביי-שטרסן.) בהינתן מספר אי-זוגי שלם n > 2 {\displaystyle n>2} , ניתן לכתוב   n − 1 = 2 s r {\displaystyle \ n-1=2^{s}r} , כאשר s מספר טבעי ו-r מספר טבעי אי-זוגי. יהי a מספר שלם, כך ש a ו-n מספרים זרים. אם n ראשוני, אז המשפט הקטן של פרמה מבטיח ש-   a n − 1 ≡ 1 ( mod n ) {\displaystyle \ a^{n-1}\equiv 1{\pmod {n}}} . מכיוון שבחשבון מודולו מספר ראשוני יש ל-1 בדיוק שני שורשים ריבועיים,   ± 1 {\displaystyle \ \pm 1} , בהכרח מתקיים   a r ≡ 1 ( mod n ) {\displaystyle \ a^{r}\equiv 1{\pmod {n}}} , או ש-   a 2 j ⋅ r ≡ − 1 ( mod n ) {\displaystyle \ a^{2^{j}\cdot r}\equiv -1{\pmod {n}}} עבור   0 ≤ j ≤ s − 1 {\displaystyle \ 0\leq j\leq s-1} כלשהו. תנאי זה חייב להתקיים אם n ראשוני. סיבוכיות הבדיקה כ-   O ( log 3 ⁡ ( n ) ) {\displaystyle \ O(\log ^{3}(n))} פעולות. לצורך המבחן, בוחרים באקראי את הבסיס a, ובודקים את השוויוניים לעיל. אם הם אינם מתקיימים, n הוא מספר פריק. אם אחד מהם מתקיים, אז a הוא עד חזק לכך ש- n ראשוני (המונח עד משמש, בהקשר דומה, במבחן פרמה), אבל זו אינה הוכחה לראשוניות: קיימים מספרים פריקים שיש עדים חזקים לראשוניות שלהם. אפשר להוכיח שאם n פריק, אז לכל היותר רבע מבין המספרים הטבעיים עד n-1 עלולים להיות עדים חזקים לראשוניות של n. משום כך, אם בדיקה באמצעות t עדים אקראיים מודיעה שהמספר הנבדק ראשוני, הסיכוי לטעות באימוץ ההצהרה הוא לכל היותר   4 − t {\displaystyle \ 4^{-t}} . לצרכים מעשיים (למשל, הגרלת מספרים ראשוניים גדולים עבור אלגוריתמי הצפנה כגון RSA או שיטת רבין), מקובל להסתפק בבדיקה כזו ולא להפעיל אלגוריתמים דטרמיניסטיים לבדיקת ראשוניות, שהם איטיים בהרבה. להלן מימוש של האלגוריתם בשפת פייתון: from random import randrange def surely_composite(n, d, s, a): 'n-1 == 2**s * d' x = pow(a, d, n) # a^d mod n, efficiently if x == 1 or x == n - 1: return False for _ in range(s): x = pow(x, 2, n) if x == 1: return True if x == n - 1: return False return True def miller_rabin(n, number_of_rounds): (d, s) = n - 1, 0 while d % 2 == 0: (d, s) = (d//2, s+1) for round in range(number_of_rounds): if surely_composite(n, d, s, randrange(2, n - 1)): return "Composite" return "Probably Prime" נבדוק את המספר   n = 781 {\displaystyle \ n=781} , שעבורו   n − 1 = 2 2 ⋅ 195 {\displaystyle \ n-1=2^{2}\cdot 195} . בבדיקת הבסיס 5 מתברר ש-   5 195 ≡ 1 ( mod 781 ) {\displaystyle \ 5^{195}\equiv 1{\pmod {781}}} (שהרי   5 5 = 1 + 4 n {\displaystyle \ 5^{5}=1+4n} ). לכן 5 הוא עד חזק לראשוניות של 781. עבור הבסיס 17, מקבלים   17 195 ≡ − 1 ( mod 781 ) {\displaystyle \ 17^{195}\equiv -1{\pmod {781}}} , ולכן גם 17 הוא עד חזק. לעומת זאת, בדיקת הבסיס 2 נותנת   2 780 ≡ 243 {\displaystyle \ 2^{780}\equiv 243} , ומכאן ש- 781 אינו יכול להיות ראשוני. ואכן,   781 = 11 ⋅ 71 {\displaystyle \ 781=11\cdot 71} . תומאס ה. קורמן, צ'ארלס א. לייזרסון, רונאלד ל. ריבסט, מבוא לאלגוריתמים, הוצאת MIT, תורגם לעברית על ידי האוניברסיטה הפתוחה. אלגוריתם מילר-רבין, באתר MathWorld (באנגלית) R. Solovay, V. Strassen, A Fast Monte-Carlo Test for Primality, SIAM Journal on Computing 6, 1977-03-01, עמ' 84–85 doi: 10.1137/0206006