Attacks on RSA and Primality Testing

September 29, 2022

Prime numbers

Implementing RSA

How can we generate large prime numbers?

  1. Choose a large, odd, random number.
  2. Test to see if it is prime. If not, add 2 and repeat.

The hard part is going to be determining if a large number is prime.

Some prime number theorems

  • There are infinitely many primes. (Euclid, 300 BC) Proof by contradiction.
  • The Prime Number Theorem. (Hadamard, 1896)
    • The \(n\)th prime is approximately (asymptotically) \(n \ln n\).
    • The number of primes less than \(x\) is approximately (asymptotically) \(\displaystyle{\frac{x}{\ln x}}\).
    • Short proof

\[ \lim_{x \rightarrow \infty} \frac{\pi(x)}{x/\ln x} = 1 \]

Testing primality

  • Exhaustive search for factors:
    • Keep a big list of primes.
    • To determine if a given \(n\) is prime, test all the prime numbers up to \(\sqrt{n}\) to see if any divide \(n\).
  • Exercise: If \(n\) has 100 digits, how big will this list need to be (roughly)?
    • Fact needed: The number of primes less than \(x\) is approximately \(\displaystyle{\frac{x}{\ln x}}\).

Recall Euler’s Theorem

Euler’s Theorem: If \(\gcd(a,n)=1\), then \(a^{\phi(n)} \equiv 1 \pmod n\).

An immediate corollary is known as Fermat’s Little Theorem. (FlT)

If \(p\) is prime, then \(a^{p-1} \equiv 1 \pmod{p}\), for any \(a < p\).

Contrapositive of FlT

bigNumber <- as.bigz("2759906923170465870349284572513444495119639631
                     59159755581777302729039253474767543706477020042
                     97818745287627330276222679878256760119559870281
                     13146956853126194280414475892676777659939564742
                     44785168959704762122652461722078612423678394923
                     32839718788654764956662118459134315194058852873
                     11045581942871881388186309640860418454846129570
                     91247592793784631777384902156354032599108753489
                     93476673140050791456486240379352438607931317122
                     29805074199522231082822668601073716264370514378
                     45187017123708751530264674793463510019061497797
                     88166169654875208818278825075813161445176049456
                     40971682725620759622798463427777619513770932520
                     2107521")
powm(17, bigNumber-1, bigNumber)
Big Integer ('bigz') :
[1] 6650140431333936275382041721808523637610817926201174971655682582373050059109600551992218941686565785857011437452363736100304169594731029823418537817232472681814143581065829312812108472548201636126316461647218250893826807146200727521137303598994539754634905622275999866697219492970559639020312750360994307177973929091146545550583093401543392278759758266989803193943617891823656313378285385606452416950277605820361151614300838123484869032516947256779541663798577904408564545271133852054854244776651151502008515020913021241218501084304700788482525430498285154732279036303519438570143410212271309996052070997255806251

What can you conclude?

What can you conclude?

powm(2, 562, 563)
Big Integer ('bigz') :
[1] 1
powm(2, 560, 561)
Big Integer ('bigz') :
[1] 1

Fermat Primality Test

To test to see if \(n\) is prime,

  1. Choose \(a < n\).
  2. Compute \(x = a^{n-1} \bmod n\).
  3. If \(x\neq 1\), then \(n\) is composite. If \(x=1\) then \(n\) is “probably” prime.

Fermat (Weak) Pseudoprimes

A probable prime that isn’t prime is called a “pseudoprime”.

More precisely, if \(a^{n-1} \equiv 1 \pmod{n}\), and \(n\) is composite, then \(n\) is a (weak) pseudoprime for the base \(a\).

For example, 561 is a pseudoprime for the base 2. Pseudoprimes make up a tiny fraction of any range of numbers (but not tiny enough).

Square roots of 1?

How many \(x\) satisfy \(x^2 = 1\) in…

  • \(\mathbb{Z}_5\)?
  • \(\mathbb{Z}_6\)?
  • \(\mathbb{Z}_7\)?
  • \(\mathbb{Z}_8\)?

Only two square roots of 1 in \(\mathbb{Z}_p\)

Lemma 1. If there is some \(x\) in \(\mathbb{Z}_n\) such that \(x^2 = 1\) but \(x\neq \pm 1\), then \(n\) is composite.

Sketch Proof: Let \(d = \mbox{gcd}(x - 1, n)\). Show that \(d \neq 1\).

Improving the Fermat Primality Test

Lemma 1. If there is some \(x\) in \(\mathbb{Z}_n\) such that \(x^2 = 1\) but \(x\neq \pm 1\), then \(n\) is composite.

Example. \(42^{204} \equiv 1 \pmod{205}\), so \(205\) is a pseudoprime for the base \(42\).

Note that \(204 = 51 \cdot 2 \cdot 2\). Instead of raising to the 204th power all at once, we proceed bit by bit:

\[ \begin{aligned} 42^{51} &\equiv 83 \pmod{205} \\ 83^{2} &\equiv 124 \pmod{205} \\ 124^{2} &\equiv 1 \pmod{205} \end{aligned} \]

Apply lemma.

Miller-Rabin Primality Test

To test to see if \(n\) is prime, write \(n-1 = 2^km\), where \(m\) is odd. Choose \(a<n-1\) randomly. The following computations are done in \(\mathbb{Z}_n\).

Let \(b_0 = a^m\).

  • If \(b_0 = \pm 1\), then \(n\) is probably prime. Stop.

Otherwise, let \(b_1 = b_0^2\).

  • If \(b_1 = 1\), then \(n\) is composite. Stop.
  • If \(b_1 = -1\), then \(n\) is probably prime. Stop.

Otherwise, let \(b_2 = b_1^2\).

  • If \(b_2 = 1\), then \(n\) is composite. Stop.
  • If \(b_2 = -1\), then \(n\) is probably prime. Stop.

Continue, if necessary, until reaching \(b_{k-1}\). If \(b_{k-1}\neq -1\), then \(n\) is composite. Otherwise, \(n\) is probably prime.

Group Exercise

Step through Miller-Rabin for 561.

Strong Pseudoprimes

If a composite \(n\) is found to be probably prime by the Miller-Rabin test using the number \(a\), it is called a strong pseudoprime for the base \(a\).

Strong pseudoprimes are very, very rare. So repeated applications of Miller-Rabin will determine primality with such a low probability of error as to be considered zero. According to the OpenSSL specification,

Both BN_is_prime_ex() and BN_is_prime_fasttest_ex() perform a Miller-Rabin probabilistic primality test with nchecks iterations. If nchecks == BN_prime_checks, a number of iterations is used that yields a false positive rate of at most \(2^{-80}\) for random input.

More RSA considerations

Attacks on RSA

An RSA implementation is vulnerable if

  • \(n\) can be easily factored. (factorization attack)
  • \(e\) or \(d\) is too small. (low exponent attack)
  • \(m\) is too small. (short plaintext attack)
  • Eve can observe how long decryption takes. (timing attack)

Factorization Attacks

Fermat’s Factorization Method:

Suppose \(n=pq\) and \(p\) and \(q\) are approximately the same size.

  1. Calculate \(n+i^2\) for \(i=1,2,3,\ldots\) until you get a perfect square.

  2. If \(n+i^2 = k^2\), then \(n=k^2-i^2= (k-i)(k+i)\).

Prevention: Check that \(p\) and \(q\) are far enough apart. (\(10^{100}\))

Exponent factorization attack

Step through the Miller-Rabin test for some choice of \(a\). If at some point \(b_i = 1\) for \(i>0\), then \(\gcd(b_{i-1}, n)\) is a factor of \(n\).

Write \(n-1 = 2^km\), where \(m\) is odd. Let \(b_0 = a^m\).

  • If \(b_0 = \pm 1\), then \(n\) is probably prime. Stop.

Otherwise, let \(b_1 = b_0^2\).

  • If \(b_1 = 1\), then \(n\) is composite. Stop. GCD is a factor.
  • If \(b_1 = -1\), then \(n\) is probably prime. Stop.

Otherwise, let \(b_2 = b_1^2\).

  • If \(b_2 = 1\), then \(n\) is composite. GCD is a factor.
  • If \(b_2 = -1\), then \(n\) is probably prime. Stop. etc.

Quadratic Sieve

Lemma 2. If there are some \(x\) and \(y\) in \(\mathbb{Z}_n\) such that \(x^2=y^2\) but \(x\neq \pm y\), then \(n\) is composite, and \(\gcd(x-y,n)\) is a factor.

Idea: Search for \(x\) and \(y\) by looking at products of squares of small primes.

Prevention: Make sure \(p-1\) and \(q-1\) don’t have only small prime factors.

Low Exponent Attacks

If the exponent \(e\) is chosen too small, and Eve can observe the same \(m\) encrypted with several different keys \(n_1, n_2, \ldots\), then Eve can solve a system of equations for \(m\). \[ \begin{aligned} c_1 &= m^e \bmod n_1 \\ c_2 &= m^e \bmod n_2 \\ \vdots \\ \end{aligned} \] Only possible if \(m^e\) is less than the product of the \(n_i's\).

Prevention: Use “large” \(e\). (65537)

Short plaintext attack

If the plaintext is known to be a small number, Eve can use brute force to find it by encrypting all the small plaintexts. Even better, in \(\mathbb{Z}_n\)

  • Make a list of \(cx^{-e}\) for \(x = 1, 2, \ldots\).
  • Make a list of \(y^e\) for \(y = 1, 2, \ldots\).

If Eve finds a match, then \(c = (xy)^e\), so \(xy\) is the plaintext.

Prevention: padding.

Padding

  • Block ciphers work one block at a time.
  • Some block cipher modes (e.g., ECB, CBC) also work one block at a time.
  • If the plaintext is not an integral number of blocks, you need to pad it to make it so.
    • How do you decrypt? Make the padding say how many bytes you added. (e.g. 03 03 03)
    • Decrypt, then throw away padding.
  • Problem: if the plaintext is an integral number of blocks, and you don’t pad it, decryption might think it has to throw away padding.
    • Solution: pad an integral number of blocks with a whole block of padding.
    • i.e., you always pad, so you always throw away padding when decrypting.

Programming assignment

Returning a bunch of things in a list:

makeRSAkey <- function() {
  p <- NA # TODO
  q <- NA # TODO
  e <- as.bigz("65537")
  d <- NA # TODO
  return(list(n=p*q, p=p, q=q, e=e, d=d))
}

Written assignment