Click here to load reader

Fattorizzazione e log discreto

  • View
    452

  • Download
    6

Embed Size (px)

Text of Fattorizzazione e log discreto

  1. 1. Indagini sulla fattorizzazione RSA e sul logaritmo discreto Di Cristiano Armellini, [email protected] Fattorizzazione: metodo QR quadro Sia con p, q numeri primi k dispari allora posso scrivere per un determinato valore di a: n-kp = 2(a+n/p) e ponendo v = n-2a ho l'equazione di II grado Si poteva anche considerare il caso n-kp=2(n/p-a) ma del tutto analogo con la sola differenza che v=n+2a k pari allora posso scrivere n-kp = 2(a+n/p)+ 1 e ponendo v = n-2a-1 ho l'equazione di II grado Si poteva anche considerare il caso n-kp=2(n/p-a)+1 ma del tutto analogo con la sola differenza che v=n+2a-1 Nota: se k dispari allora v dispari, se k pari allora v pari Stabilisco oltre a n anche il valore di k (k varia per ogni PC - calcolo parallelo). Il valore di k molto importante. L'algoritmo per funzionare ha bisogno di un valore di k intero con k > p/q dove p> q ovvero k=2, 3, 4, 5, .... Negli RSA dove la dimensione di p circa quella di q ,k pu assumere un valore basso da 2 a 100 (massimo). In ogni caso k < n/8 come si pu facilmente provare. Risolvo l'equazione di II grado finch non trovo le soluzioni intere facendo variare il valore del parametro v. Ecco una semplice applicazione in Python: import math; def fact(n, k): v = math.floor(math.sqrt(8*n*k)); delta = math.sqrt(math.fabs(v*v-8*n*k)); p = (v-delta)/(2*k); q = (v+delta)/(2*k); while p != math.floor(p) and q != math.floor(q): v = v+1;
  2. 2. delta = math.sqrt(math.fabs(v*v-8*n*k)); p = (v-delta)/(2*k); q = (v+delta)/(2*k); if p == math.floor(p): print(p); print(n/p); else: print(q); print(n/q); Con semplici considerazioni algebriche si pu pervenire in modo altrettanto valido anche alle altre equazioni del tipo , . Quindi possiamo scrivere anche (dove k>p/q, p> q , k = 1, 2, 3, 4, ,.... per numeri RSA) import math; def fact(n, k): v = 0; delta = math.sqrt(math.fabs(v*v+8*n*k)); p = (v-delta)/(2*k); q = (v+delta)/(2*k); while p != math.floor(p) and q != math.floor(q): v = v+1; delta = math.sqrt(math.fabs(v*v+8*n*k)); p = (v-delta)/(2*k); q = (v+delta)/(2*k); if p == math.floor(p): print(p); print(n/p); else: print(q); print(n/q);
  3. 3. Algoritmi per fattorizzare i numeri con il software Mathematica Si consiglia di usare comunque l'ultima versione del software e all'occorrenza di impostare i calcoli con un elevato numero di cifre decimali n := 187 b := 1 a := N[Sqrt[n+b^2]] While[a != Floor[a], b=b+1; a := N[Sqrt[n+b^2]] ] p := a-b q := a+b Print[p] Print[q] ----------------------- n := 187 a := Floor[N[Sqrt[n]]] b := N[Sqrt[Abs[a^2-n]]] While[ b != Floor[b], a = a+1; b := N[Sqrt[Abs[a^2-n]]]] p := a-b q := a+b Print[p] Print[q] ------------------------- n := 187 i := 1 p := GCD[10^i-1, n] While[p==1, i=i+1;p := GCD[10^i-1, n] ] Print[p] Print[n/p] ---------------------------- Nota Per aumentare la precisione e il numero delle cifre significative si pu usare la funzione N[], con la specifica ad esempio N[, 100] per calcoli con 100 cifre significative
  4. 4. La teoria dei numeri con il software Mathematica Di seguito esempi di codice (anche programmazione) con il software Mathematica per applicazioni nella teoria dei numeri FATTORIZZAZIONE CON ALGORITMO EQUAZIONE DI II GRADO n := 2535311 s := 2*Floor[N[Sqrt[n]]] delta := N[Sqrt[Abs[s*s-4*n]]] While[delta != Floor[delta],s=s+2;delta := N[Sqrt[Abs[s*s-4*n]]]] p := (s-delta)/2 q := (s+delta)/2 Print[p] Print[q] FATTORIZZAZIONE CON IL FATTORIALE n := 187 s := Floor[N[Sqrt[n]]] GCD[n, s!] FATTORIZZAZIONE CON ATTACCO FORZA BRUTA n := 2535311 i = 3 While[n/i != Floor[n/i],i=i+2] Print[i] Print[n/i] n := 1234567891273 i := 3 While[Mod[n, i]!=0, i= i+2] Print[i] Print[n/i] LISTA DEI NUMERI PRIMI i := 1 While[i r = 0 ( Questo prova perch le soluzioni del logaritmo discreto sotto le opportune ipotesi di cui sopra sono tutte equidistanti ovvero in media aritmetica con ragione e dove e | p-1. Infatti se allora y=x+be tale che . Quindi y = x+be soluzione di , p primo e x soluzione data, e = ragione della progressione delle soluzioni. Discorso analogo per lequazione dove MCD(a, )=1, y= x+be soluzione con e | , x la soluzione pi piccola trovata, e = ragione della progressione delle soluzioni. Nell'equazione con p primo (siamo qui nelle ipotesi di Diffie-Helmann) il periodo che caratterizza tutte le soluzioni in progressione aritmetica si calcola trovando il valore minimo tale che d = periodo della progressione aritmetica delle soluzioni. Tale valore come sopra provato deve essere un divisore di p-1 (o molto spesso lo stesso valore p-1) I divisori di un numero senza ripetizioni Nel procedimento per trovare le soluzioni dellalgoritmo di Diffie-Helmann pu essere utile trovare tutti i divisori di un numero senza ripetizioni. Applicazioni: teoria dei numeri, logaritmo discreto import math; def divisori(n): j = 1; while (j < math.floor(math.sqrt(n))):
  5. 8. if n % j == 0: print(j); print(n/j); j = j+1; else: j =j+1; le soluzioni del Logaritmo discreto e le progressioni aritmetiche Dato il logaritmo discreto con a, b, n noti se esiste una soluzione allora ne esistono infinite e tutte le soluzioni sono in progressione aritmetica MCD(a, n)=1 inoltre se n primo la ragione d | (n-1) mentre se n=pq con p, q primi allora la ragione d | (p-1)(q-1), In alcuni casi la condizione MCD(a,n)=1 non indispensabile, come vedremo negli esempi seguenti Se n=pq, con p, q primi, da dove MCD(a,n)=1 ricordiamo che , , Questo ci aiuta nella fattorizzazione di n spendo che i fattori si trovano , conosciuto s risolvendo direttamente lequazione di II grado Esempio 1) 7^x = 2 mod 11 si trova che x = 3 , x = 13, x = 23, ..... (soluzioni in progressione aritmetica con ragione 10 =11-1, 10 | 10) Esempio 2) 7^x = 4 mod 11 si trova che x = 6 , x = 16, x = 26, ..... (soluzioni in progressione aritmetica con ragione 10=11-1, 10 | 10) Esempio 3) 4^x = 9 mod 11 si trova che x = 3 , x = 8, x = 13, ..... (soluzioni in progressione aritmetica con ragione 5, 5 | 10) Esempio 4) 2^x = 9 mod 11
  6. 9. si trova che x = 6 , x = 16, x = 26, ..... (soluzioni in progressione aritmetica con ragione 10=11-1, 10 | 10) Esempio 5) 3^x = 15 mod 17 si trova che x = 6 , x = 22, x = 38, ..... (soluzioni in progressione aritmetica con ragione 16=17-1, 16 | 16) Esempio 6) 204^x = 34 mod 391 si trova che x = 15 , x = 37, x = 59, ..... (soluzioni in progressione aritmetica con ragione 22, 22 | (17-1)(23-1) = 352) qui molte in z_n. Esempio 7) 9^x = 15 mod 33 si trova che x = 2 , x = 7, x = 12, ..... (soluzioni in progressione aritmetica con ragione 5, 5| (3-1)(11-1)=2*10 ) Esempio 8) 3^x = 13 mod 17 si trova che x = 4 , x = 20, x = 36, ..... (soluzioni in progressione aritmetica con ragione 16=17-1 , 16 | 16) quindi trovando le prime due soluzioni si ha la formula per trovare tutte le altre. Programma BC: logaritmo discreto e fattorizzazione FATTORIZZAZIONE CON BC (BRUTE FORCE) n = 187; scale = 0; p = 3; while ( n%p != 0 ) p = p+2; print p; print n/p;
  7. 10. LOGARITMO DISCRETO CON BC (BRUTE FORCE) i = 80; scale = 0; while ((204^i) % 391 != 34) i = i+1; print i in Python a^x = b mod n import math; def logdisc(a, b, n): i= 1; while(a**i % n != b): i = i+1; print(i); In PARI/GP {logdisc(a, b, n) = local(i); i = 1; while(a^i % n != b, i=i+1); print(i); } Ancora formule per problemi RSA Dalla relazione sempre verificata , s=p+q, n=pq, ottengo sapendo che q=n/p V deve essere pari perch differenza di due pari Oppure: dalle relazioni di somma e prodotto ,
  8. 11. In generale non molto efficiente ..... Ecco un programma in Python import math; def facto(n): V = 2*n; delta = V*V-4*n*n; p = math.sqrt((V+math.sqrt(delta))/2); while (n%p != 0): V = V+2; delta = V*V-4*n*n; p = math.sqrt((V+math.sqrt(delta))/2); q = n/p; print(p); print(q); Crivello per la fattorizzazione con le equazioni di II grado ogni numero primo pu terminare solo con una della cifre 1, 3, 7, 9 sia n = pq dove p, q sono numeri primi In base alla seguente tabella moltiplicativa: X 1 3 7 9 1 1 3 7 9 3 3 9 (2)1 (2)7 7 7 (2)1 (4)9 (6)3 9 9 (2)7 (6)3 (8)1 il numero n = pq con p, q primi pu terminare a sua volta con una delle seguenti cifre finali: 1, 3, 7, 9 Sia n =pq, s = p+q, d =p-q in base quindi alla tabella abbiamo il seguente schema: se l'ultima cifra di n = pq : cifra finale di n 3 allora abbiamo le seguenti combinazioni per le cifre finali di p, q: (3,1), (7, 9) quindi la somma s=p+q deve terminare con una delle cifre 4, 6; mentre la differenza d=p-q con una delle cifre 2, 8 cifra finale di n 1 allora abbiamo le seguenti combinazioni per le cifre finali di p, q: (9,9), (1, 1), (3, 7) quindi la somma s=p+qdeve terminare con una delle cifre 0, 2, 8; mentre la differenzad=p-q con una delle cifre 0, 4, 6
  9. 12. cifra finale di n 9 allora abbiamo le seguenti combinazioni per le cifre finali di p, q: (3,3), (1, 9), (7, 7) quindi la somma s=p+qdeve terminare con una delle cifre 0, 4, 6; mentre la differenzad=p-q con una delle cifre 0, 2, 8 cifra finale di n 7 allora abbiamo le seguenti combinazioni per le cifre finali di p, q: (3,9), (7, 1) quindi la somma s=p+q deve terminare con una delle cifre 2, 8; mentre la differenza d=p-q con una delle cifre 6, 4 Queste considerazioni ci possono essere molto utili in algoritmi di fattorizzazione del tipo . Inoltre dato che deve essere un quadrato perfetto facile vedere che un quadrato perfetto deve terminare con una delle cifre 0, 1, 4, 5, 6, 9. Infatti basta osservare la tabella: I I^2 0 0 1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 e questo aumenta ulteriormente la velocit nella ricerca delle soluzioni RSA: ancora equazioni di II grado n= pq => RSA p-V = 2a, con V numeri dispari fissato qualsiasi p-V = 2(q+b) => p-V = 2(n/p +b) => M = V+2b => M dispari (V dispari, 2b pari) => p =MCD(n, p1)
  10. 13. q =MCD(n, p2) Il metodo risulta particolarmente efficiente quando p/q circa 1/2 e in RSA caso abbastanza comune import math; def mcd(a, b): if b == 0: return

Search related