The RSA Cryptosystem in 10 minutes

Is this number prime?!

p = 31987937737479355332620068643713101490952335301
p=31987937737479355332620068643713101490952335301p = 31987937737479355332620068643713101490952335301

Euler's Theorem to the rescue!

a^{\phi(n)} \equiv 1\text{ (mod n)}
aϕ(n)1 (mod n)a^{\phi(n)} \equiv 1\text{ (mod n)}

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

\phi(3) = 2 \text{ (1,2)}
ϕ(3)=2 (1,2)\phi(3) = 2 \text{ (1,2)}
\phi(7) = 6 \text{ (1,2,3,4,5,6)}
ϕ(7)=6 (1,2,3,4,5,6)\phi(7) = 6 \text{ (1,2,3,4,5,6)}
\phi(15) = 8 \text{ (1,2,4,7,8,11,13,14)}
ϕ(15)=8 (1,2,4,7,8,11,13,14)\phi(15) = 8 \text{ (1,2,4,7,8,11,13,14)}
\phi(5) = 4 \text{ (1,2,3,4)}
ϕ(5)=4 (1,2,3,4)\phi(5) = 4 \text{ (1,2,3,4)}
\phi(6) = 2 \text{ (1,5)}
ϕ(6)=2 (1,5)\phi(6) = 2 \text{ (1,5)}
\phi(2) = 1 \text{ (1)}
ϕ(2)=1 (1)\phi(2) = 1 \text{ (1)}
\phi(15) = \phi(3)\cdot\phi(5)
ϕ(15)=ϕ(3)ϕ(5)\phi(15) = \phi(3)\cdot\phi(5)
\phi(pq) = \phi(p)\cdot\phi(q)
ϕ(pq)=ϕ(p)ϕ(q)\phi(pq) = \phi(p)\cdot\phi(q)

(in general)

\phi(p) = p - 1
ϕ(p)=p1\phi(p) = p - 1

(if p is prime)

Version of Euler's Theorem for pq

\phi(pq) = (p-1)(q-1)
ϕ(pq)=(p1)(q1)\phi(pq) = (p-1)(q-1)

if:

n = pq
n=pqn = pq

then:

a^{(p-1)(q-1)} \equiv 1\text{ mod pq}
a(p1)(q1)1 mod pqa^{(p-1)(q-1)} \equiv 1\text{ mod pq}

Euler to Fermat

If p is prime, then Euler's theorem contains Fermat's as a special case:

a^{p-1} \equiv 1\text{ mod p}, p\nmid a
ap11 mod p,paa^{p-1} \equiv 1\text{ mod p}, p\nmid a

So let's pick a = 2.  If that monster number is prime, then we expect it to be 1 mod p.

p = 31987937737479355332620068643713101490952335301
p=31987937737479355332620068643713101490952335301p = 31987937737479355332620068643713101490952335301
2^{p-1} = 1281265953551359064133601216247151836053160074\text{ mod p}
2p1=1281265953551359064133601216247151836053160074 mod p2^{p-1} = 1281265953551359064133601216247151836053160074\text{ 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:

3^{218}\text{ mod 1000}
3218 mod 10003^{218}\text{ mod 1000}

Expand the exponent in base-2:

3^{218} = 3^{2 + 2^3 + 2^4 + 2^6 + 2^7} = 3^2\cdot3^{2^3}\cdot3^{2^4}\cdot3^{2^6}\cdot3^{2^7}
3218=32+23+24+26+27=323233243263273^{218} = 3^{2 + 2^3 + 2^4 + 2^6 + 2^7} = 3^2\cdot3^{2^3}\cdot3^{2^4}\cdot3^{2^6}\cdot3^{2^7}

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
489

Write 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.

218 = 11011010
218=11011010218 = 11011010
3^{218} = 3^2\cdot3^{2^3}\cdot3^{2^4}\cdot3^{2^6}\cdot3^{2^7}
3218=323233243263273^{218} = 3^2\cdot3^{2^3}\cdot3^{2^4}\cdot3^{2^6}\cdot3^{2^7}
3^{218} \equiv 9\cdot561\cdot721\cdot281\cdot961\text{ mod 1000} \equiv 489\text{ mod 1000}
32189561721281961 mod 1000489 mod 10003^{218} \equiv 9\cdot561\cdot721\cdot281\cdot961\text{ mod 1000} \equiv 489\text{ mod 1000}

Find "mod roots" is really hard

x^e \equiv c\text{ mod N}
xec mod Nx^e \equiv c\text{ mod N}

(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):

de \equiv 1\text{ mod (p-1)(q-1)}
de1 mod (p-1)(q-1)de \equiv 1\text{ mod (p-1)(q-1)}

Then, the unique solution is:

x \equiv c^d\text{ mod pq}
xcd mod pqx \equiv c^d\text{ mod pq}
x^e \equiv c\text{ mod pq}
xec mod pqx^e \equiv c\text{ mod pq}

Proof

x^e
xex^e
x \equiv c^d\text{ mod pq}
xcd mod pqx \equiv c^d\text{ mod pq}
x^e \equiv c^{de}
xecdex^e \equiv c^{de}
x^e \equiv (c^d)^e
xe(cd)ex^e \equiv (c^d)^e
x^e \equiv c^{1 + k(p-1)(q-1) }
xec1+k(p1)(q1)x^e \equiv c^{1 + k(p-1)(q-1) }
x^e \equiv c^1 \cdot c^{k(p-1)(q-1) }
xec1ck(p1)(q1)x^e \equiv c^1 \cdot c^{k(p-1)(q-1) }
x^e \equiv c^1 \cdot 1^k
xec11kx^e \equiv c^1 \cdot 1^k
x^e \equiv c\text{ mod pq}
xec mod pqx^e \equiv c\text{ mod pq}
\blacksquare
\blacksquare

(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.

\text{gcd}(4,15) = 1
gcd(4,15)=1\text{gcd}(4,15) = 1

So 4 has an inverse mod 15.  Since

4\cdot4 = 16 \equiv 1\text{ mod 15}
44=161 mod 154\cdot4 = 16 \equiv 1\text{ mod 15}

4 is its own inverse!  (mod 15)

\text{gcd}(7,11) = 1
gcd(7,11)=1\text{gcd}(7,11) = 1

So 7 has an inverse mod 11.  Since

7\cdot8 = 56 \equiv 1\text{ mod 11}
78=561 mod 117\cdot8 = 56 \equiv 1\text{ mod 11}
7^{-1} \equiv 8\text{ mod 11}
718 mod 117^{-1} \equiv 8\text{ mod 11}

Euclid's Algorithm

Euclid's algorithm for the GCD can also give you numbers u,v that satisfy

au + bv = \text{gcd}(a,b)
au+bv=gcd(a,b)au + bv = \text{gcd}(a,b)
\text{gcd}(18,24) = 6
gcd(18,24)=6\text{gcd}(18,24) = 6
18\cdot(-1) + 24\cdot1 = 6, u = -1, v=1
18(1)+241=6,u=1,v=118\cdot(-1) + 24\cdot1 = 6, u = -1, v=1
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

xy \equiv 1\text{ mod m}
xy1 mod mxy \equiv 1\text{ mod m}

But the definition of mod means this is equivalent to

xy = 1 \pm km\text{ , k an integer}
xy=1±km , k an integerxy = 1 \pm km\text{ , k an integer}
xy + km = 1
xy+km=1xy + km = 1

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

1583x \equiv 1\text{ mod 7918}
1583x1 mod 79181583x \equiv 1\text{ mod 7918}
\text{gcd}(1583, 7918) = 1
gcd(1583,7918)=1\text{gcd}(1583, 7918) = 1

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
1
x \equiv 5277\text{ mod 7918}
x5277 mod 7918x \equiv 5277\text{ mod 7918}

Something more fun

x^{9843} \equiv 134872\text{ mod 30069476293}
x9843134872 mod 30069476293x^{9843} \equiv 134872\text{ mod 30069476293}

Is 30069476293 prime?

2^{30069476293 - 1} \equiv 18152503626 \text{ mod 30069476293}
230069476293118152503626 mod 300694762932^{30069476293 - 1} \equiv 18152503626 \text{ mod 30069476293}

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
30069476293
30069476293 = p\cdot q = 104729\cdot 287117
30069476293=pq=10472928711730069476293 = p\cdot q = 104729\cdot 287117

Now it's easy to solve!

Solution

"Let p and q be distinct prime numbers,

and let e be coprime to (p-1)(q-1)."

de \equiv 1\text{ mod (p-1)(q-1)}
de1 mod (p-1)(q-1)de \equiv 1\text{ mod (p-1)(q-1)}
x \equiv c^d\text{ mod pq}
xcd mod pqx \equiv c^d\text{ mod pq}
x^e \equiv c\text{ mod pq}
xec mod pqx^e \equiv c\text{ mod pq}
p = 104729,q = 287117,e = 9843,c = 134872
p=104729,q=287117,e=9843,c=134872p = 104729,q = 287117,e = 9843,c = 134872

Is 9843 coprime to

(104729-1)(287117-1)?

>>> e = 9843
>>> p = 104729
>>> q = 287117
>>> print gcd(e, (p-1)*(q-1))
1

Yep.

9843d \equiv 1 \text{ mod (104729-1)(287117-1)}
9843d1 mod (104729-1)(287117-1)9843d \equiv 1 \text{ mod (104729-1)(287117-1)}

Use Euclid's algorithm

to get d:

>>> print invmod(e, (p-1)*(q-1))
18472798299 # mod (p-1)(q-1)
x \equiv 134872^{18472798299} \text{ mod 30069476293}
x13487218472798299 mod 30069476293x \equiv 134872^{18472798299} \text{ mod 30069476293}
>>> print expmod(134872, 18472798299, 30069476293)
25470280263
x \equiv 25470280263\text{ mod 30069476293}
x25470280263 mod 30069476293x \equiv 25470280263\text{ mod 30069476293}

Setup 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:

c \equiv m^e\text{ mod N}
cme mod Nc \equiv m^e\text{ mod N}

Third, Alice takes her message m and computes the ciphertext c, encrypted with Bob's public key (N,e):

c^d\text{ mod N}
cd mod Nc^d\text{ mod N}
de \equiv 1\text{ mod (p-1)(q-1)}
de1 mod (p-1)(q-1)de \equiv 1\text{ mod (p-1)(q-1)}

where:

RSA Example: Key Creation

Bob picks p and q.

p = 1223, q = 1987, N = pq = 2430101
p=1223,q=1987,N=pq=2430101p = 1223, q = 1987, N = pq = 2430101

He also picks e such that it's coprime to (p-1)(q-1).

e = 948047
e=948047e = 948047
>>> e = 948047
>>> p = 1223
>>> q = 1987
>>> print gcd(e, (p-1)*(q-1))
1

So (2430101, 948047) is Bob's public key.

RSA Example: Encryption

Alice wants to send Bob the message m = 1070777.

She calculates:

c \equiv m^e\text{ mod N}
cme mod Nc \equiv m^e\text{ mod N}
c \equiv 1070777^{948047} \text{ mod 2430101}
c1070777948047 mod 2430101c \equiv 1070777^{948047} \text{ mod 2430101}
>>> print expmod(1070777, 948047, 2430101)
1473513

She 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:

de \equiv 1\text{ mod (p-1)(q-1)}
de1 mod (p-1)(q-1)de \equiv 1\text{ mod (p-1)(q-1)}
>>> print invmod(e, (p-1)*(q-1))
1051235
c^d\text{ mod N}
cd mod Nc^d\text{ mod N}

Now he can recover the message:

>>> print expmod(1473513, 1051235, 2430101)
1070777

Bob 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: 

O(e^{\sqrt[3]{(ln N)\cdot (ln ln N)^2}})
O(e(lnN)(lnlnN)23)O(e^{\sqrt[3]{(ln N)\cdot (ln ln N)^2}})
Made with Slides.com