Reputation: 5247
I'm trying to decrypt a message that was encrypted using the RSA algorithm
The example from above is taken from Website, so I tried to implement it in C#:
int msg = 67;
int Ee = 5;
int Nn = 91;
int Dd = 29;
var cipher = Math.Pow(msg, Ee) % Nn;
var msg2 = Math.Pow(cipher, Dd) % Nn;
MessageBox.Show("Msg: " + msg.ToString() + " cipher: " + cipher.ToString()
+ " msg: " + msg2.ToString());
And the output is following:
Msg: 67 cipher: 58 msg: 45
As you can see - encryption works fine, but decryption isn't!
So I went and inspected the website and it turned out that Javaspript uses another formula:
function mod( m, n )
{
return m - n*Math.floor(m/n)
}
function PowerMod(x,p,N)
// Compute x^p mod N
{
var A = 1
var m = p
var t = x
while( m > 0 )
{
k = Math.floor( m/2 )
r = m - 2*k
if( r == 1 )
A = mod( A*t, N )
t = mod( t*t, N )
m = k
}
return A
}
var temp = ""
var e = form.e.value
var d = form.d.value
var N = form.N.value
var M = form.Msg.value
form.Cipher.value = PowerMod(M,e,N)
var C = form.Cipher.value
form.Decipher.value = PowerMod(C,d,N)
Rather than copying and pasting ready formula - I'd like to know why my approach isn't working and i'd rather fix my formula than just rewrite JS. Any ideas on how to fix decryption?
Upvotes: 2
Views: 1146
Reputation: 6375
The cipher text is 58, and your decipher key is 29.
58^29 = really, really huge. Approximately 1.378516 * 10^51
I think your direct approach is overrunning the precision of the double data type used in Math.Pow. For a modulus divide, it's the least significant bits that matter the most, and those are precisely the ones that are being ignored/lost.
It looks to me like the javascript algorithm is collapsing the power operation and the mod operation together so the data always stays within easy reach of the precision of the underlying data types.
Upvotes: 2
Reputation: 85478
Your logic is correct, but Math.Pow()
won't yield a precise result because 5829 is too large for it to handle. This is what ultimately breaks your algorithm. In practice, RSA keys are much larger than that, and computing b ^ e
is simply not feasible.
The PowerMod()
JavaScript function performs modular exponentiation (b ^ e % m
) without loss of precision using the right-to-left binary method, which is why it works.
You can read more about it on Wikipedia article for modular exponentiation.
Upvotes: 3