RSA

di il
7 risposte

RSA

Salve a tutti,
ho creato un programma in c++ dell'algoritmo di crittografia a doppia chiave RSA.
Ho un problema però... Il programma non codifica e non decodifica, però logicamente e a livello di sintassi sembra giusto ma non so... Qualcuno può darmi un consiglio?!? Il codice è questo:

#include<iostream>
#include<assert.h>
#include<ctype.h>
#include<errno.h>
#include<float.h>
#include<math.h>
#include<stddef.h>
#include<stdlib.h>
#include<string.h>
#include<iso646.h>
#include<time.h>
using namespace std;

int const righe=50;			//costante per vettore n primi
int q;						//variabile contenente fattore per kpubblica e kprivata
int p;						//variabile contenente fattore per kpubblica e kprivata
int pq;						//variabile contenente parte di kpubblica e kprivata
bool vet_np[righe];			//matrice contenente numeri primi
int e;						//variabile che contiene la seconda parte della chiave pubblica generato automaticamente
int d;						//variabile che contiene la seconda parte della chiave privata
int pq_1;					//variabile contenente (p-1)(q-1)
int jnd;					//indice
int ind;					//indice
bool flag;					//operatore booleano
bool flag2;					//operatore booleano
char m;						//variabile contenente il messaggio da cifrare
// variabili per calcolare la d
int x;					
int y;
int z;
int g;
int a;
int b;
int c;
int v;
int resto;
int resto2;
int resto3;



void n_primi()	/*carico vettore booleano, accendo tutti i flag, moltiplico l'indice principale ind con un indice secondario jnd, 
							genero cosi un terzo indice che mi darà la posizione di un numero non primo. Rilevato il numero non primo il flag si spegnerà*/
{
	for(ind=0; ind<righe; ind++)
		{
			vet_np[ind]=1;
		}
	for(ind=2; ind<righe; ind++)
		{
			for(jnd=2; jnd<righe; jnd++)
				{
					z=ind*jnd;
					if(z>righe)
						{
							continue;		//istruzione che fa proseguire il programma all'istruzione successiva
						}
					else
					{
						vet_np[z]=0;
					}
				}
		}
}

void inserimento_nprimi() /*si inseriscono P e Q*/ 
{
	//prendo p e q in input dall'utente
	cout<<"Inserire numero primo (P)"<<endl;		
	cin>>p;
	cout<<"Inserire un secondo numero primo (Q)"<<endl;
	cin>>q;
	system("cls");
}


void controllo_nprimo()
{
	flag=false;
	flag2=false;
	//controllo i valori inseriti
	do{
		for(ind=0; ind<righe; ind++)
			{
				if(p==ind and vet_np[ind]==1)
					{
						flag=true;		//se il primo numero inserito è primo si attiva il primo flag
					}
				if(q==ind and vet_np[ind]==1)
					{
						flag2=true;		//se il secondo numero inserito è primo si attiva il secondo flag
					}
			}
		
			if(flag!=true or flag2!=true)
					{
						ind=0;
						inserimento_nprimi();
					}
	}while(flag!=true or flag2!=true);
}

void calcolo()
{
	pq=p*q;								//calcolo p*q
	pq_1=(p-1)*(q-1);					//calcolo p-1)*(q-1
	e=pq_1-1;							//calcolo il coprimo di p-1)*(q-1
	
	/*calcolo la d*/
	
	c=pq_1/e;							//calcolo p-1)*(q-1 fratto e							
	resto=pq_1%e;						//riporto il resto dell'operazione precedeente
	z=a-b*c;							//calcolo la d
	
/*per poter calcolare la d il resto deve essere = 1, nel caso non sia cosi continuiamo
 con le operazioni fatte fin ora cambiando semplicemente il nome della variabile*/
 
	if (resto!=1 and resto>0)			
	{
		x=e/resto;
		resto2=e%resto;
		y=b-z*x;
	}
	if(z<0)
	{
		z=z+pq_1;
	}
	if(resto2!=1 and resto2>0)
	{
		g=resto/resto2;
		resto3=resto&resto2;
		v=z-y*g;
	}
	if (v<0)
	{
		v=v+pq_1;
	}
	if(resto==1)
	{
		d=z;
	}
	if(resto2==1)
	{
		d=y;
	}
	
	/*dati fino a tre possibili casi dove il resto del teorema di euclide è diverso da 1*/
}

void messaggio()
{
	cout<<"Inserire messaggio da cifrare"<<endl;	//inserimento messaggio da cifrare
	cin>>m;
	system("cls");
}

void cifratura()
{
	c=int(m);			//conversione da stringa a integer
	d=(c^e)/pq;			//messaggio elevato ad e il tutto diviso p-1)(q-1
	v=d*pq;				//si moltiplica il risultato dell'operazione di prima senza la virgola per il modulo stesso
	c=d-v;				//si sottrae il primo risultato per il secondo per completare la cifratura
	m=char(c);			//conversione da stringa a integer
	cout<<"Il messaggio e' stato cifrato "<<m<<endl;
	system("pause");
}

void decifratura()
{				/*i passaggi effettuati in cifratura sono uguali a quelli della decifratura solo che al posto di andare a elevare il 
				valore del messaggio per e si eleva per d*/
	c=int(m);
	d=(c^d)/pq;
	v=d*pq;
	c=d-v;
	m=char(c);
	cout<<"Il messaggio e' stato decifrato "<<m<<endl;
	system("pause");
}

int main()
{
	n_primi();
    inserimento_nprimi();
    controllo_nprimo();		//parte automaticamente il controllo sui dati in inputi e li confronta con il vettore	
	messaggio();
	calcolo();
	cifratura();
	decifratura();
	system("pause");
}
Grazie mille a chi mi può aiutare!!

7 Risposte

  • Re: RSA

    Ti dispiace se inserisci i tag code al codice possibilmente indentandolo. Sarà più semplice leggerlo e darti una mano.
  • Re: RSA

    I tag code si inseriscono come [_code_] ... codice ... [_/code_] ma senza le "_" - e infatti si legge meglio:
    int main()
    {
      n_primi();
      inserimento_nprimi();
      controllo_nprimo(); //parte automaticamente il controllo sui dati in inputi e li confronta con il vettore
      messaggio();
      calcolo();
      cifratura();
      decifratura();
      system("pause");
    }
    Ma devo farti un complemento: Ho raramente visto un programma con tanti commenti dettagliati - stupendo! RSA non è la mia specializzazione, purtroppo, ma qualcuno ti darà una mano. Abbi pazienza.
  • Re: RSA

    jj2007 ha scritto:


    I tag code si inseriscono come [_code_] ... codice ... [_/code_] ma senza le "_" - e infatti si legge meglio:
    int main()
    {
      n_primi();
      inserimento_nprimi();
      controllo_nprimo(); //parte automaticamente il controllo sui dati in inputi e li confronta con il vettore
      messaggio();
      calcolo();
      cifratura();
      decifratura();
      system("pause");
    }
    Ma devo farti un complemento: Ho raramente visto un programma con tanti commenti dettagliati - stupendo! RSA non è la mia specializzazione, purtroppo, ma qualcuno ti darà una mano. Abbi pazienza.

    Grazie mille per il complimento!!
  • Re: RSA

    #include <iostream>
    #include <assert.h>
    #include <ctype.h>
    #include <errno.h>
    #include <float.h>
    #include <math.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iso646.h>
    #include <time.h>
    using namespace std;
    
    int const righe = 50; //costante per vettore n primi
    int q; //variabile contenente fattore per kpubblica e kprivata
    int p; //variabile contenente fattore per kpubblica e kprivata
    int pq; //variabile contenente parte di kpubblica e kprivata
    bool vet_np[righe]; //matrice contenente numeri primi
    int e; //variabile che contiene la seconda parte della chiave pubblica generato automaticamente
    int d; //variabile che contiene la seconda parte della chiave privata
    int pq_1; //variabile contenente (p-1)(q-1)
    int jnd; //indice
    int ind; //indice
    bool flag; //operatore booleano
    bool flag2; //operatore booleano
    char m; //variabile contenente il messaggio da cifrare
    // variabili per calcolare la d
    int x;
    int y;
    int z;
    int g;
    int a;
    int b;
    int c;
    int v;
    int resto;
    int resto2;
    int resto3;
    
    void n_primi() /*carico vettore booleano, accendo tutti i flag, moltiplico l'indice principale ind con un indice secondario jnd, 
    genero cosi un terzo indice che mi darà la posizione di un numero non primo. Rilevato il numero non primo il flag si spegnerà*/
    {
        for (ind = 0; ind < righe; ind++) {
            vet_np[ind] = 1;
        }
        for (ind = 2; ind < righe; ind++) {
            for (jnd = 2; jnd < righe; jnd++) {
                z = ind * jnd;
                if (z > righe) {
                    continue; //istruzione che fa proseguire il programma all'istruzione successiva
                }
                else {
                    vet_np[z] = 0;
                }
            }
        }
    }
    
    void inserimento_nprimi() /*si inseriscono P e Q*/
    {
        //prendo p e q in input dall'utente
        cout << "Inserire numero primo (P)" << endl;
        cin >> p;
        cout << "Inserire un secondo numero primo (Q)" << endl;
        cin >> q;
        system("cls");
    }
    
    void controllo_nprimo()
    {
        flag = false;
        flag2 = false;
        //controllo i valori inseriti
        do {
            for (ind = 0; ind < righe; ind++) {
                if (p == ind and vet_np[ind] == 1) {
                    flag = true; //se il primo numero inserito è primo si attiva il primo flag
                }
                if (q == ind and vet_np[ind] == 1) {
                    flag2 = true; //se il secondo numero inserito è primo si attiva il secondo flag
                }
            }
    
            if (flag != true or flag2 != true) {
                ind = 0;
                inserimento_nprimi();
            }
        } while (flag != true or flag2 != true);
    }
    
    void calcolo()
    {
        pq = p * q; //calcolo p*q
        pq_1 = (p - 1) * (q - 1); //calcolo p-1)*(q-1
        e = pq_1 - 1; //calcolo il coprimo di p-1)*(q-1
    
        /*calcolo la d*/
    
        c = pq_1 / e; //calcolo p-1)*(q-1 fratto e
        resto = pq_1 % e; //riporto il resto dell'operazione precedeente
        z = a - b * c; //calcolo la d
    
        /*per poter calcolare la d il resto deve essere = 1, nel caso non sia cosi continuiamo
    con le operazioni fatte fin ora cambiando semplicemente il nome della variabile*/
    
        if (resto != 1 and resto > 0) {
            x = e / resto;
            resto2 = e % resto;
            y = b - z * x;
        }
        if (z < 0) {
            z = z + pq_1;
        }
        if (resto2 != 1 and resto2 > 0) {
            g = resto / resto2;
            resto3 = resto & resto2;
            v = z - y * g;
        }
        if (v < 0) {
            v = v + pq_1;
        }
        if (resto == 1) {
            d = z;
        }
        if (resto2 == 1) {
            d = y;
        }
    
        /*dati fino a tre possibili casi dove il resto del teorema di euclide è diverso da 1*/
    }
    
    void messaggio()
    {
        cout << "Inserire messaggio da cifrare" << endl; //inserimento messaggio da cifrare
        cin >> m;
        system("cls");
    }
    
    void cifratura()
    {
        c = int(m); //conversione da stringa a integer
        d = (c ^ e) / pq; //messaggio elevato ad e il tutto diviso p-1)(q-1
        v = d * pq; //si moltiplica il risultato dell'operazione di prima senza la virgola per il modulo stesso
        c = d - v; //si sottrae il primo risultato per il secondo per completare la cifratura
        m = char(c); //conversione da stringa a integer
        cout << "Il messaggio e' stato cifrato " << m << endl;
        system("pause");
    }
    
    void decifratura()
    { /*i passaggi effettuati in cifratura sono uguali a quelli della decifratura solo che al posto di andare a elevare il 
    valore del messaggio per e si eleva per d*/
        c = int(m);
        d = (c ^ d) / pq;
        v = d * pq;
        c = d - v;
        m = char(c);
        cout << "Il messaggio e' stato decifrato " << m << endl;
        system("pause");
    }
    
    int main()
    {
        n_primi();
        inserimento_nprimi();
        controllo_nprimo(); //parte automaticamente il controllo sui dati in inputi e li confronta con il vettore
        messaggio();
        calcolo();
        cifratura();
        decifratura();
        system("pause");
    }
    Adesso non riesco a controllare tutto l'algoritmo, pero' secondo me ci sono altri problemi con il tuo codice...molto piu' seri.
    1) Stai mischiando C e C++
    2) Stai usando soltanto variabili globali
    3) Hai commentato il tuo codice, pero' 90% dei commenti sono inutili o possono essere sostituiti con variabili/funzioni
  • Re: RSA

    Blazgrom ha scritto:


    #include <iostream>
    #include <assert.h>
    #include <ctype.h>
    #include <errno.h>
    #include <float.h>
    #include <math.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iso646.h>
    #include <time.h>
    using namespace std;
    
    int const righe = 50; //costante per vettore n primi
    int q; //variabile contenente fattore per kpubblica e kprivata
    int p; //variabile contenente fattore per kpubblica e kprivata
    int pq; //variabile contenente parte di kpubblica e kprivata
    bool vet_np[righe]; //matrice contenente numeri primi
    int e; //variabile che contiene la seconda parte della chiave pubblica generato automaticamente
    int d; //variabile che contiene la seconda parte della chiave privata
    int pq_1; //variabile contenente (p-1)(q-1)
    int jnd; //indice
    int ind; //indice
    bool flag; //operatore booleano
    bool flag2; //operatore booleano
    char m; //variabile contenente il messaggio da cifrare
    // variabili per calcolare la d
    int x;
    int y;
    int z;
    int g;
    int a;
    int b;
    int c;
    int v;
    int resto;
    int resto2;
    int resto3;
    
    void n_primi() /*carico vettore booleano, accendo tutti i flag, moltiplico l'indice principale ind con un indice secondario jnd, 
    genero cosi un terzo indice che mi darà la posizione di un numero non primo. Rilevato il numero non primo il flag si spegnerà*/
    {
        for (ind = 0; ind < righe; ind++) {
            vet_np[ind] = 1;
        }
        for (ind = 2; ind < righe; ind++) {
            for (jnd = 2; jnd < righe; jnd++) {
                z = ind * jnd;
                if (z > righe) {
                    continue; //istruzione che fa proseguire il programma all'istruzione successiva
                }
                else {
                    vet_np[z] = 0;
                }
            }
        }
    }
    
    void inserimento_nprimi() /*si inseriscono P e Q*/
    {
        //prendo p e q in input dall'utente
        cout << "Inserire numero primo (P)" << endl;
        cin >> p;
        cout << "Inserire un secondo numero primo (Q)" << endl;
        cin >> q;
        system("cls");
    }
    
    void controllo_nprimo()
    {
        flag = false;
        flag2 = false;
        //controllo i valori inseriti
        do {
            for (ind = 0; ind < righe; ind++) {
                if (p == ind and vet_np[ind] == 1) {
                    flag = true; //se il primo numero inserito è primo si attiva il primo flag
                }
                if (q == ind and vet_np[ind] == 1) {
                    flag2 = true; //se il secondo numero inserito è primo si attiva il secondo flag
                }
            }
    
            if (flag != true or flag2 != true) {
                ind = 0;
                inserimento_nprimi();
            }
        } while (flag != true or flag2 != true);
    }
    
    void calcolo()
    {
        pq = p * q; //calcolo p*q
        pq_1 = (p - 1) * (q - 1); //calcolo p-1)*(q-1
        e = pq_1 - 1; //calcolo il coprimo di p-1)*(q-1
    
        /*calcolo la d*/
    
        c = pq_1 / e; //calcolo p-1)*(q-1 fratto e
        resto = pq_1 % e; //riporto il resto dell'operazione precedeente
        z = a - b * c; //calcolo la d
    
        /*per poter calcolare la d il resto deve essere = 1, nel caso non sia cosi continuiamo
    con le operazioni fatte fin ora cambiando semplicemente il nome della variabile*/
    
        if (resto != 1 and resto > 0) {
            x = e / resto;
            resto2 = e % resto;
            y = b - z * x;
        }
        if (z < 0) {
            z = z + pq_1;
        }
        if (resto2 != 1 and resto2 > 0) {
            g = resto / resto2;
            resto3 = resto & resto2;
            v = z - y * g;
        }
        if (v < 0) {
            v = v + pq_1;
        }
        if (resto == 1) {
            d = z;
        }
        if (resto2 == 1) {
            d = y;
        }
    
        /*dati fino a tre possibili casi dove il resto del teorema di euclide è diverso da 1*/
    }
    
    void messaggio()
    {
        cout << "Inserire messaggio da cifrare" << endl; //inserimento messaggio da cifrare
        cin >> m;
        system("cls");
    }
    
    void cifratura()
    {
        c = int(m); //conversione da stringa a integer
        d = (c ^ e) / pq; //messaggio elevato ad e il tutto diviso p-1)(q-1
        v = d * pq; //si moltiplica il risultato dell'operazione di prima senza la virgola per il modulo stesso
        c = d - v; //si sottrae il primo risultato per il secondo per completare la cifratura
        m = char(c); //conversione da stringa a integer
        cout << "Il messaggio e' stato cifrato " << m << endl;
        system("pause");
    }
    
    void decifratura()
    { /*i passaggi effettuati in cifratura sono uguali a quelli della decifratura solo che al posto di andare a elevare il 
    valore del messaggio per e si eleva per d*/
        c = int(m);
        d = (c ^ d) / pq;
        v = d * pq;
        c = d - v;
        m = char(c);
        cout << "Il messaggio e' stato decifrato " << m << endl;
        system("pause");
    }
    
    int main()
    {
        n_primi();
        inserimento_nprimi();
        controllo_nprimo(); //parte automaticamente il controllo sui dati in inputi e li confronta con il vettore
        messaggio();
        calcolo();
        cifratura();
        decifratura();
        system("pause");
    }
    Adesso non riesco a controllare tutto l'algoritmo, pero' secondo me ci sono altri problemi con il tuo codice...molto piu' seri.
    1) Stai mischiando C e C++
    2) Stai usando soltanto variabili globali
    3) Hai commentato il tuo codice, pero' 90% dei commenti sono inutili o possono essere sostituiti con variabili/funzioni

    Scusami mica mi puoi dire quali istruzioni di C starei usando?
    non penso sia un problema usare solo variabili globali, si rende più semplice e leggero il codice
    Per i commenti mi hanno insegnato che anche i commenti più stupidi possono servire a chi legge il programma, da allora commento tutto!!
  • Re: RSA

    Blazgrom ha scritto:


    Adesso non riesco a controllare tutto l'algoritmo, pero' secondo me ci sono altri problemi con il tuo codice...molto piu' seri.
    1) Stai mischiando C e C++
    2) Stai usando soltanto variabili globali
    3) Hai commentato il tuo codice, pero' 90% dei commenti sono inutili o possono essere sostituiti con variabili/funzioni
    Se non riesci a "controllare" tutto l'algoritmo, allora perché non riesci almeno a trattenere l'impulso di scrivere commenti del tutto inutili?

    @Tsunami:
    - mischiare C e C++ non è vietato, se il tuo compiler lo accetta, ci sarà un motivo
    - non abituarti troppo ai variabili globali; per un Hello World sono OK ma alla lunga creano problemi
    - i tuoi commenti sono perfetti, non lasciarti intimidare da nessuno.
  • Re: RSA

    @Tsunami909
    Gli include, in C++ se vuoi fare l'include di un header della standard library di C dovresti usare
    #include <cheader>
    Esempio
    #include <float.h>
    diventa
    #include <cfloat>
    oltre a questo se non ricordo male l'utilizzo l'uso di #include <nome.h> e' deprecato.
    Si e' vero che i commenti a volte i commenti sono utili pero' dimmi cosa ti comunica questo commenca che il codice non te lo dice gia' ?
    
        pq = p * q; //calcolo p*q
    


    @jj2007
    Perche' non penso sono inutili, quando si discutte il codice non bisogna guardare soltanto la correttezza dell'algoritmo...
    Si e' vero che non e' evitato pero' e' una brutta prattica.
    Il codice che ha postato l'OP non mi sembra un hello world quindi non vedo' perche' dovrebbero andare bene le variabili globali.
    Non cercavo di intimidire nessuno, semplicemente un commento scritto male e' peggio di un commento mancante
Devi accedere o registrarti per scrivere nel forum
7 risposte