Cryptography - Affine Cipher



Now we will learn Affine Cipher and its encryption and decryption algorithms. The Affine Cipher is an illustration of a Monoalphabetic Substitution cipher. It is a sort of encryption strategy. It is too like a secret code that changes sensitive content into encoded form.

In the Affine Cipher, each letter in the message is replace by another letter by taking after a straightforward numerical equation. In this algorithm we increase the letter's position in the letter set by a number and at that point include it with another number to it. This handle changes the message so that as it were somebody who knows the right numbers can translate it back into its unique form.

Since the encryption strategy is basically mathematical, it separates a bit from the other cases we have seen however. The entire process depends on working modulo m where m is the length of the character set. We translate the plaintext by applying an equation to the plaintext characters.

Encryption of Affine Cipher

Transforming each letter in the plaintext letter set into its comparing numbers in the range of 0 to M-1 is to begin with arrange in the encryption handle. Once this is done, the process of encryption for each letter is given by

E(x) = (Ax + B) mod M

where,

  • E is the encrypted message.

  • x is the position of the letter in the letter set (e.g., A=0, B=1, C=2, ..., Z=25)

  • A and B are the cipher's keys. This demonstrates that we include B to the result after multiplying our numbers value for the plaintext letter by A.

  • M shows modulus.

(That is, we discover the remainder portion when we divide the big number by the length of the letter set. This makes beyond any doubt that our unused letters remain inside the alphabet).

Decryption of Affine Cipher

When we've to decipher a ciphertext translated with the help of the Affine Cipher encryption system, we will have to do the contrary process of what we've done to cipher it. The first step is to convert each ciphertext letter back into its number value, just like we did when we translated the communication.

Then, to decrypt each number, we use this formula −

D(x)= C(x − B) mod M

where,

  • D represents the decrypted message.

  • x shows the number we got from the ciphertext letter.

  • B represents the number we have added at the time of encryption to shift the letters.

  • C is a special number called the modular multiplicative inverse of A. It is a number that, when we multiply it by A and keep subtracting the length of the alphabet, we get to 1.

  • M is modulus or length or the alphabets.

Let us see the below image to understand the encryption and decryption process in a simple way.

basic implementation of affine cipher

Implementation using Python

Now we will implement affine encryption and decryption programs using different methods −

  • Using Dictionary Mapping

  • Using Predefined Keys

So we will see all the above methods and their implementation in Python in the following sections −

Using Dictionary Mapping

In this example we will use dictionary mapping to create an affine cipher algorithm using Python. The process of dictionary mapping requires converting every alphabet letter to its equivalent, in both cases decryption or encryption.

Our encryption and decryption mathematical formula provides the starting point for this mapping in the Affine Cipher. The alphabet's original letters work as the dictionary's keys, and their encrypted or decrypted versions act as the values. The encrypted or decrypted letter for each letter in the plaintext or ciphertext can be accessed using this dictionary within the code.

Example

Following is a Python implementation for affine cipher encryption and decryption algorithm using dictionary mapping. Please check the code below −

# Encryption function
def affine_encrypt(text, a, b):
   encrypted_text = ""
   for char in text:
      if char.isalpha():
         if char.isupper():
            encrypted_text += chr(((a * (ord(char) - ord('A')) + b) % 26) + ord('A'))
         else:
            encrypted_text += chr(((a * (ord(char) - ord('a')) + b) % 26) + ord('a'))
      else:
         encrypted_text += char
   return encrypted_text

# Decryption function
def affine_decrypt(text, a, b):
   decrypted_text = ""
   m = 26
   a_inv = pow(a, -1, m)
   for char in text:
      if char.isalpha():
         if char.isupper():
            decrypted_text += chr(((a_inv * (ord(char) - ord('A') - b)) % 26) + ord('A'))
         else:
            decrypted_text += chr(((a_inv * (ord(char) - ord('a') - b)) % 26) + ord('a'))
      else:
         decrypted_text += char
   return decrypted_text

# plain text message and keys
plain_text = "Nice to meet you!"
a = 5
b = 8

encrypted_text = affine_encrypt(plain_text, a, b)
print("Our Encrypted text:", encrypted_text)

decrypted_text = affine_decrypt(encrypted_text, a, b)
print("Our Decrypted text:", decrypted_text)

Following is the output of the above example −

Input/Output
Our Encrypted text: Vwsc za qccz yae!
Our Decrypted text: Nice to meet you!

Using Predefined Keys

This code executes the Affine Cipher process for encoding and decoding content. It uses a predefined key in the KEY variable for encryption and decryption. This variable is a tuple containing three values: (7, 3, 55). These values show the encryption and decryption key for the Affine Cipher. We will moreover have another variable called DIE which represents the character set size (128).

Example

Here is a Python implementation for affine cipher encryption and decryption algorithm using predefined keys. Check the code below −

# Affine cipher Class
class affine_cipher(object):
   DIE = 128
   KEY = (7, 3, 55)

   def __init__(self):
     pass

   def encryptChar(self, char):
      K1, K2, kI = self.KEY
      return chr((K1 * ord(char) + K2) % self.DIE)

   def encrypt(self, string):
      return "".join(map(self.encryptChar, string))

   def decryptChar(self, char):
      K1, K2, KI = self.KEY
      return chr((KI * (ord(char) - K2)) % self.DIE)

   def decrypt(self, string):
      return "".join(map(self.decryptChar, string))

affine = affine_cipher()
print("Our Encrypted Text: ", affine.encrypt('Affine Cipher'))
print("Our Decrypted Text: ", affine.decrypt('JMMbFcXb[F!'))

Following is the output of the above example −

Input/Output
Our Encrypted Text:  JMMbFcXb[F!
Our Decrypted Text:  Affine Cipher

Implementation using Java

In this implementation we will use Java programming language to encrypt and decrypt a message using Affine Cipher. So basically we will use two secret keys here, first is the Multiplicative Key (A) and the second one is Additive Key (B). These keys will be used to mix up the letters in the given message, making it secret. And for decrypting the message, a special math formula called Modular Multiplicative Inverse is used to undo the encryption.

Example

So the implementation of Affine Cipher using Java is given below −

public class AffineCipher {
    
   static final int A = 17; // Multiplicative Key
   static final int B = 20; // Additive Key

   // Function to find modular multiplicative inverse
   static int modInverse(int a, int m) {
      for (int x = 1; x < m; x++) {
         if (((a % m) * (x % m)) % m == 1) {
            return x;
         }
      }
      return -1; // If inverse is not there
   }
    
   // Function to encrypt plaintext
   static String encryptMessage(String pt) {
      StringBuilder ciphertext = new StringBuilder();
      for (int i = 0; i < pt.length(); i++) {
         char ch = pt.charAt(i);
         if (Character.isLetter(ch)) {
            if (Character.isUpperCase(ch)) {
               ciphertext.append((char) ('A' + (A * (ch - 'A') + B) % 26));
            } else {
               ciphertext.append((char) ('a' + (A * (ch - 'a') + B) % 26));
            }
         } else {
            ciphertext.append(ch);
         }
      }
      return ciphertext.toString();
   }
    
   // Function to decrypt ciphertext
   static String decryptMessage(String ciphertext) {
      StringBuilder pt = new StringBuilder();
      int aInverse = modInverse(A, 26);
      if (aInverse == -1) {
         return "Inverse doesn't exist";
      }
      for (int i = 0; i < ciphertext.length(); i++) {
         char ch = ciphertext.charAt(i);
         if (Character.isLetter(ch)) {
            if (Character.isUpperCase(ch)) {
               int x = (aInverse * (ch - 'A' - B + 26)) % 26;
               pt.append((char) ('A' + x));
            } else {
               int x = (aInverse * (ch - 'a' - B + 26)) % 26;
               pt.append((char) ('a' + x));
            }
         } else {
            pt.append(ch);
         }
      }
      return pt.toString();
   }
    
   public static void main(String[] args) {
      String pt = "Hello this is an example of affine cipher";

      String et = encryptMessage(pt); // Encrypted Text
      System.out.println("The Encrypted Text: " + et);

      String dt = decryptMessage(et); // Decrypted Text
      System.out.println("The Decrypted Text: " + dt);
   }
}

Following is the output of the above example −

Input/Output

The Encrypted Text: Jkzzy fjao ao uh kvuqpzk yb ubbahk capjkx
The Decrypted Text: Hello this is an example of affine cipher

Implementation using C++

In this we are going to use C++ programming language to implement the Affine Cipher, a method to keep messages secret. So the concept of this code will be the same as we have used in the Java implementation but the difference will be that we will use C++ here.

Example

So the implementation for affine cipher in c++ is given below −

#include <iostream>
#include <string>
using namespace std;

const int A = 17; // Multiplicative Key
const int B = 20; // Additive Key

// function to find mod inverse
int modInverse(int a, int m) {
   for (int x = 1; x < m; x++) {
      if (((a % m) * (x % m)) % m == 1) {
         return x;
      }
   }
   return -1; // If inverse is not there
}

// Function to encrypt plaintext
string encryptMessage(string plaintext) {
   string ciphertext = "";
   for (char ch : plaintext) {
      if (isalpha(ch)) {
         if (isupper(ch)) {
            ciphertext += (char)('A' + (A * (ch - 'A') + B) % 26);
         } else {
            ciphertext += (char)('a' + (A * (ch - 'a') + B) % 26);
         }
      } else {
         ciphertext += ch;
      }
   }
   return ciphertext;
}

// Function to decrypt ciphertext
string decryptMessage(string ciphertext) {
   string plaintext = "";
   int aInverse = modInverse(A, 26);
   if (aInverse == -1) {
      return "Inverse doesn't exist";
   }
   for (char ch : ciphertext) {
      if (isalpha(ch)) {
         if (isupper(ch)) {
            int x = (aInverse * (ch - 'A' - B + 26)) % 26;
            plaintext += (char)('A' + x);
         } else {
            int x = (aInverse * (ch - 'a' - B + 26)) % 26;
            plaintext += (char)('a' + x);
         }
      } else {
         plaintext += ch;
      }
   }
   return plaintext;
}

int main() {
   string pt = "Hello there i am working with Affine Cipher";
   string et = encryptMessage(pt);
   cout << "Encrypted Text: " << et << endl;

   string dt = decryptMessage(et);
   cout << "Decrypted Text: " << dt << endl;

   return 0;
}

Following is the output of the above example −

Input/Output

The Encrypted Text: Jkzzy fjkxk a uq eyxiahs eafj Ubbahk Capjkx
The Decrypted Text: Hello there i am working with Affine Cipher

Features

  • It is easy to understand and implement.

  • The size of the alphabet can be adjusted.

  • It allows the use of different keys for encryption and decryption. So it provides flexibility in choosing security levels.

  • The encryption and decryption process includes numerical operations which include a layer of security to the encoded messages.

Drawbacks

  • The number of possible keys are constrained by the size of the letter set, which is vulnerable to brute-force attacks.

  • Since Affine Cipher preserves letter frequencies, it is vulnerable to frequency analysis attacks.

  • It only focuses on encryption and decryption, lacking mechanisms for data integrity verification or sender authentication.

Summary

In this chapter, we have learned about the affine cipher algorithm to encrypt and decrypt our secret information. It uses a mathematical formula to encrypt and decrypt the given message. It helps keep messages secure by turning them into secret codes that can only be understood with the right numbers. We have also seen the implementation of affine cipher in different ways using Python. One method involves using modular arithmetic operations, where we keep numbers within a certain range. Another method uses dictionary mapping, in which each letter is replaced with its encrypted or decrypted version as per the formula.

Advertisements