Lecture 35: RSA

Public key cryptography

The goal of public key cryptography is to transmit secrets over a completely public channel with no coordination before hand.

We assume there is a sender who has a message that they want to transmit to a recipient, with no other party able to observe the contents of the message. To accomplish this, the recipient generates a public/private key pair. They broadcast the public key to everybody, and keep the private key to themselves.

The goal of the cryptosystem is that anybody with the public key can use it to encrypt a message so that only somebody with the private key can decrypt it.

RSA

RSA is a particular public key cryptography scheme. The idea is simple: the public key consists of a large modulus \(m \in \mathbb{Z}\) and a unit \([k] \in \mathbb{Z}_{φ(m)}\).

The private key is the inverse of \([k]\) mod \(φ(m)\).

To encrypt a message \(msg\) (sometimes referred to as the plaintext), the sender first breaks the message into pieces, each of which is a number that is smaller than \(m\); from now on, we will assume \(0 \leq msg \lt m\). This way, if the recipient computes the unique representative of \([msg]_m\) that is between \(0\) and \(m\), they will have the message.

The encrypted message (often referred to as the cyphertext) is simply \(c = [msg]^{[k]}\).

To decrypt, the recipient computes \(c^{[k]^{-1}}\). By definition, this is \(([msg]^{[k]})^{[k^{-1}]} = [msg]^{[k][k]^{-1}}\). By Euler's theorem, we can do arithmetic in the exponent as long as we consider the elements as equivalence classes mod \(φ(m)\); this tells us that \([msg]^{[k][k]^{-1}} = [msg]^{[1]} = [msg]\).

Security based on efficiency

At first glance, this scheme doesn't seem secure. An attacker knows \(m\) and \(k\), so they can compute \(φ(m)\) (for example by factoring \(m\), or even enumerating the elements of \(\mathbb{Z}_m\) and checking whether each is a unit). They can then use the Bezout coefficients to compute \(k^{-1}\), and can then do anything the recipient can.

The security of RSA depends on the assumption that these operations take exponential time in the size of the keys, but that the operations that the "good guys" (the sender and recipient) need to perform can be computed in polynomial time.

This means that no matter how fast the attacker's computer is, the recipient can always add a few digits to the key to increase the attacker's computational work by a factor of \(10^{\text{a few}}\); if the attacker takes 5 minutes to compute \([k]^{-1}\), the recipient can easily add a few digits to raise this to years, or even decades or millenia. Of course, it will also increase the time it takes the sender and receiver to encrypt and decrypt, but it will not raise them exponentially; a few extra digits will only add a small amount of extra work.

The steps, in some detail

Here we list the protocol in some detail. Since the security depends on the efficiency of the operations performed by the good guys, we sketch algorithms for each of the necessary operations.

  1. First the recipient chooses large primes \(p\) and \(q\).
  1. Then, they multiply them to find \(m\)
  1. Then, they compute \(φ(m)\).
  1. Then, they choose a unit \([k]\) of \(\mathbb{Z}_{φ(m)}\).
  1. They also need to compute \([k]^{-1}_{φ(m)}\).
  1. They transmit \([k]\) and \(m\) to the world.
  1. The sender computes \(c = [msg]^k_m\)
  1. The sender broadcasts \(c = [msg]^k_m\)

    • Again, we can represent \([msg]\) by \(rem(msg,m)\); it is just a number between \(0\) and \(m\)
  2. The recipient raises \(c^{[k]^{-1}}\)

    • Using the exponentiation algorithm described above.

What can the attacker do?

The attacker sees \(c\), \(m\), and \(k\). We lose the game if they can (efficiently) compute \(msg\).

If they can compute any of the intermediate parts of the computation that the reciever uses, they can simulate the receiver. For example, if they know \(p\), they can divide \(m\) by \(p\) to find \(q\), and can then compute \(φ(m)\), and then \([k]^{-1}\), just like the recipient. Even without \(p\) and \(q\), if they know \(φ(m)\), they can still compute \(k^{-1}\).

The best known algorithms for factoring take exponential time. It is widely believed that any algorithm to factor a number will take exponential time, but nobody has yet been able to prove this.

Note that it is easy to write an efficient non-deterministic algorithm for decryption: Start by guessing \(p\) and \(q\), then check that \(m = pq\). Not only is it not known whether factoring can be done efficiently, it is not even known whether there are any problems that can be solved efficiently non-deterministically but can't be solved efficiently deterministically.

This problem is stated concisely by asking whether "\(P = NP\)"; \(P\) is the class of problems that can be solved deterministically in polynomial time, while \(NP\) is the class of problems that can be solved non-deterministically in polynomial time.

\(P = NP\) is literally one of the "million dollar questions": the Clay Institute has offered a one million dollar prize if you can prove or disprove it. However, if you are able to prove or disprove it, you can probably do much better than a million dollars, either by breaking into everybody's bank account or by developing and selling technology based on your proof.