Why does this tiny RSA implementation give wrong results?
I'm trying to implement a simple RSA encryption/decryption process, and I'm pretty sure I've got the equations around the right way. Although it doesn't seem to be printing out the correct decrypted value after the开发者_StackOverflow encryption. Any ideas?.
//test program
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int gcd(int a, int b);
int main(){
char character = 'A'; //character that is to be encrypted
int p = 7;
int q = 5;
int e = 0; // just initializing to 0, assigning actual e value in the 1st for loop
int n = p*q;
int phi = (p-1)*(q-1);
int d = 0; // " " 2nd for loop
//---------------------------finding 'e' with phi. where "1 < e < phi(n)"
for (int i=2; i < phi; i++){
if (gcd(i,phi) == 1){ //if gcd is 1
e = i;
break;
}
}
//----------------------------
//---------------------------finding 'd'
for (int i = 2; i < phi; i++){
int temp = (e*i)%phi;
if (temp == 1){
d = i;
break;
}
}
printf("n:%d , e:%d , phi:%d , d:%d \n",n,e,phi,d);
printf("\npublic key is:[%d,%d]\n",e,n);
printf("private key is:[%d,%d]\n",d,n);
int m = static_cast<int>(character); //converting to a number
printf("\nconverted character num:%d\n",m);
//Encryption part ie. c = m^e MOD n
int power = pow(m,e); // m^e
int c = power%n; // c = m^e MOD n. ie. encrypted character
printf("\n\nEncrypted character number:%d\n",c);
//decryption part, ie. m = c^d MOD n
power = pow(c,d);
int m2 = power%n;
printf("\n\ndecrypted character number:%d\n",m2);
return 0;
}
int gcd(int a, int b){
int r;
if (a < 0) a = -a;
if (b < 0) b = -b;
if (b > a) {
r = b; b = a; a = r;
}
while (b > 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
(The prime numbers being used are 5 and 7, for the test)
Here I'm converting the character 'A' to its numeric value which is of course 65. When I encrypt this value using c = m^e MOD n
(where m is the converted value, i.e. 65) it gives me c as 25.
Now, to reverse the process, I do m = c^d MOD n
, which gives me m
as 30 ... which really isn't correct because it should be 65, no?
Where exactly have I gone wrong?
[edit]
Is my calculation of d
correct?
The encrypted message m
must be less than n
. You can't use values larger than n, because the calculations are done modulo n. In your case m=65
and n=35
. So you are actually getting the correct answer modulo n
, because 65 % 35 == 30
.
It is caused by having m
greater than or equal to n
like @interjay already answered.
But I found another problem with your code, my gcc4.1.2 compiler output 24
for the encrypted value not 25
. It is because you use pow()
function and then convert the result (which is type double) to int that causes precision loss.
Don't use pow()
function, instead use square and multiply modulo n algorithm to compute c = m^e MOD n
and m = c^d MOD n
. It is faster than pow()
and you won't need to unsafely downcast the result to integer.
精彩评论