Badanie pierwszości liczby, klasa NP i test Rabina Antoni Kościelski Piękno teorii matematycznej nie jest wystarczającym powodem nauczania jej w szkole. Liczby pierwsze pojawiały się w programach szkolnych przy okazji obliczania wartości wyrażeń wymiernych. Dzisiaj umiejętność ręcznego przeprowadzania rachunków ma już mniejsze znaczenie. Nie chciałbym teraz uzasadniać potrzeby uczenia o liczbach pierwszych. Chciałbym raczej zwrócić uwagę, że przyszli informatycy powinni znać pojęcie liczby pierwszej i byłoby bardzo dobrze, gdyby zetknęli się z nim dosyć wcześnie. Liczby pierwsze są dzisiaj potrzebne do zrozumienia wielu zagadnień o dużym znaczeniu praktycznym. Są m.in. powszechnie wykorzystywane w algorytmach pozwalających na szyfrowanie informacji, między innymi takich, od których zależy bezpieczeństwo internetowej bankowości. Co więcej, nie jest ostatecznie rozstrzygnięte, czy wykorzystywane metody szyfrowania zapewniają poufność przesyłanych informacji. Dzisiaj stosujemy metody, o których tylko to przypuszczamy, a twierdzenia o własnościach stosowanych algorytmów czekają nadal na swoich odkrywców. Klasyczne testy pierwszości Informatycy rozważają kilka zadań związanych z liczbami pierwszymi. Po pierwsze, zajmują się samym problemem pierwszości. Słowo problem powinno tu kojarzyć się z pewnym pytaniem, w tym przypadku z pytaniem, czy dana liczba jest pierwsza. Zwykle problemy są utożsamiane ze zbiorami tych danych, dla których odpowiedź jest pozytywna. Tak więc problem pierwszości bywa utożsamiany ze zbiorem liczb pierwszych (lub przedstawień liczb pierwszych). Drugim ważnym problemem jest problem złożoności. Odpowiada on zbiorowi liczb złożonych. Te problemy nie różnią się istotnie, gdy posługujemy się zwykłymi algorytmami. Wtedy, rozwiązując jeden z nich, jednocześnie rozwiązujemy także drugi. Mogą zacząć się różnić, gdy zajmiemy się algorytmami niedeterministycznymi lub wszelkiego rodzaju algorytmami losowymi. Interesujące jest również zadanie znajdowania dzielnika danej liczby. Różni się od problemu złożoności. Aby je rozwiązać nie wystarczy ustalić, czy dana liczba jest złożona. Trzeba także wskazać jeden z właściwych dzielników tej liczby lub stwierdzić, że taki dzielnik nie istnieje. Algorytmy znajdowania dzielnika pozwalają rozwiązać niewielkim dodatkowym kosztem zadanie faktoryzacji, czyli znajdowania przedstawienia danej liczby w postaci iloczynu liczb pierwszych. Naturalne algorytmy badające, czy dana liczba jest pierwsza, są wykładnicze. Łatwo się o tym przekonać dla najprostszego algorytmu, wynikającego z definicji liczby pierwszej i sprawdzającego podzielność się przez wszystkie liczby mniejsze. Jeżeli dodatnia liczba naturalna ma przedstawienie dziesiętne złożone z n cyfr, to jest równa przynajmniej 10n-1 i badanie, czy jest to liczba pierwsza, wymaga – zgodnie z najpopularniejszą definicją – wykonania 10n-1-2 dzieleń. Liczba dzieleń wykonywanych podczas takiego sprawdzania pierwszości jest więc wykładnicza w stosunku do długości przedstawienia badanej liczby, czyli rozmiaru liczby. Wiadomo, że nie trzeba wykonywać wszystkich dzieleń, ale po zoptymalizowaniu algorytm i tak pozostanie wykładniczy. Nietrudno też się przekonać, że algorytm ten wykorzystuje pamięć zaledwie kilka razy większą od potrzebnej do zapisania danej liczby. Sito Eratostenesa, opisane w artykule Jana Ulmana, jest jeszcze gorszym algorytmem. Nie tylko wykonuje wykładniczą liczbę operacji, ale również korzysta z wykładniczej pamięci. Innym algorytmem badającym pierwszość, dość prostym do zaprogramowania, jest tzw. test Wilsona. Polega on na obliczaniu reszty z dzielenia (m-1)! przez m. Znając tę resztę bez trudu można odpowiedzieć na pytanie, czy liczba m jest pierwsza. Dla złożonych liczb m > 4 ta reszta jest równa 0. Jeżeli zaś m jest liczbą pierwszą, to czynniki iloczynu 1 2 3 (m 2) (m 1) można grupować w pary złożone z liczb a i b takich, że ab przystaje do 1 modulo m (dla każdej dodatniej liczby a<m taka liczba b<m istnieje, ponieważ a jest względnie pierwsze z m, a największy wspólny dzielnik a i m (czyli 1) można przedstawić w postaci 1 = ab+mn). Podczas liczenia reszty z dzielenia tego iloczynu, po pogrupowaniu, większość czynników powinna się więc uprościć. W dwóch przypadkach jednak liczby a nie ma z czym grupować, gdyż a równa się b. Tak jest dla a=1 oraz a=m-1. Okazuje się więc, że dla każdej liczby pierwszej m liczba (m-1)! przystaje do m-1 (albo do -1) modulo m. Nietrudno zauważyć, że test Wilsona też jest algorytmem wykładniczym. Dla liczb o n cyfrowym przedstawieniu wymaga obliczenia iloczynu 10n-1-2 czynników. Dla matematyków złożoność obliczeniowa testów nie była pierwszoplanowym zagadnieniem. Teoria złożoności obliczeniowej zaczęła się rozwijać dopiero około 1960 roku, a informatycy dość długo nie potrafili powiedzieć niczego interesującego o testowaniu pierwszości. Dopiero w 1975 roku Vaughan Robert Pratt pokazał, że problem pierwszości należy do klasy NP. Klasa NP Symbolem NP oznaczamy klasę problemów rozwiązywanych w sposób niedeterministyczny w czasie wielomianowym. Aby przybliżyć to pojęcie, posłużymy się problemem, czy dana liczba jest złożona (czyli problemem złożoności). Najprostszy algorytm rozwiązujący ten problem przegląda wszystkie liczby mniejsze od danej liczby m i szuka dzielnika. Dzielnika można jednak szukać na wiele sposobów. Na przykład, można go szukać badając liczby od najmniejszej do największej d:= 2; while (d nie_dzieli m) do d:=d+1; if d<>m then write(’Dana liczba jest złożona.’) albo odwrotnie, przeglądając liczby od największej do najmniejszej, zgodnie z algorytmem d:= m-1; while (d nie_dzieli m) do d:=d-1; if d<>1 then write(’Dana liczba jest złożona.’) Przypuśćmy, że liczba m jest parzysta. Te dwa algorytmy, mimo że są bardzo podobne, różnią się istotnie. Pierwszy zakończy pracę po jednorazowym sprawdzeniu podzielności. Drugi – najpierw będzie testować bez powodzenia wszystkie liczby między m-1 i m/2+1. Zanim znajdzie dzielnik wykona wykładniczo wiele testów podzielności. Mając więc trochę szczęścia, możemy błyskawicznie sprawdzić, czy dana liczba jest złożona. Pechowcy, którzy źle wybrali sposób szukania dzielnika, długo będą czekać na wynik obliczeń. Zdarza się więc, że badanie złożoności liczby trwa bardzo długo, ale można też mieć nadzieję, że dobierając odpowiednio algorytm obliczenia da się przeprowadzić krótkim czasie. Informatycy – mówiąc o takich algorytmach – dzielnik nazywają ,,certyfikatem złożoności’’, czyli informacją zaświadczającą o złożoności danej liczby. Wszystkie problemy z klasy NP są podobne do problemu, czy dana liczba jest złożona. Ich rozwiązanie polega na przeszukaniu dość dużego zbioru, o wykładniczej w stosunku do rozmiaru danych liczności, w poszukiwaniu tzw. certyfikatu. Jeżeli certyfikat zostanie znaleziony, to zapoznanie się z nim i sprawdzenie jego poprawności powinno być łatwe, czyli możliwe do wykonania w czasie wielomianowym. Formalna definicja klasy NP wymaga przypomnienia pojęcia rozmiaru. Dla liczby naturalnej m rozmiar r(m) to liczba znaków potrzebna do zapisania przedstawienia tej liczby. Z dokładnością do stałego czynnika i w przybliżeniu jest to log2m. Informatycy pojęcie rozmiaru uogólniają na dowolne informacje. Problem A należy do klasy NP, jeżeli istnieje wielomian w(x) i wielomianowy1 problem B taki, że m A k r k wr m m, k B. Zwykły, znany wszystkim algorytm dzielenia liczb, a także oparty o ten algorytm test podzielności, są wielomianowe. Dzielnik liczby, czyli certyfikat złożoności, ma rozmiar nie przekraczający rozmiaru tej liczby. Zgodnie z podaną definicją, problem złożoności należy do klasy NP. Natomiast zadanie znalezienia dzielnika nie należy do klasy NP z przyczyn formalnych. Zadanie to nie jest problemem, rozwiązując je oczekujemy bardziej skomplikowanej informacji niż tak lub nie. Użycie kwantyfikatora egzystencjalnego w definicji NP powoduje, że trudno sobie wyobrazić dowód zamkniętości klasy NP ze względu na dopełnienie (negację). Tym niemniej dopełnienie problemu złożoności, czyli problem pierwszości – jak to zauważył Pratt – także należy do klasy NP. Pytanie, czy P=NP, i badanie złożoności liczby Jednym z głównych otwartych problemów informatyki jest pytanie, czy klasa problemów wielomianowych P jest równa klasie NP. Oczywiście, problemy wielomianowe należą do klasy NP. Aby więc odpowiedzieć na to pytanie pozytywnie, należałoby wykazać, że każde zadanie z klasy NP można rozwiązać za pomocą algorytmu wielomianowego. Mówiąc intuicyjnie, aby dowieść, że P=NP, wystarczy wymyślić taką metodę przeszukiwania danych, aby zadania dające się szybko rozwiązać przy odrobinie szczęścia mogli sprawnie rozwiązywać także najwięksi pechowcy. Informatycy wiedzą, że w tym celu nie trzeba badać wszystkich zadań. Wystarczy za pomocą algorytmu wielomianowego rozwiązać jeden, dostatecznie trudny problem z klasy NP. Większość informatyków jest jednak przekonana, że klasy P i NP są różne. 1 Być może przypomnienia wymaga też pojęcie problemu wielomianowego. Tak nazywamy problem, który można rozwiązać za pomocą algorytmu wielomianowego, a więc wykonującego dla pewnego wielomianu w i dla każdej z danych rozmiaru n najwyżej w(n) czynności elementarnych. Pojęcie czynności elementarnej jest dokładnie definiowane, ale może być rozumiane intuicyjnie jako bardzo prosta czynność wykonywana podczas realizacji algorytmu. Problem B w przytoczonej definicji NP wymaga pary liczb jako danej. Rozmiar takiej pary to suma rozmiaru jej współrzędnych. Spróbujmy znowu zająć się naszym przykładem: problemem złożoności. Aby pokazać, że jest to problem wielomianowy można spróbować opracować metodę, która pozwoli znajdować wśród liczb < m dzielnik liczby m i będzie wykonywać wielomianową w porównaniu z log2 m liczbę elementarnych czynności. Gdyby taką metodą udało się znaleźć – i co najważniejsze – gdyby była ona dostatecznie ogólna i dawałaby się zastosować także w innych przypadkach, to klasy P i NP byłyby równe. Jest to mało prawdopodobne i chyba w ten sposób problemu złożoności nie da się rozwiązać. Znalezienie szczególnej, wielomianowej metody służącej do szukania dzielnika mogłoby nie wystarczyć do wykazania, że P=NP. Pytanie o istnienie takiej metody też nie jest jeszcze rozwiązane. Także w tym przypadku informatycy są przekonani, że taka metoda nie istnieje. Jest to bardzo ważne pytanie, gdyż od odpowiedzi na nie zależy bezpieczeństwo danych przesyłanych za pomocą sieci komputerowych. Zanim poznamy odpowiedź na pytanie, czy problem złożoności jest wielomianowy, wróćmy na chwilę do historycznie wcześniejszych badań Pratta. Przy okazji jeszcze raz zobaczymy, jak można wykazać, że jakiś problem należy do klasy NP. Twierdzenie Pratta W dowodzie swojego twierdzenia Pratt korzystał z tzw. testu Lucasa. Jego poprawność wynika łatwo z istnienia pierwiastków pierwotnych. Aby zaś wyjaśnić pojęcie pierwiastków pierwotnych musimy przypomnieć sobie małe Twierdzenie Fermata. Jeżeli m jest liczbą pierwszą, to dla dowolnej dodatniej liczby a < m liczba am-1 przystaje do 1 modulo m. Fakt ten można również wyrazić nieco inaczej: w ciele Zm reszt z dzielenia przez liczbę pierwszą m, z dodawaniem i mnożeniem modulo m, wszystkie niezerowe elementy są pierwiastkami z jedności stopnia m-1. Wśród m-1 pierwiastków z jedności stopnia m-1 jest też pierwiastek pierwotny, czyli taki, który nie jest jednocześnie pierwiastkiem stopnia mniejszego niż m-1. Czasem nazywa się go krótko pierwiastkiem pierwotnym modulo m (lub dla modułu m). Zachodzi też Twierdzenie 2. Liczba naturalna m jest pierwsza wtedy i tylko wtedy, gdy w Zm istnieje pierwiastek pierwotny modulo m. Tak więc istnienie pierwiastków pierwotnych nie tylko wynika z pierwszości liczby, ale też charakteryzuje liczby pierwsze. Fakt ten jest wykorzystywany w teście Lucasa, zgodnie z którym po prostu szukamy pierwiastka pierwotnego modulo dana liczba. Natomiast badanie, czy a jest pierwiastkiem pierwotnym modulo m, polega – zgodnie z tym testem – na sprawdzeniu 1. czy am-1 przystaje do 1 modulo m oraz 2. czy a(m-1)/q nie przystaje do 1 modulo m dla każdej liczby pierwszej q dzielącej m-1. Test Lucasa sugeruje, że certyfikatem pierwszości liczby m może być informacja złożona z pierwiastka pierwotnego a modulo m i wszystkich dzielników pierwszych liczby m-1. Rzeczywiście, mając a i dzielniki pierwsze m-1 łatwo sprawdzić większość warunków z testu Lucasa. Nie jest to jednak dobre rozwiązanie, gdyż sprawdzenie poprawności certyfikatu powinno obejmować także badanie pierwszości wymienionych dzielników. Liczbę a wraz z wszystkimi dzielnikami pierwszymi d1,…,dt liczby m-1 będziemy nazywać niepełnym certyfikatem i będziemy zapisywać jako (a,d1,…,dt). Pratt dodatkowo zauważył, że jeżeli niepełny certyfikat pierwszości uzupełnimy o niepełne certyfikaty pierwszości wymienionych w nim liczb pierwszych, a także o niepełne certyfikaty pierwszości liczb pierwszych w dołączonych certyfikatach itd., to otrzymamy informację, której rozmiar jest tylko kwadratowy w porównaniu z rozmiarem danej liczby. Otrzymana w ten sposób informacja nie jest duża, może więc być certyfikatem pierwszości liczby m. Na przykład certyfikatem pierwszości liczby 23 może być informacja (5,2,11(2,2,5(3,2))), którą powinniśmy rozumieć jako stwierdzenie, że liczba 23 jest pierwsza, ponieważ 5 jest pierwiastkiem pierwotnym modulo 23, a 22 dzieli się tylko przez 2 (które jest oczywiście liczbą pierwszą i stwierdzenie tego faktu nie wymaga już żadnego certyfikatu) oraz przez 11. Liczba 11 jest pierwsza, gdyż 2 jest świadczącym o tym pierwiastkiem pierwotnym, a 10 dzieli się tylko przez dwie liczby pierwsze 2 i 5. W końcu 5 jest liczbą pierwszą, gdyż 3 jest pierwiastkiem pierwotnym modulo 5, a 4 dzieli się tylko przez liczbę pierwszą 2. Mając tak rozumiany certyfikat bez trudu, zgodnie z testem Lucasa, przeprowadzamy obliczenia dowodzące kolejno pierwszości liczb 5, 11 i w końcu liczby 23. W ogólnym przypadku potrzebne do tego obliczenia są wielomianowe. Współczesne testy pierwszości Po ogłoszeniu wyniku Pratta było wiadomo, że zarówno problem pierwszości, jaki i jego dopełnienie, czyli problem złożoności, są w klasie NP. Zdaniem wielu badaczy wskazywało to na istnienie wielomianowego algorytmu badającego pierwszość. Ważnym argumentem był też test pierwszości podany przez Gary Millera w 1976 roku. Miller przedstawił także dowód wielomianowości swojego testu, przeprowadzony jednak przy założeniu rozszerzonej hipotezy Reimanna, której prawdziwość nie jest rozstrzygnięta. W tej sytuacji trudno się dziwić, że matematycy i informatycy rozpoczęli poszukiwania efektywnych algorytmów. W 1983 roku Leonard Adleman, Carl Pomerance i Robert Rumeley podali pierwszy deterministyczny test pierwszości, który nie jest wykładniczy2, ale też nie jest jeszcze wielomianowy. Opracowano również wiele innych testów, często z elementami losowymi. Dzisiaj wynik Pratta ma już tylko historyczne znaczenie. W 2002 roku matematyk hinduski Manindra Agraval oraz jego uczniowie Neeraj Kayal i Nitin Saxena podali deterministyczny i wielomianowy test pierwszości. Jak to bywa często w teorii liczb, mimo że długo szukano takiego testu, dowód jego poprawności nie jest trudny. Może go zrozumieć student matematyki po wysłuchaniu kursowych wykładów z teorii ciał skończonych. Test jest oparty o następującą charakteryzację liczb pierwszych: Twierdzenie 3. Przyjmijmy, że liczby naturalne m i a<m są względnie pierwsze. Liczba m jest pierwsza wtedy i tylko wtedy, gdy wielomian (x-a)m o współczynnikach z pierścienia reszt modulo m jest równy wielomianowi xm-a. 2 Taka uwaga wymaga od autora dużej wiedzy historycznej. Przytaczam ją na podstawie pracy PRIMES is in P autorstwa Manindra Agravala i jego studentów, relacjonowanej w dalszej części artykułu. Z tej pracy pochodzi także kilka innych przytoczonych przeze mnie szczegółów historycznych. Przypuszczam, że wielu Czytelników Matematyki jest w stanie samodzielnie zweryfikować przytoczone twierdzenie3. Więcej kłopotów autorom testu sprawiła jego wielomianowość. Pokazali ostatecznie, że dla liczb o rozmiarze n ich algorytm wykonuje najwyżej c n12 operacji dla pewnej stałej c, a jeżeli są prawdziwe pewne hipotezy, to realizacja algorytmu może wymagać wykonania tylko c n 6 operacji. Z pracy Agravala wynika także, że problem złożoności jest wielomianowy. Nie wiem, czy test Agravala ma znaczenie praktyczne. Zdarza się, że algorytmy wielomianowe gorzej spisują się dla danych mających znaczenie praktyczne od algorytmów wykładniczych. Deterministyczne algorytmy mają też dodatkową konkurencję ze strony algorytmów probabilistycznych. Posługiwanie się algorytmami probabilistycznymi wymaga istotnej, wręcz rewolucyjnej zmiany sposobu myślenia. Rozwiązując zadanie zwykle chcemy uzyskać jednoznaczną odpowiedź: tak lub nie. W przypadku algorytmów probabilistycznych otrzymujemy też informację: najprawdopodobniej tak. Takie algorytmy często okazują się bardzo efektywne, ale ceną jest możliwość popełnienia błędu. Są znane także dla interesującego nas zadania. Jeden z najwcześniejszych i najbardziej znanych probabilistycznych testów, rozwiązujący problem pierwszości, o olbrzymim znaczeniu praktycznym został zaproponowany przez Michaela Rabina w 1980 roku. Sylwetka Michaela Rabina Michael Oser Rabin jest głównym bohaterem tego artykułu i jednym z najwybitniejszych współczesnych informatyków. Urodził się w 1931 roku we Wrocławiu. Przed drugą wojną światową znalazł się w Palestynie. W 1953 roku ukończył studia matematyczne na Uniwersytecie Hebrajskim w Jerozolimie. Odgrywa ciągle istotną rolę w rozwoju informatyki. Brał udział w tworzeniu teorii złożoności obliczeniowej. Był pierwszym uczonym, który zwracał uwagę na znaczenie niedeterminizmu i odegrał pewną rolę w ukształtowaniu takiego pojęcia, jak klasa NP. Został za to uhonorowany w 1976 roku razem z Dana Scottem nagrodą Turinga, która dla informatyków jest odpowiednikiem medalu Fieldsa przyznawanego za największe osiągnięcia matematyczne lub nagrody Nobla za wyniki z fizyki, chemii i innych dziedzin. Szczególnie znaczące osiągnięcia ma w kryptografii. Opracował system szyfrujący, pierwszy tego rodzaju, o którym wiadomo, jak trudno rozszyfrowywać tworzone przez niego komunikaty. W tym systemie rozszyfrowywanie komunikatów jest tak samo trudne, jak rozkładanie liczby na czynniki pierwsze. W praktyce stosowany jest system szyfrujący RSA oparty o metodę zaproponowaną przez Ronalda Rivesta, Adi Shamira i Leonarda Adlemana, którego komunikaty też można odczytywać mając efektywny algorytm rozwiązujący zadanie faktoryzacji. Jednak nie wiadomo, czy nie można ich odczytywać jeszcze w inny sposób. Jest doktorem honoris causa wielu znaczących uniwersytetów. Z inicjatywy prof. Leszka Pacholskiego, rektora Uniwersytetu Wrocławskiego i długoletniego dyrektora Instytutu 3 Jako wskazówkę przytoczę następujący fakt: jeżeli q jest liczbą występującą k krotnie w rozkładzie liczby m na iloczyn liczb pierwszych, to liczba qk nie dzieli m . q Informatyki, także Senat Uniwersytetu Wrocławskiego podjął uchwałę o nadaniu Michaelowi Rabinowi doktoratu honorowego. Uroczystość promocji honorowej odbyła się13 lipca 2007 roku w Auli Leopoldyńskiej Uniwersytetu Wrocławskiego w obecności uczestników międzynarodowych konferencji informatycznych: 34th Intenational Colloquium on Automata, Languages and Programming oraz 22th Symposium on Logic in Computer Science, a także matematycznej konferencji Logic Colloquium. Podczas uroczystości w auli byli obecni uczeni z całego świata, w tym Dana Scott, aktualny przewodniczący komitetu nagrody Turinga i współautor nagrodzonej pracy o niedeterminizmie i automatach skończonych, a także ambasador Izraela i najbliższa rodzina Michaela Rabina. Szukając informacji o wynikach Michaela Rabina przejrzałem ksiązki z informatyki teoretycznej, które mam w domu. We wszystkich były cytowane jego prace. W większości o osiągnięciach Profesora można było czytać w kilku lub nawet w kilkunastu miejscach. Teraz sygnalizowałem tylko osiągnięcia związane z treścią artykułu. Interesuje nas jeszcze probabilistyczny test pierwszości. Probabilistyczny test Rabina Aby lepiej zrozumieć test Rabina zacznijmy od testu Fermata, stosowanego od dawna przez matematyków, ale uważanego za narzędzie pomocnicze. Jest on oparty o małe twierdzenie Fermata. W twierdzeniu Fermata prawdziwa jest nie tylko podana implikacja, ale także implikacja odwrotna. Twierdzenie uzupełnione o tę implikację stanie się charakteryzacją liczb pierwszych i może być podstawą algorytmu testującego pierwszość. Algorytm ten powinien badać wszystkie liczby mniejsze niż m i będzie wykładniczy. Dla każdej liczby a < m sprawdzi, czy am-1 przystaje do 1 modulo m. Jeżeli przeprowadzenie obliczeń dla wszystkich liczb mniejszych od m okaże się zbyt żmudne, to zawsze można przeprowadzić je dla kilku wybranych wartości a i spróbować stąd wyciągnąć wnioski. Jeżeli dla chociaż jednej liczby okaże się, ze am-1 nie przystaje do 1 modulo m, to liczba m będzie złożona. Jeżeli we wszystkich sprawdzonych przypadkach am-1 przystaje do 1 modulo m, to jest jakaś szansa, że m jest liczbą pierwszą. Informatycy uznali, że tę szansę należy zbadać. W tym celu rozważymy następujący algorytm – test Fermata: dla danej liczby m 1. wylosuj dodatnią liczbę a < m i sprawdź, czy am-1 przystaje do 1 modulo m, 2. jeżeli tak jest, to przekaż, że m jest prawdopodobnie liczbą pierwszą, a w przeciwnym razie – stwierdź, że m jest liczbą złożoną. Podany algorytm udziela odpowiedzi, która zależy od wylosowanej liczby. Nie myli się nigdy, gdy stwierdza, że dana liczba jest złożona, i może popełnić błąd, który polega na przekazaniu o liczbie złożonej informacji, że jest prawdopodobnie pierwsza. Od algorytmu probabilistycznego, takiego jak przedstawiony, oczekujemy, że niezależnie od danej robi błąd z prawdopodobieństwem nie przekraczającym pewnej stałej c<1. Algorytmy spełniające ten warunek określamy mianem Monte Carlo. Mając taki algorytm, można konstruować efektywne algorytmy probabilistyczne. Wystarczy go dla danej liczby m wielokrotnie powtarzać. Prawdopodobieństwo popełnienia błędu podczas k kolejnych i niezależnych powtórzeń algorytmu Monte Carlo nie przekracza liczby ck. Dobierając odpowiednio liczbę powtórzeń możemy uzyskać algorytm popełniający błąd z zadanym prawdopodobieństwem, także niemal równym zero. Przypuśćmy, że test Fermata uruchamiamy z liczbą złożoną m, a więc w sytuacji, gdy może popełnić błąd. Jeżeli zostanie wylosowana liczba a, która ma wspólny dzielnik z m, to otrzymamy poprawną odpowiedź. Gdyby bowiem algorytm przekazał błędną odpowiedź, to potęga am-1 przystawałaby do 1 modulo m i wspólny dzielnik liczb a i m dzieliłby także 1. Błędna odpowiedź może się pojawić wyłącznie po wylosowaniu liczby względnie pierwszej z m. Będziemy teraz przez chwilę rozważać liczbę m będącą iloczynem4 trzech różnych liczb pierwszych p, q i r. Nietrudno przekonać się, że jest (p-1)(q-1)(r-1) liczb mniejszych od m i względnie pierwszych z m. Wobec tego prawdopodobieństwo popełnienia błędu przez nasz ( p 1)(q 1)(r 1) algorytm jest nie większe niż . Zauważmy, że jeżeli będziemy zwiększać pqr 1 liczby p, q i r, to znalezione oszacowanie będzie zbliżać się do 1. Co gorsze, w niektórych przypadkach prawdopodobieństwo popełnienia błędu jest takie, jak znalezione oszacowanie. Są liczby złożone m, dla których teza małego twierdzenia Fermata jest spełniona dla wszelkich liczb względnie pierwszych z m i podany algorytm zawsze po wylosowaniu liczby względnie pierwszej z m udzieli błędnej odpowiedzi. Nazywamy je liczbami Carmichaela, a najmniejszą taką liczbą jest 561. Wskazuje to, że test Fermata nie jest algorytmem Monte Carlo. Aby otrzymać dobrą charakteryzację liczb pierwszych, pozwalającą na skonstruowanie algorytmu Monte Carlo, tezę twierdzenia Fermata trzeba uzupełnić o dodatkowe informacje o liczbach pierwszych. Gary Miller w swoim algorytmie korzystał z następującego faktu: Twierdzenie 4. Jeżeli m jest liczbą pierwszą, to każda liczba x, której kwadrat przystaje do 1, przystaje modulo m albo do 1, albo do -1. Jest to znany fakt. Reszty z dzielenia przez liczbę pierwszą tworzą ciało, a w każdym ciele równanie x2=1 ma dwa pierwiastki: 1 i -1. Teza twierdzenia 4 zachodzi dla wielu liczb m, nie tylko dla pierwszych. Nie zachodzi jednak dla liczb, które można przedstawić w postaci iloczynu pq względnie pierwszych liczb p i q większych od 2. Tezę tego twierdzenia poza liczbami pierwszymi spełniają więc najwyżej liczby parzyste oraz potęgi liczb pierwszych. Te dwa rodzaje liczb nie są jednak liczbami Carmichaela. Spostrzeżenie to pozwala dowieść Twierdzenie 5. Jeżeli 1. dla każdej dodatniej liczby a < m i względnie pierwszej z m potęga am-1 przystaje do 1 modulo m oraz 2. x2 przystaje do 1 modulo m tylko dla liczb x przystających do 1 i do -1 modulo m, to m jest liczbą pierwszą. 4 Liczby Carmichaela, które w tej chwili zaczynamy analizować, są iloczynami przynajmniej trzech różnych liczb pierwszych. O niektórych własności tych liczb dowiemy z dalszych rozważań. Twierdzenie 5 dla wygody połączymy z twierdzeniem Fermata i twierdzeniem 4 oraz sformułujemy używając odpowiedniejszej terminologii. Liczbę m najpierw przedstawmy w postaci m=2kn+1 dla pewnej nieparzystej liczby n. O liczbie a będziemy mówić, że świadczy o pierwszości m, jeżeli albo an przystaje do 1 modulo i m, albo a 2 n przystaje do -1 modulo m dla pewnej liczby naturalnej i k . Wprowadzone pojęcie pozwala w następujący sposób podsumować przeprowadzone rozumowania. Twierdzenie 6. Liczba m jest pierwsza wtedy i tylko wtedy, gdy każda dodatnia liczba a m świadczy o pierwszości m. Twierdzenie 6 jest podstawą algorytmu Gary Millera. Michael Rabin, propagujący przy każdej okazji algorytmy probabilistyczne, zaproponował także w oparciu o nie następujący test pierwszości liczby m: 1. wylosuj dodatnią liczbę naturalną a < m i sprawdź, czy a świadczy o pierwszości m, 2. jeżeli świadczy, to przekaż, że m jest prawdopodobnie liczbą pierwszą, w przeciwnym razie przekaż, że m jest liczbą złożoną. O teście Rabina stosunkowo łatwo dowodzi się, że popełnia błąd najwyżej z prawdopodobieństwem ½. Aby się o tym przekonać, musimy przeanalizować działanie tego testu dla złożonych liczb m. Niech G x m : x m1 1 mod m oraz Z m x m : x jest wzglednie pierwsze z m. Oczywiście G jest podzbiorem Z m . Oba te zbiory są zamknięte ze względu na mnożenie modulo m i są grupami z tym działaniem. Tak więc, zgodnie z twierdzeniem Lagrange’a, liczba elementów G dzieli rząd Z m . Nietrudno też zauważyć, że zarówno w przypadku testu Fermata, jak i testu Rabina, wszystkie liczby a generujące błędne odpowiedzi należą do G. Jeżeli m nie jest liczbą Carmichaela, to G Z m i liczba elementów Z m jest przynajmniej dwa razy większa od liczby elementów G. Poprawne odpowiedzi otrzymamy więc po wylosowaniu liczby a, która nie jest względnie pierwsza z m i dla przynajmniej połowy pozostałych liczb. Tak więc prawdopodobieństwo popełnienia błędu w tym przypadku jest 1 . 2 Jeżeli m jest liczbą Carmichaela, to co prawda G Z m , ale sytuacja jest podobna. Nieco subtelniejsze, analogiczne rozumowanie pozwala oszacować prawdopodobieństwo błędu. Liczba m jest wtedy nieparzysta i można ją przedstawić w postaci 2k+1n+1 dla pewnej liczby nieparzystej n. Jeżeli teraz przyjmiemy, że Gi x m : x 2 n 1 mod m , to będziemy mogli inaczej zapisać definicję G. Oczywiście dla i=k+1 zachodzi równość Gi G . Może się jednak zdarzyć, ze równość ta jest też prawdziwa dla innych i. Przyjmijmy, że l jest najmniejszą liczbą taką, że Gl G . Ponieważ m-1 nie należy do G0, więc l > 0. i l 1 Liczby a powodujące błędy testu Rabina należą do zbioru G' x m : x 2 n 1 mod m . Zbiór ten też jest zamknięty ze względu na mnożenie modulo m, a więc jest podgrupą Z m . Można dowieść, że jest właściwą podgrupą. Dalsze szacowanie prawdopodobieństwa błędu przebiega tak, jak w poprzednim przypadku. A więc zarówno dla liczb Carmichaela, jak i pozostałych, prawdopodobieństwo popełnienia błędu przez test Rabina nie przekracza ½. Test Rabina jest więc probabilistycznym algorytmem Monte Carlo i pozwala konstruować efektywne algorytmy, które można wykorzystać zarówno do badania złożoności liczby, jak i sprawdzania, czy dana liczba jest pierwsza. Michael Rabin zauważył jeszcze, że jeżeli m jest liczbą złożoną, to nie połowa jak pokazaliśmy, a najwyżej jedna czwarta liczb mniejszych niż m świadczy o pierwszości m. Test Rabina popełnia więc błąd z prawdopodobieństwem nie przekraczającym ¼. Jeżeli będziemy go niezależnie powtarzać, a po t krotnym powtórzeniu popełni już błąd z prawdopodobieństwem nie przekraczającym 1/4t. Jest to bardzo prosty algorytm. Od studenta pierwszego roku informatyki, uczącego się programowania, oczekiwałbym, że w ciągu kilku tygodni przygotuje oparty o naturalne algorytmy5 program realizujący test Rabina i pozwalający eksperymentować z badaniem pierwszości liczb o długich przedstawieniach. Sądzę, że taki projekt mogłaby zrealizować pod kierunkiem nauczyciela także grupa uczniów uczestniczących na przykład w zajęciach pozalekcyjnych z informatyki. Uzupełnienia. Dla Czytelników zainteresowanych bardziej szczegółowymi dowodami przedstawię na koniec rozumowania świadczące o prawdziwości kilku faktów użytych w artykule. Żadna liczba parzysta m > 2 nie jest liczbą Carmichaela. Aby się o tym przekonać, wystarczy zauważyć, że (m-1)m-1 przystaje do -1 modulo m. Liczbę przystającą do -1 podnosimy przecież do nieparzystej potęgi. Trudniej uzasadnić, że potęga m=pk liczby pierwszej p nie jest liczbą Carmichaela. Tak jest, gdyż dla k > 1 mamy p p p ( p k 1 1) p p ( k 1)i p k 1 1 1 mod p k . i 2 i 1 Gdyby m było liczbą Carmichaela, to także ( p k 1 1) p k 1 1 mod p k i ze względnej pierwszości wykładników w powyższych wzorach otrzymalibyśmy, że p k 1 1 przystaje do 1 modulo pk. To oznaczałoby, że pk dzieli pk-1, co nie jest możliwe. Jeżeli p i q są względnie pierwszymi liczbami większymi od 2 i m=pq, to istnieją przynajmniej trzy dodatnie liczby x < m, których kwadraty przystają do 1 modulo m. Zawsze do 1 przystają modulo m kwadraty liczb 1 oraz m-1. Kolejną taką liczbę można skonstruować w następujący sposób: najpierw przedstawiamy największy wspólny dzielnik p i q (czyli 1) w postaci 1=ap+bq i bierzemy liczbę x przystającą do (p-1)bq+ap modulo m. Liczba x przystaje do -1 modulo p oraz do 1 modulo q. Stąd x2 5 Trzeba pamiętać, że algorytm potęgowania oparty o zwykłą definicję jest wykładniczy. Potęgę można jednak obliczać za pomocą łatwego do zrozumienia i dość naturalnego wielomianowego algorytmu. przystaje do 1 modulo pq. Liczba x nie przystaje jednak do 1 modulo pq. W przeciwnym razie, przystawałaby modulo p jednocześnie do 1 i do -1, a to jest możliwe wyłącznie dla p=2. Analogicznie, analizując przystawanie modulo q, pokazujemy, że x nie przystaje do -1 (ani m-1) modulo pq. Nadal niech m będzie iloczynem względnie pierwszych i nieparzystych liczb p i q. Ponieważ – zgodnie z wcześniejszymi oznaczeniami – Gl-1 jest różne od G, więc dla t 2 l 1 n istnieje względnie pierwsza z m liczba x taka, że xt nie przystaje do 1 modulo m. Wtedy istnieje też względnie pierwsza z m liczba y taka, że yt nie przystaje modulo m ani do 1, ani do -1. Liczba ta nie należy G ' , mimo że należy do G. Jeżeli xt nie przystaje do 1 modulo m, to także nie przystaje do 1 albo modulo p, albo modulo q. W obu przypadkach postępujemy analogicznie. Załóżmy więc, że xt nie przystaje do 1 modulo p. Znajdźmy znowu przedstawienie największego wspólnego dzielnika p i q (czyli 1) w postaci ap+bq i przyjmijmy, że y jest resztą z dzielenia xbq+ap przez m. Liczba y przystaje do x modulo p oraz do 1 modulo q. Wynika stąd, że jest względnie pierwsza zarówno z p, jak i z q. Jest więc względnie pierwsza z m. Potęga yt nie przystaje ani do 1, ani do -1 modulo m. Nie przystaje do 1, ponieważ y przystaje do x modulo p. Gdyby zaś przystawała do -1 modulo m, to także przystawałaby -1 modulo q. Nie może jednak przystawać modulo m jednocześnie do 1 i do -1 dla m > 2.