I want to calculate ab mod n for use in RSA decryption. My code (below) returns incorrect answers. What is wrong with it?
unsigned long int decrypt2(int a,int b,int n)
{
unsigned long int res = 1;
for (int i = 0; i < (b / 2); i++)
{
res *= ((a * a) % n);
res %= n;
}
if (b % n == 1)
res *=a;
res %=n;
return res;
}
In order to calculate
pow(a,b) % n
to be used for RSA decryption, the best algorithm I came across is Primality Testing 1) which is as follows:See below reference for more details.
1) Primality Testing : Non-deterministic Algorithms – topcoder
I'm using this function:
I parse the variable result because pow give you back a double, and for using mod you need two variables of type int, anyway, in a RSA decryption, you should just use integer numbers.
A key problem with OP's code is
a * a
. This isint
overflow (undefined behavior) whena
is large enough. The type ofres
is irrelevant in the multiplication ofa * a
.The solution is to ensure either:
n
,n*n <= type_MAX + 1
There is no reason to return a wider type than the type of the modulus as the result is always represent by that type.
Using unsigned math is certainly more suitable for OP's RSA goals.
Doing the raw power operation is very costly, hence you can apply the following logic to simplify the decryption.
From here,
but my best bet is you are overflowing int (IE: the number is two large for the int) on the power I had the same problem creating the exact same function.
The only actual logic error that I see is this line:
which should be this:
But your overall design is problematic: your function performs O(b) multiplications and modulus operations, but your use of
b / 2
anda * a
implies that you were aiming to perform O(log b) operations (which is usually how modular exponentiation is done).