Play Fair Cipher

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 51

PLAY FAIR CIPHER-------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------

Algorithm :

1. Read the key as input from the user.

2. Then create the key table of 5x5 grids of alphabets.

3. Get the plain text as an input.

4. Then split the plain text message into pairs of two letters(digraphs).

5. Pair cannot be made with same letter. Break the letter in single and add a bogus letter z

to the previous letter

6. If both the letters are in the same column, take the letter below each one.

7. If both letters are in the same row, take the letter to the right of each one.

8. If neither of the preceding two rules are true, form a rectangle with the two letters and

take the letters on the horizontal opposite corner of the rectangle.

Python CODE :

def matrix(key):

matrix = []

for e in key.upper():

if e not in matrix:

matrix.append(e)

alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"

for e in alphabet:

if e not in matrix:

matrix.append(e)

matrix_group = []

for e in range(5):
matrix_group.append('')

matrix_group[0] = matrix[0:5]

matrix_group[1] = matrix[5:10]

matrix_group[2] = matrix[10:15]

matrix_group[3] = matrix[15:20]

matrix_group[4] = matrix[20:25]

return matrix_group

def message_to_digraphs(message_original):

message = []

for e in message_original:

message.append(e)

for unused in range(len(message)):

if " " in message:

message.remove(" ")

i=0

for e in range(int(len(message)/2)):

if message[i] == message[i+1]:

message.insert(i+1,'X')

i = i+2

if len(message) % 2 == 1:

message.append("X")

i=0

new = []

for x in range(1,int(len(message)/2) + 1):

new.append(message[i:i+2])
i = i+2

return new

def find_position(key_matrix,letter):

x=y=0

for i in range(5):

for j in range(5):

if key_matrix[i][j] == letter:

x=i

y=j

return x,y

def encrypt(message, key):

message = message_to_digraphs(message)

key_matrix = matrix(key)

cipher = []

for e in message:

p1,q1 = find_position(key_matrix,e[0])

p2,q2 = find_position(key_matrix,e[1])

if p1 == p2:

if q1 == 4:

q1 = -1

if q2 == 4:

q2 = -1

cipher.append(key_matrix[p1][q1+1])

cipher.append(key_matrix[p1][q2+1])

elif q1 == q2:

if p1 == 4:

p1 = -1;

if p2 == 4:

p2 = -1;
cipher.append(key_matrix[p1+1][q1])

cipher.append(key_matrix[p2+1][q2])

else:

cipher.append(key_matrix[p1][q2])

cipher.append(key_matrix[p2][q1])

return cipher

def decrypt(cipher, key):

cipher = message_to_digraphs(cipher)

key_matrix = matrix(key)

plaintext = []

for e in cipher:

p1,q1 = find_position(key_matrix,e[0])

p2,q2 = find_position(key_matrix,e[1])

if p1 == p2:

if q1 == 4:

q1 = -1

if q2 == 4:

q2 = -1

plaintext.append(key_matrix[p1][q1-1])

plaintext.append(key_matrix[p1][q2-1])

elif q1 == q2:

if p1 == 4:

p1 = -1;

if p2 == 4:

p2 = -1;

plaintext.append(key_matrix[p1-1][q1])

plaintext.append(key_matrix[p2-1][q2])

else:

plaintext.append(key_matrix[p1][q2])

plaintext.append(key_matrix[p2][q1])
return plaintext

def main():

print("Playfair Cipher")

keyword = input("Enter keyword: ")

message = input("Enter message to encrypt: ")

key = keyword.replace("j", "i")

key = key.upper()

message = message.upper()

key_matrix = matrix(key)

print("Key Square Matrix:")

for row in key_matrix:

print(' '.join(row))

cipher = encrypt(message, key)

print("Encrypting...")

print("The encrypted text is: ", "".join(cipher))

print("Decrypting...")

decrypted_text = decrypt("".join(cipher), key)

print("The decrypted text is: ", "".join(decrypted_text))

main()

JAVA

import java.util.Scanner;

public class PlayfairCipher {

private static String key = "";

private static char[][] keyTable = new char[5][5];

public static void main(String[] args) {


Scanner scanner = new Scanner(System.in);

System.out.print("Enter the key: ");

key = scanner.nextLine();

System.out.print("Enter the plaintext: ");

String plaintext = scanner.nextLine();

scanner.close();

createKeyTable();

String encryptedText = encrypt(plaintext);

System.out.println("Encrypted Text: " + encryptedText);

// For decryption, the encrypted text is treated as the plaintext input

String decryptedText = decrypt(encryptedText);

System.out.println("Decrypted Text: " + decryptedText);

private static void createKeyTable() {

String keyString = key.toUpperCase() + "ABCDEFGHIKLMNOPQRSTUVWXYZ";

// Remove duplicate characters and 'J'

StringBuilder uniqueKey = new StringBuilder();

for (char c : keyString.toCharArray()) {

if (uniqueKey.indexOf("" + c) == -1 && c != 'J')

uniqueKey.append(c);

// Fill key table

for (int i = 0, k = 0; i < 5; i++) {

for (int j = 0; j < 5; j++) {


keyTable[i][j] = uniqueKey.charAt(k++);

private static String encrypt(String text) {

return processText(text, true);

private static String decrypt(String text) {

return processText(text, false);

private static String processText(String text, boolean encrypt) {

StringBuilder processedText = new StringBuilder();

text = text.toUpperCase().replace("J", "I").replaceAll("[^A-Z]", "");

// Create digraphs with filler 'X' for repeated letters

for (int i = 0; i < text.length(); i += 2) {

char first = text.charAt(i);

char second = (i + 1 < text.length()) ? text.charAt(i + 1) : 'X';

if (first == second) {

processedText.append(first).append('X');

i--;

} else

processedText.append(first);

processedText.append(second);

}
// Process each digraph

for (int i = 0; i < processedText.length(); i += 2) {

char first = processedText.charAt(i);

char second = processedText.charAt(i + 1);

processedText.replace(i, i + 2, processDigraph(first, second, encrypt));

return processedText.toString();

private static String processDigraph(char a, char b, boolean encrypt) {

int[] posA = findPosition(a);

int[] posB = findPosition(b);

// Check if both characters are found in the key table

if (posA[0] == -1 || posB[0] == -1) {

throw new IllegalArgumentException("Both characters must be in the key table.");

// Same row

if (posA[0] == posB[0]) {

return "" + keyTable[posA[0]][(posA[1] + (encrypt ? 1 : 4)) % 5] + keyTable[posB[0]][(posB[1]


+ (encrypt ? 1 : 4)) % 5];

// Same column

else if (posA[1] == posB[1]) {

return "" + keyTable[(posA[0] + (encrypt ? 1 : 4)) % 5][posA[1]] + keyTable[(posB[0] +


(encrypt ? 1 : 4)) % 5][posB[1]];

// Rectangle

else {
return "" + keyTable[posA[0]][posB[1]] + keyTable[posB[0]][posA[1]];

private static int[] findPosition(char c) {

for (int i = 0; i < 5; i++) {

for (int j = 0; j < 5; j++) {

if (keyTable[i][j] == c) {

return new int[]{i, j};

return new int[]{-1, -1}; // Character not found

HILL CIPHER--------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------

Algorithm:

1. Obtain a plain text message to encode in Standard English with no spaces.

2. Split the plain text into group of length three. To fill this, add X at the end.

3. Convert each group of letters with length three into plain text vectors.

4. Replace each letter by the number corresponding to its position in the alphabet i.e.

A=1, B=2, C=3…Z=0.

5. Create the key word in a 3*3 matrix.

6. Multiply the two matrices to obtain the cipher text of length three.

7. For decryption, convert each entry in the cipher text vector into its plain text vector by

multiplying the cipher text vector and inverse of a matrix.

8. Thus plaintext is obtained from the corresponding plaintext vector by corresponding


PYTHON CODE :

import numpy

def create_matrix_from(key):

m=[[0] * 3 for i in range(3)]

for i in range(3):

for j in range(3):

m[i][j] = ord(key[3*i+j]) % 65

return m

def encrypt(P, K):

C=[0,0,0]

C[0] = (K[0][0]*P[0] + K[1][0]*P[1] + K[2][0]*P[2]) % 26

C[1] = (K[0][1]*P[0] + K[1][1]*P[1] + K[2][1]*P[2]) % 26

C[2] = (K[0][2]*P[0] + K[1][2]*P[1] + K[2][2]*P[2]) % 26

return C

def Hill(message, K):

cipher_text = []

for i in range(0,len(message), 3):

P=[0, 0, 0]

for j in range(3):

P[j] = ord(message[i+j]) % 65

C = encrypt(P,K)

for j in range(3):

cipher_text.append(chr(C[j] + 65))

return "".join(cipher_text)

def MatrixInverse(K):
det = int(numpy.linalg.det(K))

det_multiplicative_inverse = pow(det, -1, 26)

K_inv = [[0] * 3 for i in range(3)]

for i in range(3):

for j in range(3):

Dji = K

Dji = numpy.delete(Dji, (j), axis=0)

Dji = numpy.delete(Dji, (i), axis=1)

det = Dji[0][0]*Dji[1][1] - Dji[0][1]*Dji[1][0]

K_inv[i][j] = (det_multiplicative_inverse * pow(-1,i+j) * det) % 26

return K_inv

def process_string(s):

s = s.upper()

if len(s) % 3 != 0:

s += 'X'

return s

if __name__ == "__main__":

message = input("Enter plain text for encryption : ")

key = "RRFVSVCCT"

print("Padded text : ",process_string(message))

K = create_matrix_from(key)

cipher_text = Hill(process_string(message), K)

print ('Encrypted Message : ', cipher_text)

K_inv = MatrixInverse(K)

plain_text = Hill(cipher_text, K_inv)

print ('Decrypted Message : ', plain_text)

JAVA
import java.util.Scanner;

import java.util.Arrays;

public class HillCipher {

private static final int MATRIX_SIZE = 3;

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

System.out.print("Enter the Plain text for Encryption: ");

String plaintext = scanner.nextLine().toUpperCase().replaceAll("\\s+", "");

scanner.close();

// Pad plaintext to ensure it is a multiple of MATRIX_SIZE

while (plaintext.length() % MATRIX_SIZE != 0) {

plaintext += "X";

// Example key matrix for encryption and decryption

int[][] keyMatrix = {

{17, 17, 5},

{21, 18, 21},

{2, 2, 19}

};

// Inverse of the key matrix for decryption

int[][] inverseKeyMatrix = {

{4, 9, 15},

{15, 17, 6},

{24, 0, 17}

};
System.out.println("Padded Text: " + plaintext);

// Encrypt the plaintext

String encryptedText = encrypt(plaintext, keyMatrix);

System.out.println("Encrypted Message: " + encryptedText);

// Decrypt the encrypted text

String decryptedText = decrypt(encryptedText, inverseKeyMatrix);

System.out.println("Decrypted Message: " + decryptedText);

private static String encrypt(String text, int[][] keyMatrix) {

StringBuilder encryptedText = new StringBuilder();

for (int i = 0; i < text.length(); i += MATRIX_SIZE) {

int[] textVector = new int[MATRIX_SIZE];

for (int j = 0; j < MATRIX_SIZE; j++) {

textVector[j] = text.charAt(i + j) - 'A';

int[] cipherVector = multiplyMatrixAndVector(keyMatrix, textVector);

for (int value : cipherVector) {

encryptedText.append((char) ((value % 26) + 'A'));

return encryptedText.toString();

private static String decrypt(String text, int[][] inverseKeyMatrix) {

StringBuilder decryptedText = new StringBuilder();

for (int i = 0; i < text.length(); i += MATRIX_SIZE) {

int[] textVector = new int[MATRIX_SIZE];


for (int j = 0; j < MATRIX_SIZE; j++) {

textVector[j] = text.charAt(i + j) - 'A';

int[] plainVector = multiplyMatrixAndVector(inverseKeyMatrix, textVector);

for (int value : plainVector) {

decryptedText.append((char) ((value % 26) + 'A'));

return decryptedText.toString();

private static int[] multiplyMatrixAndVector(int[][] matrix, int[] vector) {

int[] result = new int[MATRIX_SIZE];

for (int i = 0; i < MATRIX_SIZE; i++) {

for (int j = 0; j < MATRIX_SIZE; j++) {

result[i] += matrix[i][j] * vector[j];

return result;

VIGENERE CIPHER------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------

Algorithm

1. The Vigenere cipher is a method of encrypting alphabetic text by using a series of

different Caesar ciphers based on the letters of a keyword.

2. It is a simple form of polyalphabetic substitution.


3. To encrypt, a table of alphabets can be used, termeda Vigeneresquare, or Vigenere

table.

4. It consists of the alphabet written out 26 times in different rows, each alphabet shifted

cyclically to the left compared to the previous alphabet, corresponding to the 26

possible Caesar ciphers.

5. At different points in the encryption process, the cipher uses a different alphabet from

one of the rows used.

6. The alphabet at each point depends on a repeating keyword.

PYTHON CODE :

def generate_key(message, key):

key = list(key)

if len(message) == len(key):

return(key)

else:

for i in range(len(message) - len(key)):

key.append(key[i % len(key)])

return("" . join(key))

def vigenere_encryption(message, key):

cipher_text = []

for i in range(len(message)):

x = (ord(message[i]) + ord(key[i])) % 26

x += ord('A')

cipher_text.append(chr(x))

return("" . join(cipher_text))

def vigenere_decryption(cipher_text, key):

orig_text = []
for i in range(len(cipher_text)):

x = (ord(cipher_text[i]) - ord(key[i]) + 26) % 26

x += ord('A')

orig_text.append(chr(x))

return("" . join(orig_text))

def main():

message = input("Enter the message for encryption: ")

keyword = input("Enter the key: ")

key = generate_key(message, keyword)

encrypted_message = vigenere_encryption(message, key)

print("Encrypted message: Cipher Text=", encrypted_message)

decrypted_message = vigenere_decryption(encrypted_message, key)

print("Decrypted message: Plain Text=", decrypted_message)

main()

JAVA

import java.util.Scanner;

public class VigenereCipher

static String generateKey(String str, String key)

int x = str.length();

for (int i = 0; ; i++)

if (x == i)
i = 0;

if (key.length() == str.length())

break;

key+=(key.charAt(i));

return key;

static String cipherText(String str, String key)

String cipher_text="";

for (int i = 0; i < str.length(); i++)

int x = (str.charAt(i) + key.charAt(i)) %26;

x += 'A';

cipher_text+=(char)(x);

return cipher_text;

static String originalText(String cipher_text, String key)

String orig_text="";

for (int i = 0 ; i < cipher_text.length() &&


i < key.length(); i++)

int x = (cipher_text.charAt(i) -

key.charAt(i) + 26) %26;

x += 'A';

orig_text+=(char)(x);

return orig_text;

static String LowerToUpper(String s)

StringBuffer str =new StringBuffer(s);

for(int i = 0; i < s.length(); i++)

if(Character.isLowerCase(s.charAt(i)))

str.setCharAt(i, Character.toUpperCase(s.charAt(i)));

s = str.toString();

return s;

public static void main(String[] args)

{
Scanner sc = new Scanner(System.in);

System.out.println("Enter plain text : ");

String Str = sc.next();

System.out.println("Enter plain key : ");

String Keyword = sc.next();

String str = LowerToUpper(Str);

String keyword = LowerToUpper(Keyword);

String key = generateKey(str, keyword);

String cipher_text = cipherText(str, key);

System.out.println("Ciphertext : "

+ cipher_text + "\n");

System.out.println("Original/Decrypted Text : "

+ originalText(cipher_text, key));

CAESAR CIPHER---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------

Algorithm for Caesar Cipher:

Input:

Choose a shift value between 1 and 25.

Write down the alphabet in order from A to Z.

Create a new alphabet by shifting each letter of the original alphabet by the shift value. For
example, if the shift value is 3, the new alphabet would be:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
DEFGHIJKLMNOPQRSTUVWXYZABC

Replace each letter of the message with the corresponding letter from the new alphabet. For
example, if the shift value is 3, the word “hello” would become “khoor”.

To decrypt the message, shift each letter back by the same amount. For example, if the shift
value is 3, the encrypted message “khoor” would become “hello”.

PYHTON CODE

def encrypt(text,s):

result = ""

# traverse text

for i in range(len(text)):

char = text[i]

# Encrypt uppercase characters

if (char.isupper()):

result += chr((ord(char) + s-65) % 26 + 65)

# Encrypt lowercase characters

else:

result += chr((ord(char) + s - 97) % 26 + 97)

return result

#check the above function

text = "ATTACKATONCE"

s=4

print ("Text : " + text)

print ("Shift : " + str(s))

print ("Cipher: " + encrypt(text,s))

java
//A Java Program to illustrate Caesar Cipher Technique

class CaesarCipher

// Encrypts text using a shift of s

public static StringBuffer encrypt(String text, int s)

StringBuffer result= new StringBuffer();

for (int i=0; i<text.length(); i++)

if (Character.isUpperCase(text.charAt(i)))

char ch = (char)(((int)text.charAt(i) +

s - 65) % 26 + 65);

result.append(ch);

else

char ch = (char)(((int)text.charAt(i) +

s - 97) % 26 + 97);

result.append(ch);

return result;

// Driver code

public static void main(String[] args)

String text = "ATTACKATONCE";

int s = 4;
System.out.println("Text : " + text);

System.out.println("Shift : " + s);

System.out.println("Cipher: " + encrypt(text, s));

1. Write a pseudocode and program for a four-function calculator in GF(2 4 ). You should
compute the multiplicative inverses on the fly.--------------------------------------------

PYTHON CODE :

class GF2_4:

irreducible_poly=0b10011

def __init__(self,value):

self.value = value & 0xF

def add(self,other):

return GF2_4(self.value ^ other.value)

def subtract(self,other):

return self.add(other)

def multiply(self,other):

result=0

temp=other.value

for i in range(4):

if(self.value>>i)&1:

result ^= temp

temp <<= 1
for i in reversed(range(4,8)):

if (result>>i) &1:

result ^= (self.irreducible_poly << (i-4))

return GF2_4(result)

def inverse(self):

for i in range(1,16):

if self.multiply(GF2_4(i)).value == 1:

return GF2_4(i)

return GF2_4(0)

def divide(self,other):

return self.multiply(other.inverse())

a = GF2_4(0b0011)

b = GF2_4(0b0101)

print("KUMAR BAIBHAV 21BCE0877")

print("Addition :",a.add(b).value)

print("Substraction :",a.subtract(b).value)

print("Multiplication :",a.multiply(b).value)

print("Division :",a.divide(b).value)

2. Write a pseudocode and program that implements fast exponentiation modulo 𝑛.---------
----------------------------------------------------------------------------------------------

PSEUDO CODE :

function fast_exp_mod(base, exponent, modulus)

if modulus == 1
return 0

result = 1

base = base % modulus

while exponent > 0

if (exponent % 2 == 1)

result = (result * base) % modulus

exponent = exponent >> 1

base = (base * base) % modulus

return result

PYTHON CODE :

def fast_exp_mod(base, exponent, modulus):

if modulus == 1:

return 0

result = 1

base = base % modulus

while exponent > 0:

if exponent % 2 == 1:

result = (result * base) % modulus

exponent = exponent >> 1

base = (base * base) % modulus

return result

def main():

base = int(input("Enter the base number: "))

exponent = int(input("Enter the exponent value: "))

modulus = int(input("Enter the modulus value: "))

result = fast_exp_mod(base, exponent, modulus)

print(f"The result of ({base}^{exponent}) mod {modulus} is: {result}")

if __name__ == "__main__":
main()

3. Write a pseudocode and program for a P-box (DES) in which the permutation is defined
by a table.-----------------------------------------------------------------------------------------------

PSEUDO CODE :

functon pBoxPermutation(input, permutationTable):

output = empty array of the same size as permutationTable

for i from 0 to size(permutationTable) - 1:

output[i] = input[permutationTable[i] - 1]

return output

PYTHON CODE :

def pbox(input_bits, permutation_table):

output_bits = [0]*len(permutation_table)

for i in range(len(permutation_table)):

output_bits[i]=input_bits[permutation_table[i]-1]

return output_bits

permutation_table=[16,7,20,21,

29,12,28,17,

1,15,23,26,

5,18,31,10,

2,8,24,14,

32,27,3,9,

19,13,30,6,

22,11,4,25]
input_bits=[1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,0,1,1,1,0,0,0,1,1,1,1,0,1,0,1,0]

output_bits=pbox(input_bits,permutation_table)

print("KUMAR BAIBHAV 21BCE0877")

print("INPUT BITS : ",input_bits)

print("Output bits after PBox permutation : ",output_bits)

4. Write a pseudocode and program for an S-box in which the input/output is defined by a
table---------------------------------------------------------------------------------------------------

PSEUDO CODE :

PYTHON CODE :

s_box = [

[0x4, 0xA, 0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3,],

[0xE, 0xB, 0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9,],

[0x5, 0x8, 0x1,0xD,0xA,0x3,0x4,0x2,0xB,0x0,0x6,0xC,0x7,0xF,0xE,0x9,],

[0xA, 0xD, 0x0,0x7,0x9,0xE,0x6,0x3,0x4,0xF,0x1,0xB,0xC,0x2,0x8,0x5]

def SubByte(input_byte):

row = get_row(input_byte)

column = get_column(input_byte)

print(row)

print(column)

output_byte = (s_box[(row)][(column)])

return output_byte

def get_row(byte):
return ((byte) >> 4) & 0x0F

def get_column(byte):

return (byte) & 0x0F

input_byte = 0x3A

output_byte = SubByte(input_byte)

print("Input : ",hex(input_byte))

print("Output : ",hex(output_byte))

Q1. Consider a sender and receiver who need to exchange data confidentially using symmetric
encryption. Write a program that implements RC4 encryption and decryption-------------------

PYTHON CODE :

def ksa(key):

key_length = len(key)

S = list(range(256))

j=0

for i in range(256):

j = (j + S[i] + key[i % key_length]) % 256

S[i], S[j] = S[j], S[i]

return S

def prga(S, plaintext):

i, j = 0, 0

ciphertext = []

for char in plaintext:


i = (i + 1) % 256

j = (j + S[i]) % 256

S[i], S[j] = S[j], S[i]

k = S[(S[i] + S[j]) % 256]

ciphertext.append(chr(ord(char) ^ k))

return ''.join(ciphertext)

def rc4_encrypt_decrypt(key, plaintext):

S = ksa(key)

ciphertext = prga(S, plaintext)

return ciphertext

key = input("Enter the encryption key: ")

plaintext = input("Enter the plaintext: ")

ciphertext = rc4_encrypt_decrypt(key.encode(), plaintext)

print(f"Encrypted ciphertext: {ciphertext}")

decrypted_text = rc4_encrypt_decrypt(key.encode(), ciphertext)

print(f"Decrypted plaintext: {decrypted_text}")

Q2. Consider a sender and receiver who need to exchange data confidentially using symmetric
encryption. Write a program that implements S-DES encryption and decryption.--------------------

PYTHON CODE:
def apply_table(inp, table):

"""

>>> apply_table("0123456789", list(range(10)))

'9012345678'

>>> apply_table("0123456789", list(range(9, -1, -1)))

'8765432109'

"""

res = ""

for i in table:

res += inp[i - 1]

return res

def left_shift(data):

"""

>>> left_shift("0123456789")

'1234567890'

"""

return data[1:] + data[0]

def xor(a, b):

"""

>>> xor("01010101", "00001111")

'01011010'

"""

res = ""

for i in range(len(a)):

if a[i] == b[i]:

res += "0"

else:
res += "1"

return res

def apply_sbox(s, data):

row = int("0b" + data[0] + data[-1], 2)

col = int("0b" + data[1:3], 2)

return bin(s[row][col])[2:]

def function(expansion, s0, s1, key, message):

left = message[:4]

right = message[4:]

temp = apply_table(right, expansion)

temp = xor(temp, key)

l = apply_sbox(s0, temp[:4]) # noqa: E741

r = apply_sbox(s1, temp[4:])

l = "0" * (2 - len(l)) + l # noqa: E741

r = "0" * (2 - len(r)) + r

temp = apply_table(l + r, p4_table)

temp = xor(left, temp)

return temp + right

if __name__ == "__main__":

key = input("Enter 10 bit key: ")

message = input("Enter 8 bit message: ")

p8_table = [6, 3, 7, 4, 8, 5, 10, 9]

p10_table = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]

p4_table = [2, 4, 3, 1]
IP = [2, 6, 3, 1, 4, 8, 5, 7]

IP_inv = [4, 1, 3, 5, 7, 2, 8, 6]

expansion = [4, 1, 2, 3, 2, 3, 4, 1]

s0 = [[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]]

s1 = [[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]

# key generation

temp = apply_table(key, p10_table)

left = temp[:5]

right = temp[5:]

left = left_shift(left)

right = left_shift(right)

key1 = apply_table(left + right, p8_table)

left = left_shift(left)

right = left_shift(right)

left = left_shift(left)

right = left_shift(right)

key2 = apply_table(left + right, p8_table)

# encryption

temp = apply_table(message, IP)

temp = function(expansion, s0, s1, key1, temp)

temp = temp[4:] + temp[:4]

temp = function(expansion, s0, s1, key2, temp)

CT = apply_table(temp, IP_inv)

print("Cipher text is:", CT)

# decryption

temp = apply_table(CT, IP)

temp = function(expansion, s0, s1, key2, temp)

temp = temp[4:] + temp[:4]


temp = function(expansion, s0, s1, key1, temp)

PT = apply_table(temp, IP_inv)

print("Plain text after decypting is:", PT)

Q3. Write a pseudocode and program for Round Key-Generation in DES .-----------------------------
----------------------------------------------------------------------------------------

PSEUDOCODE :

Function GenerateRoundKeys(key):

Initialize round_keys list with an empty list

Apply Permuted Choice 1 (PC-1) to the key to get a 56-bit key (C0, D0)

For i = 1 to 16 do:

Apply left shift according to the round number (1 or 2) on each of (C, D)

Concatenate and apply Permuted Choice 2 (PC-2) to generate the round key

Add the generated round key to the round_keys list

Return round_keys

PYTHON CODE:

# Permutation Table for PC-1

PC_1 = [57, 49, 41, 33, 25, 17, 9,

1, 58, 50, 42, 34, 26, 18,


10, 2, 59, 51, 43, 35, 27,

19, 11, 3, 60, 52, 44, 36,

63, 55, 47, 39, 31, 23, 15,

7, 62, 54, 46, 38, 30, 22,

14, 6, 61, 53, 45, 37, 29,

21, 13, 5, 28, 20, 12, 4]

# Permutation Table for PC-2

PC_2 = [14, 17, 11, 24, 1, 5,

3, 28, 15, 6, 21, 10,

23, 19, 12, 4, 26, 8,

16, 7, 27, 20, 13, 2,

41, 52, 31, 37, 47, 55,

30, 40, 51, 45, 33, 48,

44, 49, 39, 56, 34, 53,

46, 42, 50, 36, 29, 32]

# Shift schedule for left and right halves

SHIFT_SCHEDULE = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]

def generate_round_keys(key):

"""

Generate the 16 round keys from the given 64-bit key.

"""

# Convert the key to a list of bits

key = [int(bit) for bit in key]

# Apply PC-1 permutation to the key

key = [key[PC_1[i] - 1] for i in range(56)]


# Split the key into left and right halves

left_half = key[:28]

right_half = key[28:]

# Initialize the round keys list

round_keys = []

# Generate 16 round keys

for shift in SHIFT_SCHEDULE:

# Perform left shift on the left and right halves

left_half = left_half[shift:] + left_half[:shift]

right_half = right_half[shift:] + right_half[:shift]

# Combine the left and right halves

key = left_half + right_half

# Apply PC-2 permutation to the combined key

round_key = [key[PC_2[i] - 1] for i in range(48)]

# Append the round key to the list

round_keys.append(round_key)

return round_keys

# Example usage

key = "0001001100110100010101110111100110011011101111001101111111110001"

round_keys = generate_round_keys(key)

# Print the round keys

for i, round_key in enumerate(round_keys):

print(f"Round {i + 1} key: {''.join(str(bit) for bit in round_key)}")


Q4. Write a pseudocode and program for Round Key-Generation in AES -------------------------------
-----------------------------------------------------------------------------------

PSEUDOCODE :

Function KeyExpansion(key):

round_keys[] = key

For i = 4 to 44 do:

temp = round_keys[i - 1]

If i % 4 == 0 then:

temp = SubWord(RotWord(temp)) XOR Rcon[i / 4]

Else if key size is 32 bytes and i % 4 == 4 then:

temp = SubWord(temp)

round_keys[i] = round_keys[i - 4] XOR temp

Return round_keys

PYTHON CODE:

sbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab,
0x76,

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
0x72, 0xc0,

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8,
0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb,
0x27, 0xb2, 0x75,

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29,
0xe3, 0x2f, 0x84,

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a,
0x4c, 0x58, 0xcf,

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
0x9f, 0xa8,

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff,
0xf3, 0xd2,

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64,
0x5d, 0x19, 0x73,

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde,
0x5e, 0x0b, 0xdb,

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91,
0x95, 0xe4, 0x79,

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65,
0x7a, 0xae, 0x08,

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b,
0xbd, 0x8b, 0x8a,

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,
0xc1, 0x1d, 0x9e,

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce,
0x55, 0x28, 0xdf,

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0,
0x54, 0xbb, 0x16]

Rcon = [0x00000000, 0x01000000, 0x02000000,

0x04000000, 0x08000000, 0x10000000,

0x20000000, 0x40000000, 0x80000000,

0x1b000000, 0x36000000]

def keyExpansion(key):

#prep w list to hold 44 tuples

w = [()]*44
#fill out first 4 words based on the key

for i in range(4):

w[i] = (key[4*i], key[4*i+1], key[4*i+2], key[4*i+3])

#fill out the rest based on previews words, rotword, subword and rcon values

for i in range(4, 44):

#get required previous keywords

temp = w[i-1]

word = w[i-4]

#if multiple of 4 use rot, sub, rcon etc

if i % 4 == 0:

x = RotWord(temp)

y = SubWord(x)

rcon = Rcon[int(i/4)]

temp = hexor(y, hex(rcon)[2:])

#creating strings of hex rather than tuple

word = ''.join(word)

temp = ''.join(temp)

#xor the two hex values

xord = hexor(word, temp)

w[i] = (xord[:2], xord[2:4], xord[4:6], xord[6:8])

return w

#takes two hex values and calculates hex1 xor hex2

def hexor(hex1, hex2):

#convert to binary
bin1 = hex2binary(hex1)

bin2 = hex2binary(hex2)

#calculate

xord = int(bin1, 2) ^ int(bin2, 2)

#cut prefix

hexed = hex(xord)[2:]

#leading 0s get cut above, if not length 8 add a leading 0

if len(hexed) != 8:

hexed = '0' + hexed

return hexed

#takes a hex value and returns binary

def hex2binary(hex):

return bin(int(str(hex), 16))

#takes from 1 to the end, adds on from the start to 1

def RotWord(word):

return word[1:] + word[:1]

#selects correct value from sbox based on the current word

def SubWord(word):

sWord = ()

#loop throug the current word

for i in range(4):
#check first char, if its a letter(a-f) get corresponding decimal

#otherwise just take the value and add 1

if word[i][0].isdigit() == False:

row = ord(word[i][0]) - 86

else:

row = int(word[i][0])+1

#repeat above for the seoncd char

if word[i][1].isdigit() == False:

col = ord(word[i][1]) - 86

else:

col = int(word[i][1])+1

#get the index base on row and col (16x16 grid)

sBoxIndex = (row*16) - (17-col)

#get the value from sbox without prefix

piece = hex(sbox[sBoxIndex])[2:]

#check length to ensure leading 0s are not forgotton

if len(piece) != 2:

piece = '0' + piece

#form tuple

sWord = (*sWord, piece)

#return string

return ''.join(sWord)

#used to display the keywords neatly in this form: w0 = 0f 15 71 c9


def prettyPrint(w):

print("\n\nKeywords: \n")

for i in range(len(w)):

print("w" + str(i), "=", w[i][0], w[i][1], w[i][2], w[i][3])

def main():

#hardcoding input key for demonstration purposes, could be read in from user/program
via cmd/gui etc.

key = ["0f", "15", "71", "c9", "47", "d9", "e8", "59", "0c", "b7", "ad", "d6", "af", "7f", "67", "98"]

#expand key

w = keyExpansion(key)

#display nicely

print("Key provided: " + "".join(key))

prettyPrint(w)

if __name__ == '__main__':

main()

Q5. Write a pseudocode and program for Sub-Byte Transformation in AES.----------------------------


----------------------------------------------------------------------------------------

PSEUDOCODE :

Function SubBytes(state):

For each byte b in state:


Replace b with the corresponding value from the S-box

Return the transformed state

PYTHON CODE :

S_BOX = (

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2,
0x75,

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,

def sub_byte(input_byte):

"""

Performs the Sub-Byte transformation on a single byte.

"""

row = input_byte >> 4 # Get the first 4 bits (row index)

col = input_byte & 0x0F # Get the last 4 bits (column index)

return S_BOX[row * 16 + col]


# Example usage:

input_byte = 0x53 # Example input byte

output_byte = sub_byte(input_byte)

print(f"Input: 0x{input_byte:02X}, Output: 0x{output_byte:02X}")

Q.6 Write a pseudocode and program for ShiftRows Transformation in AES.--------------------------


-----------------------------------------------------------------------------------------

PSEUDOCODE :

Function ShiftRows(state):

For each row i in state:

Shift row i to the left by i positions

Return the transformed state

PYTHON CODE:

def shift_rows(state):

"""

Perform ShiftRows Transformation for AES.

The rows of the state matrix are shifted cyclically to the left.

Row 0 is not shifted.

Row 1 is shifted by 1 byte to the left.

Row 2 is shifted by 2 bytes to the left.

Row 3 is shifted by 3 bytes to the left.


"""

for i in range(1, 4):

state[i] = state[i][i:] + state[i][:i]

return state

def main():

# Example usage:

state = [

[0x32, 0x88, 0x31, 0xe0],

[0x43, 0x5a, 0x31, 0x37],

[0xf6, 0x30, 0x98, 0x07],

[0xa8, 0x8d, 0xa2, 0x34]

print("Original State:")

for row in state:

print(row)

shifted_state = shift_rows(state)

print("\nShifted State:")

for row in shifted_state:

print(row)

if __name__ == "__main__":

main()
Q7. Write a pseudocode and program for Mix columns Transformation in AES.-----------------------
--------------------------------------------------------------------------------------------

PSEUDOCODE :

Function MixColumns(state):

For each column i in state:

Multiply the column by a fixed matrix in the Galois Field

Return the transformed state

PYTHON CODE:

def mix_columns(state_matrix):

"""

Performs the MixColumns transformation on the AES state matrix.

Args:

state_matrix (list of lists): 4x4 matrix representing the state.

Returns:

list of lists: Updated state matrix after MixColumns.

"""

def multiply(a, b):

"""

Galois field multiplication (GF(2^8)) for AES MixColumns.

"""

p=0

for _ in range(8):

if b & 1:

p ^= a

high_bit_set = a & 0x80


a <<= 1

if high_bit_set:

a ^= 0x1B # AES irreducible polynomial

b >>= 1

return p

def mix_column(column):

"""

Mix a single column using the MixColumns matrix.

"""

result = [0] * 4

for i in range(4):

result[i] = (

multiply(0x02, column[i])

^ multiply(0x03, column[(i + 1) % 4])

^ multiply(0x01, column[(i + 2) % 4])

^ multiply(0x01, column[(i + 3) % 4])

return result

# Apply MixColumns to each column

for i in range(4):

state_matrix[i] = mix_column(state_matrix[i])

return state_matrix

# Example usage:

initial_state = [

[0x32, 0x88, 0x31, 0xE0],

[0x43, 0x5A, 0x31, 0x37],

[0xF6, 0x30, 0x98, 0x07],


[0xA8, 0x8D, 0xA2, 0x34]

updated_state = mix_columns(initial_state)

for row in updated_state:

print(row)

CRT-------------------------------------------------------------------------------------------------------------------
-

import java.io.*;

public class CRT {

static int findMinX(int num[], int rem[], int k)

int x = 1;

while (true)

int j;

for (j=0; j<k; j++ )

if (x%num[j] != rem[j])

break;

if (j == k)

return x;

x++;

}
}

public static void main(String args[])

int num[] = {3, 4, 5};

int rem[] = {2, 3, 1};

int k = num.length;

System.out.println("x is " + findMinX(num, rem, k));

EUCLIDEAN---------------------------------------------------------------------------------------------------------
------

import java.util.Scanner;

public class eucld {

public static void main(String[] args)

Scanner scanner = new Scanner(System.in);

System.out.print("Enter the first number (a): ");

int a = scanner.nextInt();

System.out.print("Enter the second number (b): ");

int b = scanner.nextInt();

int[] result = extendedEuclidean(a, b);

System.out.println("GCD of " + a + " and " + b + " is: " + result[0]);

System.out.println("s value: " + result[1]);

System.out.println("t value: " + result[2]);


}

public static int[] extendedEuclidean(int a, int b) {

if (b == 0) {

return new int[]{a, 1, 0};

int[] prevResult = extendedEuclidean(b, a % b);

int gcd = prevResult[0];

int s = prevResult[2];

int t = prevResult[1] - (a / b) * prevResult[2];

return new int[]{gcd, s, t};

RC4-------------------------------------------------------------------------------------------------------------------

import java.util.Scanner;

public class RC4{

static int[] K = new int[256];

static int[] S = new int[256];

static int keylength;

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

System.out.print("\n==========================RC4Algorithm=======================
===\n");

System.out.print("\nEnter plain text: ");

String inpuString = sc.nextLine();


System.out.print("Enter Key: ");

String inpuString2 = sc.nextLine();

char[] plainText = inpuString.toCharArray();

char[] byteKey = inpuString2.toCharArray();

//Initialize and permute key and state

initAndPermute(byteKey);

char[] cipherText = encryptRC4(plainText);

System.out.print("\nCipher Text: ");

for (int i = 0; i < cipherText.length; i++) {

System.out.print(cipherText[i]);

//Initialize and permute key and state

initAndPermute(byteKey);

char[] decryptedText = decryptRC4(cipherText);

System.out.print("\nDecrypted Text: ");

for (int i = 0; i < decryptedText.length; i++) {

System.out.print(decryptedText[i]);

System.out.print("\n\n==========================RC4Algorithm=====================
=====\n");

sc.close();

private static void initAndPermute(char[] byteKey) {

if (byteKey.length > 256 || byteKey.length < 1) {

System.out.println("Key length must be between 1 to 256 chars");

} else {

// Creation of initial state and key bytes

keylength = byteKey.length;

for (int i = 0; i < 256; i++) {

S[i] = i;

K[i] = byteKey[i % keylength];


}

// Permuting state bytes based on values of key bytes

int j = 0;

for (int i = 0; i < 256; i++) {

j = (j + S[i] + K[i]) % 256;

int temp = S[i];

S[i] = S[j];

S[j] = temp;

private static char[] encryptRC4(char[] plainText) {

char[] cipherText = new char[plainText.length];

int i = 0;

int j = 0;

int key;

int plainTextLen = 0;

while (plainTextLen < plainText.length) {

// Key generation

i = (i + 1) % 256;

j = (j + S[i]) % 256;

int temp = S[i];

S[i] = S[j];

S[j] = temp;

key = S[(S[i] + S[j]) % 256];

// Encryption

cipherText[plainTextLen] = (char) (plainText[plainTextLen] ^ key);

plainTextLen++;

return cipherText;

}
private static char[] decryptRC4(char[] cipherText) {

char[] plainText = new char[cipherText.length];

int i = 0;

int j = 0;

int key;

int cipherLen = 0;

while (cipherLen < cipherText.length) {

// Key generation

i = (i + 1) % 256;

j = (j + S[i]) % 256;

int temp = S[i];

S[i] = S[j];

S[j] = temp;

key = S[(S[i] + S[j]) % 256];

// Encryption

plainText[cipherLen] = (char) (cipherText[cipherLen] ^ key);

cipherLen++;

return plainText;

You might also like