Generarea şi validarea numerelor prime mari 1 Modalităţi de generare a numerelor prime mari Metoda cea mai naturală este de a genera aleator un număr n de mărime adecvată şi de a verifica dacă acesta este prim. Acest lucru poate fi făcut verificând dacă n este divizibil prin unul din numerele prime n. Cu toate că în practică sunt necesare metode mai eficiente, pentru a motiva discuţii următoare, considerăm următorul exemplu: 1. Generează drept candidat un număr impar n de mărime adecvată;. Testează dacă n este prim; 3. Dacă n este compus (neprim), reia de la primul pas. O uşoară modificare ar fi de a considera candidaţii constrânşi la anumite secvenţe de căutare pornind de la n; o secvenţă banală ce poate fi utilizată este: n, n+, n+4, n+6,.... Utilizând secvenţe specifice de căutare se poate mări şansa ca un candidat să fie prim şi de a găsi numere prime care să posede anumite proprietăţi a priori. În al doilea pas, testul pentru număr prim poate fi un test care dovedeşte că respectivul candidat este prim (caz în care rezultatul generatorului se numeşte ce poate fi dovedit prim), sau un test ce stabileşte un rezultat mai slab, de genul n este probabil prim (caz în care rezultatul generatorului se numeşte probabil prim). În ultimul caz trebuie acordată atenţie deosebită sensului exact al acestei expresii. Cele mai multe aşa numite teste probabilistice pentru număr prim sunt absolut corecte când declară candidatul n ca fiind compus, dar nu au suport matematic că n este prim în cazul în care un astfel de număr este declarat a fi probabil prim. Totuşi, în ultimul caz, printr-o utilizare corectă, deseori se pot trage concluzii mai mult decât suficiente pentru un anume scop. De aceea, astfel de teste sunt denumite mai corect teste de număr compus decât teste probabilistice pentru număr prim. Testele adevărate pentru număr prim, care dovedesc cu suport matematic că un număr este prim, sunt de asemenea implementate, însă necesită un efort computaţional considerabil mărit. Pe când testele (adevărate) pentru număr prim pot determina (cu certitudine matematică) dacă un candidat aleator tipic este prim, alte tehnici stabilesc pe ce cale candidaţii sunt special construiţi astfel încât să se poată dovedi matematic dacă un candidat este chiar prim. Acestea se numesc tehnici de generare constructivă de numere prime. O diferenţă finală între diferitele tehnici de generare a numerelor prime este utilizarea unui generator aleator. Candidaţii sunt tipic generaţi funcţie de o intrare aleatoare. Totuşi, tehnica utilizată pentru a decide dacă candidatul este prim poate sau nu să folosească numere aleatoare. Dacă nu foloseşte, tehnica este deterministă, iar rezultatul este repetabil; dacă foloseşte, tehnica este numită ca făcând uz de aleator. Există teste probabilistice de număr prim atât deterministe, cât şi cu uz de aleator. Distribuţia numerelor prime Fie π(x) ce denotă numărul de numere prime din intervalul [,x]. Teorema numerelor x prime afirmă că π(x) ~ 1. Cu alte cuvinte, numărul de numere prime din intervalul [,x] ln x x este aproximativ egal cu. Numerele prime sunt aproximativ uniform distribuite, după ln x cum reiese din următoarele trei rezultate. f ( x) 1 Dacă f(x) şi g(x) sunt două funcţii, atunci f(x) ~ g(x) înseamnă lim 1. x g( x) 1
Lemă (Teorema Dirichlet): Dacă gcd(a, n) = 1, atunci există infinit de multe numere prime congruente cu a modulo n. (gcd cel mai mare divizor comun) O versiune mai explicită a teoremei lui Dirichlet este următoarea: Lemă: Fie π(x, n, a) numărul de numere prime din intervalul [,x] care sunt congruente cu a modulo n, unde gcd(a, n) = 1. Atunci x π(x, n, a) ~ ( n) ln x Cu alte cuvinte, numerele prime sunt uniform distribuite printre clasele congruente din Z * n, pentru orice valoare a lui n. n Lemă (aproximare pentru al n-lea număr prim): Fie p n al n-lea număr prim. Atunci p n ~ n ln n. Mai explicit, n ln n < p n < n(ln n + ln ln n), pentru n 6 3 Teste probabilistice pentru număr prim Algoritmii prezentaţi în acest paragraf sunt metode prin care întregi arbitrari pozitivi sunt testaţi pentru a afla informaţii parţiale cu privire la calitatea de a fi numere prime. Mai precis, testele probabilistice de număr prim au următorul cadru de lucru: pentru fiecare întreg impar pozitiv n, un set W(n) Z n este definit astfel încât să fie respectate următoarele proprietăţi: (i) dat a Z n, se poate verifica într-un timp determinist polinomial dacă a W(n); (ii) dacă n este prim, atunci W(n) este mulţime vidă; (iii) dacă n este compus, atunci #W(n) n/. Definiţie: Dacă n este compus, elementele lui W(n) se numesc martori ai compunerii lui n, iar elementele mulţimii complementare L(n) = Z n - W(n) se numesc mincinoşi. Un test probabilistic de număr prim utilizează aceste proprietăţi ale setului W(n) în maniera următoare. Presupunem că n este un întreg pe care dorim să-l testăm dacă este prim. Se alege aleator un întreg a Z n şi se verifică dacă a W(n). Rezultatul testului este compozit dacă a W(n) şi este prim dacă a W(n). Dacă a W(n), atunci se spune că n a căzut testul de număr prim pentru baza a; în acest caz, n este sigur compus. Dacă a W(n), atunci se spune că n a trecut testul de număr prim pentru baza a; în acest caz nu se poate trage nici o concluzie absolut sigură cu privire la calitatea lui n de a fi prim, iar declaraţia prim poate fi incorectă. Orice execuţie singulară a acestui test care returnează compus stabileşte acest fapt cu certitudine. Pe de altă parte, rulări succesive independente ale testului care returnează toate prim permit ca încrederea că intrarea este într-adevăr număr prim să fie crescută la ce nivel se doreşte probabilitatea totală de eroare este produsul probabilităţilor de eroare ale testelor independente. Dacă testul este rulat independent de t ori pe numărul compus n, probabilitatea ca n să fie declarat prim de toate cele t ori (adică probabilitatea de eroare) este cel mult t 1. Definiţie: Un întreg n care este bănuit a fi prim pe baza testului probabilistic de număr prim se numeşte probabil prim. Discuţia explică de ce un test probabilistic de număr prim ar fi mai corect denumit test de număr compus
3.1 Testul lui Fermat Teorema lui Fermat afirmă că dacă n este prim şi a este un întreg oarecare, 1 a n- 1, atunci a n-1 1 (mod n). De aceea, dacă nu se ştie dacă un număr n este sau nu prim, găsirea oricărui întreg a în intervalul specificat astfel încât echivalenţa să fie falsă este suficientă pentru a arăta că n este compus. Definiţie: Fie n un întreg impar compus. Un întreg a, 1 a n-1, astfel încât a n-1 1 (mod n) se numeşte martor Fermat (al compunerii) pentru n. Reciproc, găsirea unui întreg a între 1 şi n-1 astfel încât a n-1 1 (mod n) ar face să pară că n este prim în sensul teoremei Fermat pentru baza a. Definiţie: Fie n un întreg impar compus şi a un întreg, 1 a n-1. Atunci n se numeşte pseudo-prim în raport cu baza a dacă a n-1 1 (mod n). Întregul a se numeşte mincinos Fermat (al calităţii de a fi prim) pentru n. Exemplu (pseudo-prim): Întregul compus n = 341 (= 11 x 31) este pseudo-prim în raport cu baza, deoarece 340 1 (mod 341). Calcul gcd(a,b) IN: a,b întregi pozitive cu a b OUT: gcd(a,b) while(b) temp=a mod b; a=b; b=temp return (a) Calcul lui a k mod n IN: a număr întreg si k n unde prin k i vom înţelege bitul de rang i al lui k OUT: a k mod n b=1 if(!k)return(b); temp=a; if(k 0 )b=a; for(i=1;i++;i<t) temp=temp mod n if(k i )b=temp*bmod n return(b); Algoritmul Fermat pentru număr prim FERMAT(n,t) INTRĂRI: un întreg impar n 3 şi parametrul de securitate t 1. IEŞIRE: un răspuns prim sau compus la întrebarea Este n număr prim? 3
pentru i de la 1 la t alege aleator un întreg a, a n- calculează r = a n-1 mod n, utilizând algoritmul anterior dacă r 1, atunci return( prim ) Dacă acest algoritmul declară un număr compus, atunci n este cu siguranţă compus. Pe de altă parte, dacă algoritmul declară prim, nu este nici o dovadă că n este într-adevăr prim. În ciuda acestui fapt, deoarece numerele pseudo-prime pentru o anumită bază a sunt ştiute a fi rare, testul Fermat dă un răspuns corect pentru majoritatea intrărilor; totuşi, aceasta nu este totuna cu un răspuns de cele mai multe ori corect pentru orice intrare. De fapt, există (chiar dacă mai rare) numere compuse care sunt pseudo-prime pentru orice bază a pentru care gcd(a, n) = 1. 3. Numere Carmichael Definiţie: Un număr Carmichael n este un întreg compus pentru care a n-1 1 (mod n) pentru toţi întregii a care satisfac gcd (a, n) = 1. Dacă n este un număr Carmichael, atunci singurii martori Fermat pentru n sunt acei întregi a, 1 a n-1, pentru care gcd (a, n) > 1. Astfel, dacă factorii primi ai lui n sunt toţi mari, atunci cu probabilitate mare testul Fermat declară că n este prim, chiar dacă numărul de iteraţii t este mare. Această deficienţă a testului Fermat este înlăturară în testele Solovay-Strassen şi Miller-Rabin prin folosirea unor criterii mai puternice decât teorema Fermat. Dacă factorizarea primă a lui n este cunoscută, atunci lema următoare poate fi utilizată pentru a determina uşor dacă n este un număr Carmichael. Lemă (condiţiile necesare şi suficiente pentru numere Carmichael): Un întreg compus n este număr Carmichael dacă şi numai dacă sunt satisfăcute următoarele două condiţii: (i) n este liber de pătrate, adică nu este divizibil prin pătratul nici unui număr prim; (ii) p-1 divide n-1 pentru orice divizor prim p al lui n. O consecinţă a lemei este următoarea: Lemă: Fiecare număr Carmichael este produsul a cel puţin trei numere prime. Lemă (limite pentru numărul de numere Carmichael): (i) Există un număr infinit de numere Carmichael. De fapt, există mai mult de n /7 numere Carmichael în intervalul [, n], dacă n este destul de mare. (ii) Cea mai bună limită superioară cunoscută pentru C(n), numărul de numere Carmichael n, este: C(n) n 1-1+o(1)ln ln ln n / ln ln n, pentru n. Cel mai mic număr Carmichael este n = 561 = 3 x 11 x 17. Numerele Carmichael sunt relativ rar întâlnite; sunt doar 1051 numere Carmichael 10 15. 4
3.3 Testul Solovay-Strassen Testul probabilistic de număr prim Solovay-Strassen a fost primul astfel de test răspândit de apariţia criptografiei cheie-publică, în particular cripto-sistemul RSA. Nu mai există nici un motiv de a folosi acest test, deoarece este disponibil unul alternativ (testul Miller-Rabin), care este mai eficient şi totdeauna cel puţin la fel de corect. Descrierea este inclusă atât din motive istorice, cât şi pentru a clarifica acest test, având în vedere că mulţi oameni continuă să-l amintească. a Amintim că este simbolul Jacobi şi este echivalent cu simbolul Legendre dacă n este prim. Testul Solovay-Strassen se bazează pe următoarea lemă: Lemă (criteriul lui Euler): Fie n un număr impar prim. Atunci a (n-1)/ orice întreg a care satisface gcd (a, n) = 1. Aceasta motivează următoarea definiţie: Definiţie: Fie n un întreg impar compus şi fie a un întreg, 1 a n-1. a (mod n) pentru 5
(i) Dacă gcd (a, n) > 1 sau a (n-1)/ a (mod n), atunci a se numeşte martor Euler (al calităţii de a fi compus) pentru n. (ii) Altfel, adică dacă gcd (a, n) = 1 şi a (n-1)/ a (mod n), atunci n se numeşte un număr Euler pseudo-prim în raport cu baza a. (Adică n se comportă ca un număr prim, deoarece satisface criteriul Euler pentru o bază particulară a). Întregul a se numeşte mincinos Euler (cu privire la calitatea de a fi prim) pentru n. Exemplu (pseudo-prim Euler): Întregul compus 91 (= 7 x 13) este un pseudo-prim Euler faţă de baza 9, deoarece 9 45 9 1 (mod 91) şi = 1. 91 Criteriul Euler (lema 4.14) poate fi utilizat ca o bază pentru un test probabilistic de număr prim datorită următorului rezultat: Lemă: Fie n un întreg impar compus. Atunci cel mult (n) / din toate numerele a, 1 a n- 1, sunt mincinoşi Euler pentru n. Aici, este funcţia phi Euler. 3.4 Calculul simbolului Jacobi (identic cu simbol Legendre daca n prim) IN: un interger impar n > 3 si un intreg pozitiv a < n Out: Simbol Jacobi int jacobi(int a, int n) int ans; if (a == 0) ans = (n==1)? 1 : 0; else if (a == ) switch (n%8) case 1: case 7: ans = 1; break; case 3: case 5: ans = -1; break; else if ( a >= n ) ans = jacobi(a%n, n); else if (a% == 0) ans = jacobi(,n)*jacobi(a/, n); else ans = (a%4 == 3 && n%4 == 3)? -jacobi(n,a) : jacobi(n,a); return ans; 3.5 Algoritmul Solovay-Strassen pentru test probabilistic de număr prim 6
SOLOVAY-STRASSEN(n,t) INTRĂRI: un întreg impar n 3 şi parametrul de securitate t 1. IEŞIRE: un răspuns prim sau compus la întrebarea Este n număr prim? pentru i de la 1 la t alege aleator un întreg a, a n- calculează r = a (n-1)/ mod n, utilizând algoritmul anterior descris dacă r 1 şi r n-1, atunci a calculează simbolul Jacobi s =, utilizând algoritmul.149 dacă r s (mod n), atunci return( prim ) Dacă gcd (a, n) = d, atunci d este divizor al lui r = a (n-1)/ mod n. De aici, testul r 1 elimină necesitatea testului gcd (a, n) 1. Dacă algoritmul declară compus, atunci n este sigur compus, deoarece numerele prime nu violează criteriul Euler. Echivalent, dacă n este de fapt prim, atunci algoritmul declară totdeauna prim. Pe de altă parte, dacă n este de fapt compus, atunci deoarece bazele a sunt alese independent la fiecare iteraţie, ultima lema prezentata poate fi folosită pentru a deduce următoarea probabilitate ca algoritmul să declare eronat prim : Lemă (limita probabilităţii de eroare pentru algoritmul Solovay-Strassen): Fie n un întreg impar compus. Probabilitatea ca SOLOVAY-STRASSEN(n,t) să declare n ca fiind prim t 1 este mai mică de. 3.6 Testul Miller-Rabin Cel mai folosit test probabilistic pentru numere prim este testul Miller-Rabin, cunoscut şi sub numele de test pseudo-prim puternic. Testul se bazează pe următoarea lemă: Lemă: Fie n un număr impar prim şi n-1 = s r, unde r este impar. Fie a un întreg pentru care gcd (a, n) = 1. Atunci a r j 1 (mod n) sau a r 1(mod n) pentru unii j, 0 j s-1. Aceasta lema motivează următoarea definiţie: Definiţie: Fie n un întreg impar compus şi n-1 = s r, unde r este impar. Fie a un întreg în intervalul [1, n-1]. (i) Dacă a r j 1 (mod n) şi a r 1(mod n) pentru toţi j, 0 j s-1, atunci a se numeşte martor puternic (al compunerii) pentru n. (ii) Altfel, adică a r j 1 (mod n) sau a r 1(mod n) pentru unii j, 0 j s-1, atunci n este un pseudo-prim puternic faţă de baza a. (Adică n se comportă ca un număr prim, 7
deoarece satisface lema anterioara pentru o bază particulară a). Întregul a se numeşte mincinos puternic (cu privire la calitatea de a fi prim) pentru n. Exemplu (pseudo-prim puternic): Considerăm întregul compus n = 91 (=7 x 13). Deoarece 91 1 = 90 = x 45, s = 1 şi r = 45. Deoarece 9 r = 9 45 1 (mod 91), 91 este un pseudo-prim puternic pentru baza 9. Mulţimea tuturor mincinoşilor puternici pentru 91 este: 1,9,10,1,16,17,,9,38,53,6,69,74,75,79,81,8,90 Se observă că numărul de mincinoşi puternici pentru 91 este 18 = (91)/4, unde este funcţia phi Euler. Aceasta ultima Lema poate fi folosită drept o bază pentru un test probabilistic de număr prim datorită următorului rezultat: Lemă: Dacă n este un întreg compus impar, atunci cel mult ¼ din toţi întregii a, 1 a n-1 sunt mincinoşi puternici pentru n. De fapt, dacă n 9, numărul mincinoşilor puternici pentru n este cel mult (n)/4, unde este funcţia phi Euler (definiţia.100). Algoritmul Miller-Rabin pentru test probabilistic de număr prim MILLER-RABIN(n,t) INTRĂRI: un întreg impar n 3 şi parametrul de securitate t 1. IEŞIRE: un răspuns prim sau compus la întrebarea Este n număr prim? scrie n-1 = s r, astfel încât r să fie impar pentru i de la 1 la t alege aleator un întreg a, a n- calculează y = a r mod n, utilizând algoritmul anterior descris dacă y 1 şi y n-1, atunci j 1 cât timp j s-1 şi y n-1 calculează y y mod n dacă y = 1 atunci j j+1 dacă y n-1 atunci return( prim ) Acest algoritm testează dacă fiecare bază a satisface condiţiile definiţiei (i). În linia a j cincea a instrucţiunii dacă, dacă y = 1, atunci a r 1(mod n). Deoarece este de asemenea j 1 r cazul a 1(mod n), rezultă că n este compus. În linia a şaptea a instrucţiunii dacă, dacă y n-1, atunci a este un martor puternic pentru n. Dacă algoritmul declară compus, 8
atunci n este cu siguranţă compus. Echivalent, dacă n este de fapt prim, atunci algoritmul declară totdeauna prim. Lemă (limita probabilităţii de eroare pentru algoritmul Miller-Rabin): Pentru orice întreg compus impar, probabilitatea ca MILLER-RABIN(n,t) să declare n ca fiind prim este mai t 1 mică de. 4 Observaţie (numărul de mincinoşi puternici): Pentru majoritatea întregilor compuşi n, numărul de mincinoşi puternici pentru n este de fapt mult mai mic decât limita superioară a raportului (n)/4. Prin urmare, probabilitatea de eroare pentru algoritmul Miller-Rabin este t 1 mult mai mică decât, pentru majoritatea întregilor pozitivi n. 4 Exemplu (unii întregi compuşi au foarte puţini mincinoşi puternici): Singurii mincinoşi puternici pentru întregul compus n = 105 (= 3 x 5 x 7) sunt 1 şi 104. Mai general, dacă k şi n este produsul primelor k numere prime impare, sunt doar mincinoşi puternici pentru n, şi anume 1 şi n-1. Observaţie (baze fixe în Miller-Rabin): Dacă a 1 şi a sunt mincinoşi puternici pentru n, este foarte posibil, dar nu sigur, ca produsul lor, a 1 a, să fie de asemenea mincinos puternic pentru n. O strategie întrebuinţată uneori este de a fixa bazele a în algoritmul Miller-Rabin ca fiind primele câteva numere prime (bazele compuse sunt ignorate din cauza afirmaţiei precedente), în loc de a le alege aleator. 9