The RSA Cryptosystem in 10 minutes
Is this number prime?!
Euler's Theorem to the rescue!
If n and a are coprime and positive,
The exponent is Euler's totient function.
It counts the number of integers less than n that are coprime to it.
Fun with Totients
(in general)
(if p is prime)
Version of Euler's Theorem for pq
if:
then:
Euler to Fermat
If p is prime, then Euler's theorem contains Fermat's as a special case:
So let's pick a = 2. If that monster number is prime, then we expect it to be 1 mod p.
Thus we know the number is composite!
(But no idea what its factors are)
Giant exponents
In crypto, calculating these numbers raised to large powers happens all the time. Here's an example of the algorithm.
Let's calculate:
Expand the exponent in base-2:
Notice how each subsequent term involves squaring the previous one (sometimes multiple times)
"Fast Powering"
def expmod(g, A, m):
bits = bin(A)[2:][::-1]
a = []
for i, bit in enumerate(bits):
a.append(g%m)
g = (g%m) * (g%m)
res = 1
for i, bit in enumerate(bits):
res *= a[i]**(int(bit)) % m
res %= m
return res
print expmod(3, 218, 1000)
$ python expmod.py
489Write the exponent in binary.
Then reading the bits from right to left, you can build a table of intermediate products, taking mods at each step.
Find "mod roots" is really hard
(assuming e, c, and N are known)
The difficulty of this problem accounts for the security of RSA.
However, it's feasible to solve this problem if N is prime, or you know its factors.
Solving
Let p and q be distinct prime numbers,
and let e be coprime to (p-1)(q-1).
Then e has an inverse mod (p-1)(q-1):
Then, the unique solution is:
Proof
(by Euler's theorem)
(definition of inverse)
Modular Inverses
Not all numbers have an inverse mod N.
An inverse for a number g mod N exists if and only if g and N are coprime.
So 4 has an inverse mod 15. Since
4 is its own inverse! (mod 15)
So 7 has an inverse mod 11. Since
Euclid's Algorithm
Euclid's algorithm for the GCD can also give you numbers u,v that satisfy
def egcd(a,b):
"""Extended GCD algorithm"""
if b == 0:
return (a, 1, 0)
else:
g, x, y = egcd(b, a%b)
u = y
v = x - (a/b)*y
assert a*u + b*v == g
GCD = namedtuple('GCD', 'gcd u v')
return GCD(gcd = g, u = y, v = x - (a/b)*y)
print egcd(18,24)
$ python gcd.py
GCD(gcd=6, u=-1, v=1)Calculating Modular Inverses
The definition of an inverse of x mod m is a number y such that
But the definition of mod means this is equivalent to
or
Given that x and m are coprime, we can use Euclid's algorithm to find y (and k, which we don't care about)
Mod Inverse Example
Thus 1583 and 7918 are coprime, and we can use Euclid's algorithm.
def invmod(a, m):
assert gcd(a,m) == 1
g = egcd(a,m)
result = g.u
# find the smallest positive solution
while result < 0:
result += m
return result
$ python invmod.py
5277
>>> (5277 * 1583) % 7918
1Something more fun
Is 30069476293 prime?
Since it's not congruent to 1, it's not prime.
This problem is really hard to solve.
But: what if I told you how to factor this number?
>>> n = 30069476293
>>> print expmod(2, n-1, n)
18152503626>>> 104729 * 287117
30069476293Now it's easy to solve!
Solution
"Let p and q be distinct prime numbers,
and let e be coprime to (p-1)(q-1)."
Is 9843 coprime to
(104729-1)(287117-1)?
>>> e = 9843
>>> p = 104729
>>> q = 287117
>>> print gcd(e, (p-1)*(q-1))
1Yep.
Use Euclid's algorithm
to get d:
>>> print invmod(e, (p-1)*(q-1))
18472798299 # mod (p-1)(q-1)>>> print expmod(134872, 18472798299, 30069476293)
25470280263Setup and Encrypting RSA
Let's say Alice wants to send a message securely to Bob without Eve knowing the contents.
First, Bob has picked two big prime numbers, p and q. He keeps these secret!
Second, Bob picks another positive number e (for encryption exponent) that is coprime to (p-1)(q-1). Publish N = pq and e somewhere. This is his public key.
Sending and Decrypting RSA
She sends the ciphertext to Bob. Eve can see it too, but she can't decrypt it because this problem is really hard. Finally, Bob can decrypt Alice's message by calculating:
Third, Alice takes her message m and computes the ciphertext c, encrypted with Bob's public key (N,e):
where:
RSA Example: Key Creation
Bob picks p and q.
He also picks e such that it's coprime to (p-1)(q-1).
>>> e = 948047
>>> p = 1223
>>> q = 1987
>>> print gcd(e, (p-1)*(q-1))
1So (2430101, 948047) is Bob's public key.
RSA Example: Encryption
Alice wants to send Bob the message m = 1070777.
She calculates:
>>> print expmod(1070777, 948047, 2430101)
1473513She sends Bob the encrypted message 1473513.
RSA Example: Decryption
Eve sees 1473513 and thinks, "Huh, just gibberish."
Bob can decrypt this ciphertext since he knows p and q. First, he calculates d, the decryption exponent using Euclid's algorithm:
>>> print invmod(e, (p-1)*(q-1))
1051235Now he can recover the message:
>>> print expmod(1473513, 1051235, 2430101)
1070777Bob sees 1070777 and thinks, "Oh, that makes obvious sense."
Bibliography
I skipped over very important implementation details. A really great book for mathematical cryptography is:
Introduction to Mathematical Cryptography, by
Hoffstein, Pipher, Silverman. My examples all came straight from this book.
Another is Koblitz's Number Theory and Cryptography. Koblitz is a leader in the field and co-created elliptic curve crypto (for another time).
Extras
RSA needs very very large primes. If you pick a random number, how can you see if it's prime?
-Fermat's Little Theorem, Miller-Rabin Test
RSA depends on the difficulty of factorization. How well can we factor numbers?
-Pollard's p-1 algorithm:
-Difference of squares:
-Quadratic and number field sieve:
RSA Intro
By chrislambda
RSA Intro
Crypto lightning talk
- 890