|
1 | | -# Instructions |
| 1 | +# Description |
2 | 2 |
|
3 | 3 | Create an implementation of the affine cipher, |
4 | 4 | an ancient encryption system created in the Middle East. |
5 | 5 |
|
6 | | -The affine cipher is a type of monoalphabetic substitution cipher. |
| 6 | +The affine cipher is a type of mono-alphabetic substitution cipher. |
7 | 7 | Each character is mapped to its numeric equivalent, encrypted with |
8 | 8 | a mathematical function and then converted to the letter relating to |
9 | | -its new numeric value. Although all monoalphabetic ciphers are weak, |
10 | | -the affine cypher is much stronger than the atbash cipher, |
| 9 | +its new numeric value. Although all mono-alphabetic ciphers are weak, |
| 10 | +the affine cipher is much stronger than the atbash cipher, |
11 | 11 | because it has many more keys. |
12 | 12 |
|
| 13 | +## Encryption |
| 14 | + |
13 | 15 | The encryption function is: |
14 | 16 |
|
15 | | - `E(x) = (ax + b) mod m` |
16 | | - - where `x` is the letter's index from 0 - length of alphabet - 1 |
17 | | - - `m` is the length of the alphabet. For the roman alphabet `m == 26`. |
18 | | - - and `a` and `b` make the key |
| 17 | +```text |
| 18 | +E(x) = (ai + b) mod m |
| 19 | +``` |
| 20 | + |
| 21 | +- where `i` is the letter's index from `0` to the length of the alphabet - 1 |
| 22 | +- `m` is the length of the alphabet. For the Roman alphabet `m` is `26`. |
| 23 | +- `a` and `b` are integers which make the encryption key |
| 24 | + |
| 25 | +Values `a` and `m` must be *coprime* (or, *relatively prime*) for automatic decryption to succeed, |
| 26 | +ie. they have number `1` as their only common factor (more information can be found in the |
| 27 | +[Wikipedia article about coprime integers](https://en.wikipedia.org/wiki/Coprime_integers)). In case `a` is |
| 28 | +not coprime to `m`, your program should indicate that this is an error. Otherwise it should |
| 29 | +encrypt or decrypt with the provided key. |
| 30 | + |
| 31 | +For the purpose of this exercise, digits are valid input but they are not encrypted. Spaces and punctuation |
| 32 | +characters are excluded. Ciphertext is written out in groups of fixed length separated by space, |
| 33 | +the traditional group size being `5` letters. This is to make it harder to guess encrypted text based |
| 34 | +on word boundaries. |
| 35 | + |
| 36 | +## Decryption |
19 | 37 |
|
20 | 38 | The decryption function is: |
21 | 39 |
|
22 | | - `D(y) = a^-1(y - b) mod m` |
23 | | - - where `y` is the numeric value of an encrypted letter, ie. `y = E(x)` |
24 | | - - it is important to note that `a^-1` is the modular multiplicative inverse |
25 | | - of `a mod m` |
26 | | - - the modular multiplicative inverse of `a` only exists if `a` and `m` are |
27 | | - coprime. |
| 40 | +```text |
| 41 | +D(y) = (a^-1)(y - b) mod m |
| 42 | +``` |
| 43 | + |
| 44 | +- where `y` is the numeric value of an encrypted letter, ie. `y = E(x)` |
| 45 | +- it is important to note that `a^-1` is the modular multiplicative inverse (MMI) |
| 46 | + of `a mod m` |
| 47 | +- the modular multiplicative inverse only exists if `a` and `m` are coprime. |
28 | 48 |
|
29 | | -To find the MMI of `a`: |
| 49 | +The MMI of `a` is `x` such that the remainder after dividing `ax` by `m` is `1`: |
30 | 50 |
|
31 | | - `an mod m = 1` |
32 | | - - where `n` is the modular multiplicative inverse of `a mod m` |
| 51 | +```text |
| 52 | +ax mod m = 1 |
| 53 | +``` |
33 | 54 |
|
34 | 55 | More information regarding how to find a Modular Multiplicative Inverse |
35 | | -and what it means can be found [here.](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse) |
| 56 | +and what it means can be found in the [related Wikipedia article](https://en.wikipedia.org/wiki/Modular_multiplicative_inverse). |
36 | 57 |
|
37 | | -Because automatic decryption fails if `a` is not coprime to `m` your |
38 | | -program should return status 1 and `"Error: a and m must be coprime."` |
39 | | -if they are not. Otherwise it should encode or decode with the |
40 | | -provided key. |
| 58 | +## General Examples |
41 | 59 |
|
42 | | -The Caesar (shift) cipher is a simple affine cipher where `a` is 1 and |
43 | | -`b` as the magnitude results in a static displacement of the letters. |
44 | | -This is much less secure than a full implementation of the affine cipher. |
| 60 | +- Encrypting `"test"` gives `"ybty"` with the key `a = 5`, `b = 7` |
| 61 | +- Decrypting `"ybty"` gives `"test"` with the key `a = 5`, `b = 7` |
| 62 | +- Decrypting `"ybty"` gives `"lqul"` with the wrong key `a = 11`, `b = 7` |
| 63 | +- Decrypting `"kqlfd jzvgy tpaet icdhm rtwly kqlon ubstx"` gives `"thequickbrownfoxjumpsoverthelazydog"` with the key `a = 19`, `b = 13` |
| 64 | +- Encrypting `"test"` with the key `a = 18`, `b = 13` is an error because `18` and `26` are not coprime |
45 | 65 |
|
46 | | -Ciphertext is written out in groups of fixed length, the traditional group |
47 | | -size being 5 letters, and punctuation is excluded. This is to make it |
48 | | -harder to guess things based on word boundaries. |
| 66 | +## Example of finding a Modular Multiplicative Inverse (MMI) |
49 | 67 |
|
50 | | -## General Examples |
| 68 | +Finding MMI for `a = 15`: |
51 | 69 |
|
52 | | - - Encoding `test` gives `ybty` with the key a=5 b=7 |
53 | | - - Decoding `ybty` gives `test` with the key a=5 b=7 |
54 | | - - Decoding `ybty` gives `lqul` with the wrong key a=11 b=7 |
55 | | - - Decoding `kqlfd jzvgy tpaet icdhm rtwly kqlon ubstx` |
56 | | - - gives `thequickbrownfoxjumpsoverthelazydog` with the key a=19 b=13 |
57 | | - - Encoding `test` with the key a=18 b=13 |
58 | | - - gives `Error: a and m must be coprime.` |
59 | | - - because a and m are not relatively prime |
60 | | - |
61 | | -## Examples of finding a Modular Multiplicative Inverse (MMI) |
62 | | - |
63 | | - - simple example: |
64 | | - - `9 mod 26 = 9` |
65 | | - - `9 * 3 mod 26 = 27 mod 26 = 1` |
66 | | - - `3` is the MMI of `9 mod 26` |
67 | | - - a more complicated example: |
68 | | - - `15 mod 26 = 15` |
69 | | - - `15 * 7 mod 26 = 105 mod 26 = 1` |
70 | | - - `7` is the MMI of `15 mod 26` |
| 70 | +- `(15 * x) mod 26 = 1` |
| 71 | +- `(15 * 7) mod 26 = 1`, ie. `105 mod 26 = 1` |
| 72 | +- `7` is the MMI of `15 mod 26` |
0 commit comments