1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#include <iostream>
#include <gmpxx.h>
#include <time.h>
#include <string.h>
#define SIZE 100
#define MPZ_T(X) mpz_t X;mpz_init(X)
#define GMP_RANDSTATE_T(X) gmp_randstate_t X;gmp_randinit_default(X);
#define SEPARATEUR ";"
using namespace std;
void keygen(mpz_t & N, mpz_t & C, mpz_t & U);
void randomPrime(mpz_t &prime, int nb, gmp_randstate_t &state);
string encrypt(mpz_t &N, mpz_t &C, string message);
string decrypt(mpz_t &N, mpz_t &U, string message);
int main(int argc, char *argv[])
{
// string message = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
// cout << message << endl;
//Création des trois variables de type 'mpz_t' qui forment la clée public et la clée privée :
MPZ_T(N);
MPZ_T(C);
MPZ_T(U);
for(int i = 1; i< 10; i++){
cout << "-----------"<<endl;
keygen(N, C, U);
cout << i<<"-----------"<<endl;
}
//string message2;
// message2 = encrypt(N, C, message);
//cout << endl;
//cout << endl;
//cout << message2 << endl;
//cout << endl;
// cout << endl;
// message = decrypt(N, U, message2);
// cout << message << endl;
return 0;
}
void keygen(mpz_t & N, mpz_t & C, mpz_t & U)
{
GMP_RANDSTATE_T(state);
gmp_randseed_ui(state, (int)time(NULL));
MPZ_T(P);
MPZ_T(Q);
MPZ_T(P2);
MPZ_T(Q2);
MPZ_T(M);
randomPrime(P, SIZE, state);
randomPrime(Q, SIZE, state);
mpz_mul(N, P, Q);
mpz_sub_ui(Q2, Q, 1);
mpz_sub_ui(P2, P, 1);
mpz_mul(M, P2, Q2);
mpz_clear(P2);
mpz_clear(Q2);
randomPrime(C, SIZE/2, state);
mpz_invert(U, C, M);
mpz_clear(P);
mpz_clear(Q);
mpz_clear(M);
gmp_printf("N : %Zd \n", N);
gmp_printf("C : %Zd \n", C);
gmp_printf("U : %Zd \n", U);
return;
}
void randomPrime(mpz_t & prime, int nb, gmp_randstate_t &state) //Retourne un nombre premier d'une valeur maximal de 'nb'
{
MPZ_T(rand);
MPZ_T(sub_rand);
MPZ_T(max);
mpz_ui_pow_ui(max, 10, nb);
MPZ_T(limite);
mpz_ui_pow_ui(limite, 10, nb-1);
mpz_mul_ui(limite, limite, 9);
mpz_urandomm(rand, state, limite);
mpz_sub(sub_rand, max, rand);
mpz_nextprime(prime, sub_rand);
return;
}
string encrypt(mpz_t &N, mpz_t &C, string message)
{
string encryptMessage;
MPZ_T(nb);
for(int i = 0; i < message.size(); i++)
{
mpz_set_ui(nb, (int)message[i]);
mpz_powm(nb, nb, C, N);
encryptMessage += mpz_class(nb).get_str(10) + SEPARATEUR;
}
return encryptMessage;
}
string decrypt(mpz_t & N, mpz_t & U, string message)
{
string decryptMessage;
int start = -1, end = message.find(";", 1);
MPZ_T(current);
while(end != -1)
{
mpz_set_str(current, message.substr(start+1, end-start-1).c_str(), 10); //Extrait le nombre d'entre les deux séparateur
mpz_powm(current, current, U, N);
decryptMessage += (char)mpz_get_ui(current);
start = message.find(SEPARATEUR, start + 1);
end = message.find(SEPARATEUR, end + 1);
}
return decryptMessage;
}
| |