Lo schema parametrico nella fattorizzazione rsa

404 views

Published on

fattorizzazione dei numeri RSA

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
404
On SlideShare
0
From Embeds
0
Number of Embeds
104
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Lo schema parametrico nella fattorizzazione rsa

  1. 1. Lo schema parametrico nella fattorizzazione RSA Di Cristiano Armellini, cristiano.armellini@alice.it Supponiamo di considerare il problema RSA ovvero di cercare i fattori p, q primi del numero intero n = pq. Possiamo scrivere, ricordando che la somma di due numeri dispari è un numero pari: akn 2)12( =++ e sapendo che le soluzioni dell’equazione 02 =+− nsxx , dove s=p+q e n=pq sono proprio x = p, q possiamo scrivere 0)12(22 =++− knayy che risolta ci fornisce le soluzioni )12(,)12(2 +>+−±= knaknaay . Infatti nel formulare l’equazione di II grado abbiamo tenuto conto che n + (2k+1) = 2 a , mentre il prodotto tra n e (2k+1) è proprio n(2k+1). Quindi fissato un valore di k intero variamo il parametro a, all’interno del suo campo di esistenza (il discriminante deve essere positivo per avere soluzioni reali di y) finché non otteniamo ,appunto, valori per y interi. A questo punto troviamo i fattori di n=pq come il massimo comun divisore tra y e n: p = MCD(| y1|, n), q = MCD(n,| y2|) usando per il MCD l’algoritmo di Euclide. Possiamo associare a ogni computer di una rete di calcolatori un differente valore di k =0, 1, 2, 3,.. e quindi progettare un attacco di calcolo parallelo per arrivare più velocemente alla soluzione. Osserviamo che ci sono altri 3 casi notevoli con il medesimo schema di calcolo, tenendo conto che n è un dispari perché prodotto di due numeri primi dispari: - il caso 122 +=+ akn (sommando un dispari con un numero pari ottengo un dispari) che porta all’equazione 02)12(2 =++− knyay , ovvero 2 8)12(12 2 knaa y −+±+ = , e ponendo 12 += aM => 2 82 knMM y −± = , k = 0, 1, 2 knM 8> e dispari, )2,(),1,( ynMCDqynMCDp == . Il massimo comun divisore si calcola con l’algoritmo di Euclide e per semplicità si prendono i valori assoluti dei valori di y trovati, potendo esserci il caso in cui almeno uno di questi valori sia negativo.
  2. 2. - il caso akn 2)12( =+− (sottraendo un dispari con un dispari ottengo un numero pari) che porta all’equazione 0)12(22 =+−− knayy , ovvero )12(2 ++±= knaay , k=0, 1, 2, …; a = 0, 1, 2, …. )2,(),1,( ynMCDqynMCDp == . Il massimo comun divisore si calcola con l’algoritmo di Euclide e per semplicità si prendono i valori assoluti dei valori di y trovati, potendo esserci il caso in cui almeno uno di questi valori sia negativo. - il caso 122 +=− akn (sottraendo un dispari a un numero pari ottengo un dispari) porta all’equazione 02)12(2 =−+− knyay , ovvero 2 8)12(12 2 knaa y ++±+ = , ponendo 12 += aM 2 82 knMM y +± = k = 0, 1, 2, 3, 4…; M dispari positivo, )2,(),1,( ynMCDqynMCDp == . Il massimo comun divisore si calcola con l’algoritmo di Euclide e per semplicità si prendono i valori assoluti dei valori di y trovati, potendo esserci il caso in cui almeno uno di questi valori sia negativo. Si noti come queste formule generalizzino la fattorizzazione alla Fermat che si ottiene ponendo semplicemente k = 0. Non è affatto complesso scrivere un programma in Python, in PARI/Gp in C++ che sfrutti queste formule ed apprezzare la velocità con cui si arriva, con un sistema di calcolo parallelo che assegni ad ogni PC un valore differente di k, alla soluzione finale. Ecco alcuni esempi degli schemi descritti in Python: Caso 1) import math; def mcd(a, b): if b == 0: return a; else: return mcd(b, a%b); def facto(n, k):
  3. 3. a = math.floor(math.sqrt(n*(2*k+1))); delta = math.sqrt(math.fabs(a**2-n*(2*k+1))); while(delta != math.floor(delta)): a = a+1; delta = math.sqrt(math.fabs(a**2-n*(2*k+1))); y1 = a-delta; y2 = a+delta; p = mcd(y1, n); q = mcd(y2, n); print(p); print(q); Caso 2) import math; def mcd(a, b): if b == 0: return a; else: return mcd(b, a%b); def facto(n, k): M = math.floor(math.sqrt(8*k*n)); if M/2 == math.floor(M/2): M = M+1; else: M = M; delta = math.sqrt(math.fabs(M**2-8*k*n)); while( delta != math.floor(delta)): M = M+2; delta = math.sqrt(math.fabs(M**2-8*k*n)); y1 = (M-delta)/2; y2 = (M+delta)/2; p = mcd(y1, n); q = mcd(y2, n); print(p); print(q); Caso3) import math; def mcd(a, b): if b == 0: return a; else: return mcd(b, a%b); def facto(n, k): M = 1; delta = math.sqrt(math.fabs(M**2+8*k*n)); while( delta != math.floor(delta)): M = M+2; delta = math.sqrt(math.fabs(M**2+8*k*n));
  4. 4. y1 = (M-delta)/2; y2 = (M+delta)/2; p = mcd(y1, n); q = mcd(y2, n); print(p); print(q);
  5. 5. Caso 4) import math; def mcd(a, b): if b == 0: return a; else: return mcd(b, a%b); def facto(n, k): a = 0; delta = math.sqrt(math.fabs(a**2+n*(2*k+1))); while(delta != math.floor(delta)): a = a+1; delta = math.sqrt(math.fabs(a**2+n*(2*k+1))); y1 = a-delta; y2 = a+delta; p = mcd(y1, n); q = mcd(y2, n); print(p); print(q);
  6. 6. Caso 4) import math; def mcd(a, b): if b == 0: return a; else: return mcd(b, a%b); def facto(n, k): a = 0; delta = math.sqrt(math.fabs(a**2+n*(2*k+1))); while(delta != math.floor(delta)): a = a+1; delta = math.sqrt(math.fabs(a**2+n*(2*k+1))); y1 = a-delta; y2 = a+delta; p = mcd(y1, n); q = mcd(y2, n); print(p); print(q);

×