views:

206

answers:

4

Hi,

I'm trying to figure out how to implement RSA crypto from scratch (just for the intellectual exercise), and i'm stuck on this point:

For encryption, c = me mod n

Now, e is normally 65537. m and n are 1024-bit integers (eg 128-byte arrays). This is obviously too big for standard methods. How would you implement this?

I've been reading a bit about exponentiation here but it just isn't clicking for me:

http://en.wikipedia.org/wiki/Exponentiation_by_squaring

http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf (see section 14.85)

Thanks.

edit: Also found this - is this more what i should be looking at? http://en.wikipedia.org/wiki/Modular_exponentiation

+3  A: 
sth
+8  A: 

Exponentiation by squaring:

Let's take an example. You want to find 1723. Note that 23 is 10111 in binary. Let's try to build it up from left to right.

           // a      exponent in binary

a = 17     //17^1          1

a = a * a  //17^2         10

a = a * a  //17^4        100
a = a * 17 //17^5        101

a = a * a  //17^10      1010
a = a * 17 //17^11      1011

a = a * a  //17^22     10110
a = a * 17 //17^23     10111

When you square, you double the exponent (shift left by 1 bit). When you multiply by m, you add 1 to the exponent.

If you want to reduce modulo n, you can do it after each multiplication (rather than leaving it to the end, which would make the numbers get very large).

65537 is 10000000000000001 in binary which makes all of this pretty easy. It's basically

a = m
repeat 16 times:
    a = a * a
    a = a mod n
a = a * m
a = a mod n

where of course a, n and m are "big integers". a needs to be at least 2048 bits as it can get as large as (n-1)2.

Artelius
Fantastic answer. I'm taking a while to soak it in though, it's taking a while!
Chris
And, for implementations sake, all i need further is to implement a bignum for the multiplication and modulus steps above?
Chris
You're almost sure to implement bignum incorrectly. The problem of multiplying big numbers and adding big numbers is almost as tricky as exponentation. Can you not use a language library that handles that automatically?
Stefan Kendall
Adding big numbers is not terribly hard. Multiplying them is trickier although the Karatsuba Algorithm is not that hard to implement. I suggest starting with a library and then replacing it with your own implementation if you really want to.
Artelius
This is a learning exercise, so i really want to implement it myself. I'll start by implementing the longhand version, then move on to karatsuba later possibly. I'm sure i'll get it wrong first time, that's never stopped me before!
Chris
Ah, okay :). Slow multiplication will kill the exponentation by squaring method, so you'll want to get that right before you tackle the main problem. This exact set of problems was posed to my algorithms class when I attended university, and about 80% of the students slammed into a brick wall with multiplication.
Stefan Kendall
Boo-yah! Got the multiplication to work pretty much first go :)
Chris
Just wanted to point out that this solution only computes 1 exponent. For RSA you're going to need a general solution for the other key - see solution below :-)
phkahler
+3  A: 
phkahler
You forgot to e>>=1
Artelius
Thanks for spotting that. Fixed.
phkahler
Don't we have to start with the most significant bit? See VII.A here: http://people.csail.mit.edu/rivest/Rsapaper.pdf
Chris
My mistake, you're using the right-to-left binary method, which is a different algorithm to what i was thinking: http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method
Chris
I was going to write it scanning left to right, but at the time it seemed like a hassle. This way you don't need to find the MSB, but you do have to shift the whole exponent each loop. It's a small trade.
phkahler
+1  A: 

If g(x) = x mod 2^k is faster to calculate for your bignum library than f(x) = x mod N for N not divisible by 2, then consider using Montgomery multiplication. When used with modular exponentiation, it avoids having to calculate modulo N at each step, you just need to do the "Montgomeryization" / "un-Montgomeryization" at the beginning and end.

Jason S
N cannot be even, e.g. 26 cannot be used for Montgomery multiplication but 26 is not a power of 2.
GregS
fixed... thanks!
Jason S