```
> module FSAlab5
> where
> import Data.List
> import System.Random
> import FSA5
```

**Note**

For the exercises below you will have to modifiy both the `FSAlab5.hs`

lab file and the `FSA5.hs`

lecture file. In the lecture file, some function implementations were replaced by `error "not yet implemented"`

. In all those places, there is work for you to do.

**Exercise 1**

Implement a function

` exM :: Integer -> Integer -> Integer -> Integer`

that does modular exponentiation of \(x^y\) in polynomial time, by repeatedly squaring modulo \(N\).

E.g., \(x^{33} \mod 5\) can be computed by means of

\[ x^{33} \pmod 5 = x^{32} \pmod 5 \times x \pmod 5. \]

\(x^{32} \pmod N\) is computed in five steps by means of repeatedly squaring modulo \(N\):

\[ x \pmod N \rightarrow x^2 \pmod N \rightarrow x^4 \pmod N \rightarrow \ldots \rightarrow x^{32} \pmod N. \]

If this explanation is too concise, look up the explanation in the lecture notes, plus other relevant literature.

**Exercise 2**

Check that your implementation is more efficient than `expM`

by running a number of relevant tests and documenting the results.

**Exercise 3**

In order to test Fermat's Primality Check (as implemented in function `primeTestF`

), the list of prime numbers generated by Eratosthenes' sieve is useless, for Fermat's Primality Check correctly classify the primes as primes. Where the check can go wrong is on classifying composite numbers; these can slip through the Fermat test.

Write a function `composites :: [Integer]`

that generates the infinite list of composite natural numbers.

**Exercise 4**

Use the list of composite numbers to test Fermat's primality check. What is the least composite number that you can find that fools the check, for `primeTestsF k`

with \(k = 1, 2, 3\) ? What happens if you increase \(k\)?

**Exercise 5**

Use the list generated by the following function for a further test of Fermat's primality check.

```
> carmichael :: [Integer]
> carmichael = [ (6*k+1)*(12*k+1)*(18*k+1) |
> k <- [2..],
> prime (6*k+1),
> prime (12*k+1),
> prime (18*k+1) ]
```

Read the entry on Carmichael numbers on Wikipedia to explain what you find. If necessary, consult other sources.

**Exercise 6**

Implement the algorithm of Rabin and Miller (Miller 1976,Rabin (1980)), which gives a version of probabilistic primality testing that cannot by fooled by Carmichael numbers. See the explanation in the lecture notes, plus Rabin primality test. Next, use the list afrom the previous exercise to test the Miller-Rabin primality check. What do you find?

**Exercise 7**

You can use the Miller-Rabin primality check to discover some large Mersenne primes. The recipe: take a prime \(p\), and use the Miller-Rabin algorithm to check whether \(2^p - 1\) is also prime. Find information about Mersenne primes on internet and check whether the numbers that you found are genuine Mersenne primes. Report on your findings.

**Exercise 8**

Complete the implementation of the Diffie-Helman key exchange protocol from the lecture notes, and explain how it works by means of a number of examples, using some large prime.

See trapdoor function and (Diffie and Hellman 1976). You may assume that you have a large prime available that you can keep secret.

**Exercise 9**

For the final exercise you will need modular division and the extended Euclidean algorithm for gcd. See the lecture notes for explanation. You can use `invM`

and `fctGcd`

from the lecture notes.

In the Diffie-Hellman style trapdoor function the secret prime has to be available, so we cannot make the full recipe for constructing the encoding function publicly available. In public key cryptography, it turns out we can do much better than this. We can generate a key and make it publicly available, and from that key anyone can construct an encoding function. Decoding, given only this public key information, is thought to be hard. This is the basis for RSA public key cryptography (Rivest, Shamir, and Adleman 1978).

Implement RSA coding and decoding.

The type declarations you need are:

` rsaPublic :: Integer -> Integer -> (Integer,Integer)`

`rsaPublic`

takes a pair of large primes and generates a public key pair of which the second element is the product of the primes.

` rsaPrivate :: Integer -> Integer -> (Integer,Integer)`

`rsaPrivate`

should generates a private key pair from a pair of large primes. Again, the second element of the output is the product of the input primes.

` rsaEncode :: (Integer,Integer) -> Integer -> Integer`

`rsaEncode`

should use a public key pair to encode a message (represented by an integer).

RSA decoding using a private key is just a matter of using the private key to encode again, so we have:

` rsaDecode = rsaEncode `

Explain why `rsaEncode`

is a genuine trapdoor function.

**Bonus Exercise**

Use the above for a demonstration of:

selection of a suitable pair of primes \(p,q\) with the same bitlength,

public key and private key generation based on \(p,q\),

use of these keys for text message encoding and decoding.

Diffie, W., and M. Hellman. 1976. “New Directions in Cryptography.” *IEEE Transactions on Information Theory* 22 (6): 644–54.

Miller, Gary L. 1976. “Riemann’s Hypothesis and Tests for Primality.” *Journal of Computer and System Sciences* 13 (3): 300–317.

Rabin, Michael O. 1980. “Probabilistic Algorithm for Testing Primality.” *Journal of Number Theory* 12 (1): 128–38.

Rivest, R., A. Shamir, and L. Adleman. 1978. “A Method for Obtaining Digital Signatures and Public-Key Cryptosystems.” *Communications of the ACM* 21 (2): 120–26.