The affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using a simple mathematical function, and converted back to a letter.

Applications

  • Cryptanalysis
  • More complex Variations of Affine Cipher are used in practical cryptography

Complexity

  • Time: worst , = length of plain/cipher text
  • Space: worst , to create the new mapping (plain->cipher, cipher->plain)

References

Implementations

  • 1
    
    # TODO: Implement in Python
    
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    
    const plainText = 'secret';
    
    /*
     code assumes that plainText contains ONLY LOWER CASE ALPHABETS
     */
    
    Number.prototype.mod = function (n) {
      return ((this % n) + n) % n;
    };
    
    const keys = { a: 5, b: 7 };
    const N = 26;
    
    function encrypt(plainText) {
      let cypherText = '';
    
      function cryptAlpha(alpha) {
        const index = alpha.charCodeAt(0) - 'a'.charCodeAt(0);
        let result = ((keys.a * index) + keys.b).mod(N);
    
        console.log(`Index of ${alpha} = ${index}`);
    
        result += 'a'.charCodeAt(0);
        return String.fromCharCode(result);
      }
    
      console.log('Beginning Affine Encryption');
      console.log('Encryption formula: <b>((keys.a * indexOfAlphabet) + keys.b) % N</b>');
      console.log(`keys.a=${keys.a}, keys.b=${keys.b}, N=${N}`);
    
      for (const i in plainText) {
    
        cypherText += cryptAlpha(plainText[i]);
    
      }
    
      return cypherText;
    }
    
    function decrypt(cypherText) {
      let plainText = '';
      const aInverse = ((() => {
        for (let i = 1; i < N; i++) {
          if (((keys.a * i).mod(N)) === 1) {
            return i;
          }
        }
      })());
    
      console.log(`a<sup>-1</sup> = ${aInverse}`);
    
      function decryptAlpha(alpha) {
        const index = alpha.charCodeAt(0) - 'a'.charCodeAt(0);
        let result = (aInverse * (index - keys.b)).mod(N);
    
        console.log(`Index of ${alpha} = ${index}`);
    
        result += 'a'.charCodeAt(0);
        return String.fromCharCode(result);
      }
    
      console.log('Beginning Affine Decryption');
      console.log('Decryption formula: <b>(a<sup>-1</sup> * (index - keys.b)) % N</b>');
      console.log(`keys.b=${keys.b}, N=${N}`);
    
      for (const i in cypherText) {
    
        plainText += decryptAlpha(cypherText[i]);
    
      }
    
      return plainText;
    }
    
    const cipherText = encrypt(plainText);
    ctTracer.set(cipherText);
    decrypt(cipherText);