PLAYFAIR CIPHER
Jahnavi Redrouthu
Graduate Assistant | | MS in CS Grad Student at University of Missouri Kansas city
Contents :
Introduction :
Cryptography is the science or art of secret writing. The fundamental objective of cryptography is to enable 2 people to communicate over an insecure channel in such a way that an opponent cannot understand what is being said. There are 2 main types of cryptography in use,
There are many other types of ciphers such as monoalphabetic and polyalphabetic, stream and block, etc. This article looks at the Playfair cipher and its application using a C function.
The Playfair Cipher :
WHAT IS A PLAYFAIR CIPHER?
Playfair cipher is the first and best-known digraph substitution cipher, which uses the technique of symmetry encryption. Invented in 1854 by Charles Wheatstone, the cipher got its name from Lord Playfair, who promoted its use. Unlike single letters in a simple substitution cipher, the Playfair cipher technique encrypts digraphs or parts of letters.
The Playfair cipher is relatively fast and doesn’t require special equipment. British Forces used it for tactical purposes during World War I and the Second Boer War, and Australians utilized it during World War II. The primary use of the cipher was for protecting vital but non-critical secrets during actual combat. By the time the enemy cryptanalysts could decrypt the information, it was useless for them.
Rules of Encryption
"eb would be replaced by sd"
"ng would be replaced by gi/gj"
2. Two plaintext letters that fall in the same column of the matrix are replaced by the letters beneath, with the top element of the column circularly following the bottom.
"dt would be replaced by my"
"ty would be replaced by yr"
3. Otherwise, each plaintext letter in a pair is replaced by the letter that lies in its own row and the column occupied by the other plaintext letter.
"me would be replaced by gd"
"net would be replaced by do"
Following these rules, the ciphertext becomes?'gd do gd rq pr sd hm em bv'.
This cipher is more secure than simple substitution but is still susceptible to ciphertext-only attacks by doing statistical frequency counts of pairs of letters since each pair of letters always gets encrypted in the same fashion. Moreover, short keywords make the Playfair cipher even easier to crack.
Playfair Cipher Encryption Algorithm
The Algorithm consists of 2 steps:?
1. Generate the key Square(5×5):?The key square is a 5×5 grid of alphabets that acts as the key for encrypting the plaintext. Each of the 25 alphabets must be unique and one letter of the alphabet (usually J) is omitted from the table (as the table can hold only 25 alphabets). If the plaintext contains J, then it is replaced by I.?
2. Algorithm to encrypt the plain text:?The plaintext is split into pairs of two letters (digraphs). If there is an odd number of letters, a Z is added to the last letter.?
For example:??
PlainText: "instruments"
After Split: 'in' 'st' 'ru' 'me' 'nt' 'sz'
1.?Pair cannot be made with the same letter. Break the letter in single and add a bogus letter to the previous letter.
Plain Text:?"hello"
After Split:?'he' 'lx' 'lo'
Here?'x'?is the bogus letter.
领英推荐
2.?If the letter is standing alone in the process of pairing, then add an extra bogus letter with the alone letter
Plain Text:?"helloe"
AfterSplit:?'he' 'lx' 'lo' 'ez'
Here?'z'??is the bogus letter.
C Implementation for Encryption
// C program to implement Playfair Cipher
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
// Function to convert the string to lowercase
void toLowerCase(char plain[], int ps)
{
int i;
for (i = 0; i < ps; i++) {
if (plain[i] > 64 && plain[i] < 91)
plain[i] += 32;
}
}
// Function to remove all spaces in a string
int removeSpaces(char* plain, int ps)
{
int i, count = 0;
for (i = 0; i < ps; i++)
if (plain[i] != ' ')
plain[count++] = plain[i];
plain[count] = '\0';
return count;
}
// Function to generate the 5x5 key square
void generateKeyTable(char key[], int ks, char keyT[5][5])
{
int i, j, k, flag = 0, *dicty;
// a 26 character hashmap
// to store count of the alphabet
dicty = (int*)calloc(26, sizeof(int));
for (i = 0; i < ks; i++) {
if (key[i] != 'j')
dicty[key[i] - 97] = 2;
}
dicty['j' - 97] = 1;
i = 0;
j = 0;
for (k = 0; k < ks; k++) {
if (dicty[key[k] - 97] == 2) {
dicty[key[k] - 97] -= 1;
keyT[i][j] = key[k];
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
for (k = 0; k < 26; k++) {
if (dicty[k] == 0) {
keyT[i][j] = (char)(k + 97);
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
}
// Function to search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
int i, j;
if (a == 'j')
a = 'i';
else if (b == 'j')
b = 'i';
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (keyT[i][j] == a) {
arr[0] = i;
arr[1] = j;
}
else if (keyT[i][j] == b) {
arr[2] = i;
arr[3] = j;
}
}
}
}
// Function to find the modulus with 5
int mod5(int a)
{
return (a % 5);
}
// Function to make the plain text length to be even
int prepare(char str[], int ptrs)
{
if (ptrs % 2 != 0) {
str[ptrs++] = 'z';
str[ptrs] = '\0';
}
return ptrs;
}
// Function for performing the encryption
void encrypt(char str[], char keyT[5][5], int ps)
{
int i, a[4];
for (i = 0; i < ps; i += 2) {
search(keyT, str[i], str[i + 1], a);
if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] + 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];
}
else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] + 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
}
else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}
// Function to encrypt using Playfair Cipher
void encryptByPlayfairCipher(char str[], char key[])
{
char ps, ks, keyT[5][5];
// Key
ks = strlen(key);
ks = removeSpaces(key, ks);
toLowerCase(key, ks);
// Plaintext
ps = strlen(str);
toLowerCase(str, ps);
ps = removeSpaces(str, ps);
ps = prepare(str, ps);
generateKeyTable(key, ks, keyT);
encrypt(str, keyT, ps);
}
// Driver code
int main()
{
char str[SIZE], key[SIZE];
// Key to be encrypted
strcpy(key, "Playfair");
printf("Key text: %s\n", key);
// Plaintext to be encrypted
strcpy(str, "encryption");
printf("Plain text: %s\n", str);
// encrypt using Playfair Cipher
encryptByPlayfairCipher(str, key);
printf("Cipher text: %s\n", str);
return 0;
}
Outputs for Some Plaintexts - Encryption
Key text: Playfair
Plain text: encryption
Cipher text: nudbflndqo
Rules of Decryption
"sd would be replaced by eb"
"gi would be replaced by ng"
2. Two ciphertext letters that fall in the same column of the matrix are replaced by the letters above, with the bottom element of the column circularly following the top.
"my would be replaced by dt"
"yr would be replaced by ty"
3. Otherwise, each ciphertext letter in a pair is replaced by the letter that lies in its own row and the column occupied by the other ciphertext letter.
"gd would be replaced by me"
"do would be replaced by et"
Following these rules, the plaintext becomes ‘Meet me at the bridge’ (x is neglected at the end since it's a filler letter).
Playfair Cipher Decryption Algorithm
The Algorithm consists of 2 steps:?
1. Generate the key Square(5×5) at the receiver's end:?The key square is a 5×5 grid of alphabets that acts as the key for encrypting the plaintext. Each of the 25 alphabets must be unique and one letter of the alphabet (usually J) is omitted from the table (as the table can hold only 25 alphabets). If the plaintext contains J, then it is replaced by I .?
2. Algorithm to decrypt the ciphertext:?The ciphertext is split into pairs of two letters (digraphs).?Note: The?ciphertext?always has?an even?number of characters.
For example:?
CipherText: "gatlmzclrqtx"
After Split: 'ga' 'tl' 'mz' 'cl' 'rq' 'tx'
C Implementation for Decryption
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
// Convert all the characters
// of a string to lowercase
void toLowerCase(char plain[], int ps)
{
int i;
for (i = 0; i < ps; i++) {
if (plain[i] > 64 && plain[i] < 91)
plain[i] += 32;
}
}
// Remove all spaces in a string
// can be extended to remove punctuation
int removeSpaces(char* plain, int ps)
{
int i, count = 0;
for (i = 0; i < ps; i++)
if (plain[i] != ' ')
plain[count++] = plain[i];
plain[count] = '\0';
return count;
}
// generates the 5x5 key square
void generateKeyTable(char key[], int ks,
char keyT[5][5])
{
int i, j, k, flag = 0, *dicty;
// a 26 character hashmap
// to store count of the alphabet
dicty = (int*)calloc(26, sizeof(int));
for (i = 0; i < ks; i++) {
if (key[i] != 'j')
dicty[key[i] - 97] = 2;
}
dicty['j' - 97] = 1;
i = 0;
j = 0;
for (k = 0; k < ks; k++) {
if (dicty[key[k] - 97] == 2) {
dicty[key[k] - 97] -= 1;
keyT[i][j] = key[k];
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
for (k = 0; k < 26; k++) {
if (dicty[k] == 0) {
keyT[i][j] = (char)(k + 97);
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
}
// Search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a,
char b, int arr[])
{
int i, j;
if (a == 'j')
a = 'i';
else if (b == 'j')
b = 'i';
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (keyT[i][j] == a) {
arr[0] = i;
arr[1] = j;
}
else if (keyT[i][j] == b) {
arr[2] = i;
arr[3] = j;
}
}
}
}
// Function to find the modulus with 5
int mod5(int a)
{
return (a % 5);
}
// Function to decrypt
void decrypt(char str[], char keyT[5][5], int ps)
{
int i, a[4];
for (i = 0; i < ps; i += 2) {
search(keyT, str[i], str[i + 1], a);
if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] - 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
}
else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] - 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
}
else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}
// Function to call decrypt
void decryptByPlayfairCipher(char str[], char key[])
{
char ps, ks, keyT[5][5];
// Key
ks = strlen(key);
ks = removeSpaces(key, ks);
toLowerCase(key, ks);
// ciphertext
ps = strlen(str);
toLowerCase(str, ps);
ps = removeSpaces(str, ps);
generateKeyTable(key, ks, keyT);
decrypt(str, keyT, ps);
}
// Driver code
int main()
{
char str[SIZE], key[SIZE];
// Key to be encrypted
strcpy(key, "Playfair");
printf("Key text: %s\n", key);
// Ciphertext to be decrypted
strcpy(str, "decryption");
printf("Plain text: %s\n", str);
// encrypt using Playfair Cipher
decryptByPlayfairCipher(str, key);
printf("Deciphered text: %s\n", str);
return 0;
}
Outputs for Some Plaintexts - Decryption
Key text: Playfair
Plain text: decryption
Deciphered text: imbiandnm
THANK YOU :)