Alex
Alex

Reputation: 5247

problems with RSA decryption formula

I'm trying to decrypt a message that was encrypted using the RSA algorithm

enter image description here

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

Answers (2)

speckledcarp
speckledcarp

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

NullUserException
NullUserException

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

Related Questions