## RCM3720 Cryptography, Network and Computer Security

### Laboratory Class 4: Simple Cryptosystems

We have experimented with the Caesar cipher and the more general translation cipher. We shall start looking at the Vigenère cipher. The trick is to add the correct letter of the code to the letter of the key:

     Index of plain text i: 1  2  3  4  5  6  7  8
                 Plaintext: W  I  T  H  D  R  A  W
                       Key: C  O  D  E  C  O  D  E
            Index of key j: 1  2  3  4  1  2  3  4

The indices of the key repeat 1, 2, 3, 4. We can get a repetition of length four by using a modulus of 4:

                         i: 1  2  3  4  5  6  7  8
                 i (mod 4): 1  2  3  0  1  2  3  0

What we need to do is to subtract one before the modulus, and add one after:

                         i: 1  2  3  4  5  6  7  8
                       i-1: 0  1  2  3  4  5  6  7
               i-1 (mod 4): 0  1  2  3  0  1  2  3
           i-1 (mod 4) + 1: 1  2  3  4  1  2  3  4

This means that in the Vigenère cipher, we add the i-th character of the plaintext, and the j-th character of the key, where

       j=i-1 (mod n) + 1

with n being the length of the key.

- First read in the `rcm3720.input` file you have created:
  - )read rcm3720
  You may have to include the full path here.
- Enter a plaintext
  - plaintext:="WITHDRAWONEHUNDREDDOLLARS"
- and a keyword:
  - key := "CODE"
- Now we can obtain the lengths of the plaintext and key with the hash symbol:
  - pn:=#plaintext
  - kn:=#key
- Turn both plaintext and key into lists of numbers:
  - pl:=str2lst(plaintext)
  - kl:=str2lst(key)
- Now we can add them using the formula for `j` above to obtain the list corresponding to the ciphertext:
  - cl:=[(pl.i+kl.((i-1) rem kn+1))::ZMOD 26 for i in 1..pn]
- And obtain the ciphertext (we need to convert our list to a list of integers first):
  - ciphertext:=lst2str(cl::List INT)
- Try a few other Vigenère encryptions.
- To decrypt, we just subtract the key value from the ciphertext value:
  - pl:=[(cl.i+kl.((i-1) rem kn+1))::ZMOD 26 for i in 1..pn]
  - lst2str(pl::List INT)
- Now for the Hill (matrix) cipher. We shall use `3 x 3` matrices, so first create a plaintext whose length is a multiple of 3:
  - plaintext:="WITHDRAWONEHUNDREDDOLLARSXX"
  - pl:=str2lst(plaintext)
  - r:=3
  - c:INT:=#pl/r
- The values `r` and `c` are the row and column numbers of the plaintext matrix.
- Now put all the plaintext values into a `r x c` matrix:
  - S:=matrix([[pl.(r*(i-1)+j) for i in 1..c] for j in 1..r])
- Create the key matrix:
  - M:Matrix ZMOD 26:=matrix([[22,11,19],[15,20,24],[25,21,16]])
- Multiply the two matrices:
  - C:=M*S
- Notice how the results are automatically reduced modulo 26, because that is how the matrix `M` was defined.
- Now we have to read off the elements of `C` into a single list; this can be done by transposing the matrix, and reading off the rows as lists:
  - CL:=concat(transpose(C)::List List ZMOD 26)
- And finally turn into ciphertext:
  - lst2str(CL::List INT)
- Finally, here's how we can invert our matrix `M` modulo 26:
  - adj:=adjoint(M).adjMat
  - invdet:=recip(determinant(M))
  - MI:=invdet*adj
- Or alternatively, as one command:
  - MI:=recip(determinant(M))*adjoint(M).adjMat
- Check the result:
  - M*MI