CNS
1) Write a program that contains a string (char pointer) with a value
“Hello world”. The program should XOR each character in this string
with 0 and displays the result.
Program:
#include <stdio.h>
#include <string.h>
void charToBinary(char c) {
int mat[8];
int j=0;
int decimal=0,i,power=1;
for (int i = 7; i >= 0; --i) {
mat[j]=((c>>i) &1)^0;
j++;}
for(i=7;i>=0;i--){
decimal+=mat[i]*power;
power*=2;}
char d=decimal;
printf("%c",d);}
int main() {
const char *str = "Hello world";
printf("Original string: %s\n", str);
printf("Result after XOR with 0: ");
for (int i = 0; i < strlen(str); ++i) {
charToBinary(str[i]);}
return 0;}
output:
Original string: Hello world
Result after XOR with 0: Hello world
2) Write a program that contains a string (char pointer) with a value
“Hello world”. The program should AND or and XOR each character in
this string with 127 and display the result.
Program:
#include <stdio.h>
#include <string.h>
void charWithAND(char c){
int mat[8];
int j=0;
int decimal=0,i,power=1;
for(int i=7;i>=0;i--){
mat[j]=((c>>i) &1)& 127;
j++;
}
for(int i=7;i>=0;i--){
decimal += mat[i]* power;
power*=2;
}
char d=decimal;
printf("%c",d);
}
void charWithXOR(char c){
int mat[8];
int j=0;
int decimal=0,i,power=1;
for(int i=7;i>=0;i--){
mat[j]=((c>>i) &1)^ 127;
j++;
}
for(int i=7;i>=0;i--){
decimal += mat[i]* power;
power*=2;
}
char d=decimal;
printf("%c",d);
}
int main() {
const char *str = "Hello world";
printf("Original string: %s\n", str);
printf("Result after AND with 1: ");
for (int i = 0; i < strlen(str); ++i) {
charWithAND(str[i]);
}
printf("Result after XOR with 1: ");
for (int i = 0; i < strlen(str); ++i) {
charWithXOR(str[i]);
}return 0;}
Output : Original string: Hello world
Result after AND with 1: Hello world
Result after XOR with 1: 9a
3) Write a program to perform encryption and decryption using the
following algorithms
1. Ceaser cipher
Program:
#include <stdio.h>
#include <string.h>
int main() {
char str[] ="Hello world";
char str1[20];
int i;
printf("String after encryption :");
for (int i = 0; str[i] != '\0'; i++) {
str1[i] = str[i]+3;
printf("%c",str1[i]);
}
printf("\n");
printf("Result after decrytion:");
for (int i = 0; str1[i] !='\0'; i++)
{
str1[i] = str1[i]-3;
printf("%c",str1[i]);
}
return 0;}
output:
String after encryption :Khoor#zruog
Result after decrytion: Hello world
2) Mono alphabetic
Program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define A_SIZE 26
#define MAX 100
void encrypt(char *ptext, char *ctext, int *ind) {
int len = strlen(ptext);
for (int i = 0; i < len; i++) {
int shift = rand() % A_SIZE;
ctext[i] = (ptext[i] - 'a' + shift) % A_SIZE + 'a';
ind[i] = shift;
}
ctext[len] = '\0';
}
void decrypt(char *ctext, char *dtext, int *ind) {
int len = strlen(ctext);
for (int i = 0; i < len; i++) {
dtext[i] = (ctext[i] - 'a' - ind[i] + A_SIZE) % A_SIZE + 'a';
}
dtext[len] = '\0';
}
int main() {
char ptext[MAX];
char ctext[MAX];
char dtext[MAX];
int ind[MAX];
printf("Enter plain text: ");
scanf("%s", ptext);
encrypt(ptext, ctext, ind);
printf("Encrypted Text: %s\n", ctext);
decrypt(ctext, dtext, ind);
printf("Decrypted Text: %s", dtext);
return 0;
}
Output :
Enter plain text: hello
Encrypted Text: uawcp
Decrypted Text: hello
3)Substitution cipher:
Program:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char text[100],key[100];
int i,a;
printf("enter plain text :");
scanf("%s",text);
printf("Enter the key:");
scanf("%s",key);
for(i=0;i<strlen(text);i++){
a=i%strlen(key);
text[i]= (((text[i]-'A') + (key[a]-'A'))%26)+'A';
}
printf("\nEncrypted text:%s",text);
for(i=0;i<strlen(text);i++){
a=i%strlen(key);
text[i]= ((((text[i]-'A') - (key[a]-'A'))+26)%26)+'A';
}
printf("\nDecrypted text: %s",text);
return 0;
}
Output:
Enter plain text :GREEKSFORGREEKS
Enter the key:AYUSH
Encrypted text:GPYWRSDIJNRCYCZ
Decrypted text: GREEKSFORGREEKS
4) Hill Cipher
Program:
#include <stdio.h>
#include <string.h>
#define N 2
#define ALPHABET_SIZE 26
int calculateDeterminant(int mat[N][N]) {
return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
}
int multiplicativeInverse(int num, int m) {
num = (num % m + m) % m;
for (int x = 1; x < m; x++)
if ((num * x) % m == 1)
return x;
return -1;
}
int main() {
char message[100];
int key[N][N] = {{7, 8}, {11, 11}};
int inverse[N][N];
int det = calculateDeterminant(key);
int detInv = multiplicativeInverse(det, ALPHABET_SIZE);
if (detInv == -1) {
printf("Key matrix is not invertible. Decryption not possible.\n");
return 1;
}
inverse[0][0] = key[1][1];
inverse[0][1] = -key[0][1];
inverse[1][0] = -key[1][0];
inverse[1][1] = key[0][0];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++) {
inverse[i][j] *= detInv;
inverse[i][j] %= ALPHABET_SIZE;
if (inverse[i][j] < 0)
inverse[i][j] += ALPHABET_SIZE;
}
printf("Enter plaintext: ");
scanf("%s", message);
int len = strlen(message);
int blocks = len / 2;
char padded_message[len + 1];
strcpy(padded_message, message);
if (len % 2 != 0) {
padded_message[len] = 'X';
padded_message[len + 1] = '\0';
blocks++;
}
printf("Encrypted Cipher Text: ");
for (int i = 0; i < blocks; i++) {
int block[N] = {padded_message[i * 2] - 'A', padded_message[i * 2 +
1] - 'A'};
int result[N] = {0};
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
result[j] += key[j][k] * block[k];
}
result[j] %= ALPHABET_SIZE;
}
for (int j = 0; j < N; j++) {
printf("%c", result[j] + 'A');
}
}
printf("\n");
printf("Enter ciphertext: ");
scanf("%s", message);
len = strlen(message);
blocks = len / 2;
printf("Decrypted Plain Text: ");
for (int i = 0; i < blocks; i++) {
int block[N] = {message[i * 2] - 'A', message[i * 2 + 1] - 'A'};
int result[N] = {0};
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
result[j] += inverse[j][k] * block[k];
}
result[j] %= ALPHABET_SIZE;
if (result[j] < 0)
result[j] += ALPHABET_SIZE;
}
for (int j = 0; j < N; j++) {
printf("%c", result[j] + 'A');
}
}
printf("\n");
return 0;
}
Output : Enter plaintext: SHORT
Encrypted Cipher Text: APADFU
Enter ciphertext: APADFU
Decrypted Plain Text: SHORTX
5) Play fair
Program:
#include <stdio.h>
#include <string.h>
#define SIZE 5
void generateMatrix(char key[], char matrix[SIZE][SIZE]) {
int used[26] = {0};
int len = strlen(key);
int row = 0, col = 0;
for (int i = 0; i < len; i++) {
if (key[i] != 'J') {
if (!used[key[i] - 'A']) {
matrix[row][col++] = key[i];
used[key[i] - 'A'] = 1;
if (col == SIZE) {
col = 0;
row++;
}}}}
for (char ch = 'A'; ch <= 'Z'; ch++) {
if (ch != 'J' && !used[ch - 'A']) {
matrix[row][col++] = ch;
if (col == SIZE) {
col = 0;
row++;
}}}}
void findPosition(char matrix[SIZE][SIZE], char ch, int *row, int *col) {
if (ch == 'J') ch = 'I';
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (matrix[i][j] == ch) {
*row = i;
*col = j;
return;
}}}}
void encryptPair(char matrix[SIZE][SIZE], char a, char b) {
int row1, col1, row2, col2;
findPosition(matrix, a, &row1, &col1);
findPosition(matrix, b, &row2, &col2);
if (row1 == row2) {
printf("%c%c ", matrix[row1][(col1 + 1) % SIZE], matrix[row2][(col2 +
1) % SIZE]);
} else if (col1 == col2) {
printf("%c%c ", matrix[(row1 + 1) % SIZE][col1], matrix[(row2 + 1) %
SIZE][col2]);
} else {
printf("%c%c ", matrix[row1][col2], matrix[row2][col1]);
}
}
void decryptPair(char matrix[SIZE][SIZE], char a, char b) {
int row1, col1, row2, col2;
findPosition(matrix, a, &row1, &col1);
findPosition(matrix, b, &row2, &col2);
if (row1 == row2) {
printf("%c%c ", matrix[row1][(col1 - 1 + SIZE) % SIZE],
matrix[row2][(col2 - 1 + SIZE) % SIZE]);
} else if (col1 == col2) {
printf("%c%c ", matrix[(row1 - 1 + SIZE) % SIZE][col1], matrix[(row2 -
1 + SIZE) % SIZE][col2]);
} else {
printf("%c%c ", matrix[row1][col2], matrix[row2][col1]);
}
}
int main() {
char key[100];
char plaintext[100];
char ciphertext[100];
char matrix[SIZE][SIZE];
printf("Enter the key: ");
scanf("%s", key);
printf("Enter the plaintext: ");
scanf("%s", plaintext);
generateMatrix(key, matrix);
printf("Encrypted Text: ");
for (int i = 0; i < strlen(plaintext); i += 2) {
if (plaintext[i] == plaintext[i + 1]) {
encryptPair(matrix, plaintext[i], 'X');
i--;
} else {
encryptPair(matrix, plaintext[i], plaintext[i + 1]);
}
}
printf("\n");
printf("Enter the ciphertext:");
scanf("%s", ciphertext);
printf("Decrypted Text: ");
for (int i = 0; i < strlen(ciphertext); i += 2) {
decryptPair(matrix, ciphertext[i], ciphertext[i + 1]);
}
printf("\n");
return 0;
}
Output : Enter the key: MONARCH
Enter the plaintext: HELLO
Encrypted Text: BC IZ GR
Decrypted Text: HE LX LO
5) Write a program to implement the DES algorithm logic
Program :
def hex2bin(s):
mp = {'0': "0000",
'1': "0001",
'2': "0010",
'3': "0011",
'4': "0100",
'5': "0101",
'6': "0110",
'7': "0111",
'8': "1000",
'9': "1001",
'A': "1010",
'B': "1011",
'C': "1100",
'D': "1101",
'E': "1110",
'F': "1111"}
bin = ""
for i in range(len(s)):
bin = bin + mp[s[i]]
return bin
def bin2hex(s):
mp = {"0000": '0',
"0001": '1',
"0010": '2',
"0011": '3',
"0100": '4',
"0101": '5',
"0110": '6',
"0111": '7',
"1000": '8',
"1001": '9',
"1010": 'A',
"1011": 'B',
"1100": 'C',
"1101": 'D',
"1110": 'E',
"1111": 'F'}
hex = ""
for i in range(0, len(s), 4):
ch = ""
ch = ch + s[i]
ch = ch + s[i + 1]
ch = ch + s[i + 2]
ch = ch + s[i + 3]
hex = hex + mp[ch]
return hex
def bin2dec(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
return decimal
def dec2bin(num):
res = bin(num).replace("0b", "")
if(len(res) % 4 != 0):
div = len(res) / 4
div = int(div)
counter = (4 * (div + 1)) - len(res)
for i in range(0, counter):
res = '0' + res
return res
def permute(k, arr, n):
permutation = ""
for i in range(0, n):
permutation = permutation + k[arr[i] - 1]
return permutation
def shift_left(k, nth_shifts):
s = ""
for i in range(nth_shifts):
for j in range(1, len(k)):
s = s + k[j]
s = s + k[0]
k=s
s = ""
return k
def xor(a, b):
ans = ""
for i in range(len(a)):
if a[i] == b[i]:
ans = ans + "0"
else:
ans = ans + "1"
return ans
initial_perm = [58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7]
exp_d = [32, 1, 2, 3, 4, 5, 4, 5,
6, 7, 8, 9, 8, 9, 10, 11,
12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21,
22, 23, 24, 25, 24, 25, 26, 27,
28, 29, 28, 29, 30, 31, 32, 1]
per = [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]
sbox = [[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],
[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],
[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],
[[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],
[[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],
[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
[4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],
[[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],
[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]]
final_perm = [40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25]
def encrypt(pt, rkb, rk):
pt = hex2bin(pt)
pt = permute(pt, initial_perm, 64)
print("After initial permutation", bin2hex(pt))
left = pt[0:32]
right = pt[32:64]
for i in range(0, 16):
right_expanded = permute(right, exp_d, 48)
xor_x = xor(right_expanded, rkb[i])
sbox_str = ""
for j in range(0, 8):
row = bin2dec(int(xor_x[j * 6] + xor_x[j * 6 + 5]))
col = bin2dec(
int(xor_x[j * 6 + 1] + xor_x[j * 6 + 2] + xor_x[j *
6 + 3] + xor_x[j * 6 + 4]))
val = sbox[j][row][col]
sbox_str = sbox_str + dec2bin(val)
sbox_str = permute(sbox_str, per, 32)
result = xor(left, sbox_str)
left = result
combine = left + right
cipher_text = permute(combine, final_perm, 64)
return cipher_text
pt = "123456ABCD132536"
key = "AABB09182736CCDD"
key = hex2bin(key)
keyp = [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]
key = permute(key, keyp, 56)
shift_table = [1, 1, 2, 2,
2, 2, 2, 2,
1, 2, 2, 2,
2, 2, 2, 1]
key_comp = [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]
left = key[0:28]
right = key[28:56]
rkb = []
rk = []
for i in range(0, 16):
left = shift_left(left, shift_table[i])
right = shift_left(right, shift_table[i])
combine_str = left + right
round_key = permute(combine_str, key_comp, 48)
rkb.append(round_key)
rk.append(bin2hex(round_key))
print("Encryption")
cipher_text = bin2hex(encrypt(pt, rkb, rk))
print("Cipher Text : ", cipher_text)
print("Decryption")
rkb_rev = rkb[::-1]
rk_rev = rk[::-1]
text = bin2hex(encrypt(cipher_text, rkb_rev, rk_rev))
print("Plain Text : ", text)
Output : Encryption
After initial permutation 14A7D67818CA18AD
Cipher Text : 523407EADC466576
Decryption
After initial permutation F993F64418CA18AD
Plain Text : 123456ABCD132536
6) Write a program to implement the AES algorithm logic.
Program :
s_box_hex = (
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,
)
s_box_matrix = [
[s_box_hex[16 * i + j] for j in range(16)] for i in range(16)
]
def byte_to_hex(byte):
return "{:02x}".format(byte)
def print_matrix(matrix):
for row in matrix:
print(" ".join([byte_to_hex(byte) for byte in row]))
def sub_bytes(matrix):
return [[s_box_matrix[byte // 16][byte % 16] for byte in row] for row in
matrix]
def shift_rows(matrix):
return [row[i:] + row[:i] for i, row in enumerate(matrix)]
def mix_columns(matrix):
mix_matrix = [
[0x02, 0x03, 0x01, 0x01],
[0x01, 0x02, 0x03, 0x01],
[0x01, 0x01, 0x02, 0x03],
[0x03, 0x01, 0x01, 0x02]
]
new_matrix = []
for col in range(4):
column = [matrix[row][col] for row in range(4)]
new_column = [
(gf_multiply(column[0], mix_matrix[0][0]) ^
gf_multiply(column[1], mix_matrix[0][1]) ^
gf_multiply(column[2], mix_matrix[0][2]) ^
gf_multiply(column[3], mix_matrix[0][3])),
(gf_multiply(column[0], mix_matrix[1][0]) ^
gf_multiply(column[1], mix_matrix[1][1]) ^
gf_multiply(column[2], mix_matrix[1][2]) ^
gf_multiply(column[3], mix_matrix[1][3])),
(gf_multiply(column[0], mix_matrix[2][0]) ^
gf_multiply(column[1], mix_matrix[2][1]) ^
gf_multiply(column[2], mix_matrix[2][2]) ^
gf_multiply(column[3], mix_matrix[2][3])),
(gf_multiply(column[0], mix_matrix[3][0]) ^
gf_multiply(column[1], mix_matrix[3][1]) ^
gf_multiply(column[2], mix_matrix[3][2]) ^
gf_multiply(column[3], mix_matrix[3][3])),
]
new_matrix.append(new_column)
return new_matrix
def gf_multiply(a, b):
result = 0
while b:
if b & 1:
result ^= a
a <<= 1
if a & 0x100:
a ^= 0x11b
b >>= 1
return result
def add_round_key(matrix, round_key):
return [[matrix[i][j] ^ round_key[i][j] for j in range(4)] for i in range(4)]
def aes_encrypt(input_matrix, round_key):
print("Input:")
print_matrix(input_matrix)
print()
state = input_matrix
print("After SubBytes:")
state = sub_bytes(state)
print_matrix(state)
print()
print("After ShiftRows:")
state = shift_rows(state)
print_matrix(state)
print()
print("After MixColumns:")
state = mix_columns(state)
print_matrix(state)
print()
print("After AddRoundKey:")
state = add_round_key(state, round_key)
print_matrix(state)
print()
input_matrix = [
[0xe0, 0x32, 0x3a, 0x0a],
[0x49, 0x06, 0x24, 0x5c],
[0xc2, 0xd3, 0xac, 0x62],
[0x91, 0x95, 0xe4, 0x79]
]
round_key = [
[0x2b, 0x7e, 0x15, 0x16],
[0x28, 0xae, 0xd2, 0xa6],
[0xab, 0xf7, 0x97, 0x7e],
[0x46, 0x95, 0x32, 0x6c]
]
aes_encrypt(input_matrix, round_key)
output :
Input:
e0 32 3a 0a
49 06 24 5c
c2 d3 ac 62
91 95 e4 79
After SubBytes:
e1 23 80 67
3b 6f 36 4a
25 66 91 aa
81 2a 69 b6
After ShiftRows:
e1 23 80 67
6f 36 4a 3b
91 aa 25 66
b6 81 2a 69
After MixColumns:
4f 21 76 b1
37 2b c2 e0
ca 51 fe a0
8c d2 2b 26
After AddRoundKey:
64 5f 63 a7
1f 85 10 46
61 a6 69 de
ca 47 19 4a
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
]
rcon = [
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
]
def key_schedule_core(word, i):
word = word[1:] + word[:1]
word = [s_box[b] for b in word]
word[0] ^= rcon[i]
return word
def key_expansion(key):
round_keys = [key[:]]
for i in range(10):
temp = round_keys[-1][:]
temp = key_schedule_core(temp, i)
temp[0] ^= round_keys[-1][0]
for j in range(1, 4):
temp[j] ^= round_keys[-1][j]
round_keys.append(temp)
return round_keys
if __name__ == "_main_":
key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x97, 0x25,
0x43, 0x3c, 0xe3, 0xf7]
round_keys = key_expansion(key)
for i, round_key in enumerate(round_keys):
print(f"Round Key {i}: {round_key}")
Output :
Round Key 0: [43, 126, 21, 22, 40, 174, 210, 166, 171, 247, 151, 37, 67, 60, 227,
247]
Round Key 1: [217, 39, 82, 34, 228, 181, 36, 98, 104, 136, 63, 26, 235, 17, 104,
241]
Round Key 2: [23, 39, 193, 75, 213, 54, 170, 69, 196, 117, 162, 233, 130, 69,
161, 53]
Round Key 3: [223, 95, 114, 72, 5, 172, 110, 28, 157, 58, 30, 19, 110, 50, 150,
240]
Round Key 4: [24, 31, 32, 35, 145, 159, 156, 94, 128, 114, 125, 159, 35, 144,
140, 158]
Round Key 5: [200, 168, 6, 162, 219, 222, 88, 205, 64, 255, 219, 38, 96, 100, 11,
173]
Round Key 6: [42, 199, 60, 27, 29, 106, 189, 9, 22, 185, 247, 208, 67, 43, 149,
232]
Round Key 7: [172, 44, 147, 191, 2, 122, 1, 71, 86, 104, 112, 26, 241, 42, 155,
229]
Round Key 8: [93, 240, 155, 200, 218, 124, 160, 177, 69, 81, 162, 161, 229, 20,
217, 145]
Round Key 9: [202, 228, 115, 159, 16, 224, 200, 110, 209, 58, 50, 217, 250, 53,
129, 76]
Round Key 10: [149, 107, 168, 85, 225, 232, 159, 62, 128, 35, 53, 45, 150, 12,
41, 116]
7) Write a program to implement RSA algorithm
Program :
import math
import random
def gcd(a, h):
temp = 0
while(1):
temp = a % h
if (temp == 0):
return h
a=h
h = temp
p = int(input("Enter a prime number (p): "))
q = int(input("Enter another prime number (q): "))
n=p*q
phi = (p - 1) * (q - 1)
def generate_e(phi):
valid_e_values = []
for e in range(2, phi):
if gcd(e, phi) == 1:
valid_e_values.append(e)
return valid_e_values
valid_e_values = generate_e(phi)
print("Possible 'e' values:", valid_e_values)
e_choice = int(input("Choose one of the possible 'e' values: "))
def generate_d(e, phi):
k=0
while True:
d = (1 + (k * phi)) / e
if d.is_integer():
return int(d)
k += 1
d = generate_d(e_choice, phi)
msg = int(input("Enter the message to be encrypted: "))
print("Message data = ", msg)
c = pow(msg, e_choice, n)
print("Encrypted data = ", c)
m = pow(c, d, n)
print("Original Message Sent = ", m)
Output : Enter a prime number (p): 13
Enter another prime number (q): 17
Possible 'e' values: [5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 53,
55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97, 101, 103, 107, 109, 113,
115, 119, 121, 125, 127, 131, 133, 137, 139, 143, 145, 149, 151, 155, 157, 161,
163, 167, 169, 173, 175, 179, 181, 185, 187, 191]
Choose one of the possible 'e' values: 35
Enter the message to be encrypted: 72
Message data = 72
Encrypted data = 95
Original Message Sent = 72
8) Implement the Diffie-Hellman Key Exchange mechanism
Program:
def prime_checker(p):
if p < 1:
return False
elif p > 1:
if p == 2:
return True
for i in range(2, int(p**0.5) + 1):
if p % i == 0:
return False
return True
def prime_factors(n):
factors = []
i=2
while i * i <= n:
if n % i:
i += 1
else:
n //= i
factors.append(i)
if n > 1:
factors.append(n)
return factors
def primitive_check(g, p):
factors = prime_factors(p - 1)
for q in factors:
if pow(g, (p - 1) // q, p) == 1:
return False
return True
P = int(input("Enter P: "))
primitive_roots = []
for g in range(1, P):
if primitive_check(g, P):
primitive_roots.append(g)
if not primitive_roots:
print(f"No primitive roots found for {P}")
else:
print(f"Primitive roots for {P} are: {primitive_roots}")
while True:
G = int(input(f"Choose one of the primitive roots for {P}: "))
if G not in primitive_roots:
print(f"{G} is not a primitive root of {P}, Please Try Again!")
continue
break
x1, x2 = int(input("Enter The Private Key Of User 1 : ")), int(input("Enter The
Private Key Of User 2 : "))
y1, y2 = pow(G, x1) % P, pow(G, x2) % P
k1, k2 = pow(y2, x1) % P, pow(y1, x2) % P
print(f"\nSecret Key For User 1 Is {k1}\nSecret Key For User 2 Is {k2}\n")
if k1 == k2:
print("Keys Have Been Exchanged Successfully")
else:
print("Keys Have Not Been Exchanged Successfully")
Output :
Enter P: 11
Primitive roots for 11 are: [2, 6, 7, 8]
Choose one of the primitive roots for 11: 7
Enter The Private Key Of User 1 : 3
Enter The Private Key Of User 2 : 6
Secret Key For User 1 Is 9
Secret Key For User 2 Is 9
Keys Have Been Exchanged Successfully
9) Calculate the message digest of a text using the SHA-1
algorithm
Program:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define SIZE 5
#define ROTLEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20
typedef struct {
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[SHA1_BLOCK_SIZE];
} SHA1_CTX;
void sha1_transform(SHA1_CTX *ctx, const unsigned char *data);
void sha1_init(SHA1_CTX *ctx);
void sha1_update(SHA1_CTX *ctx, const unsigned char *data, size_t len);
void sha1_final(SHA1_CTX *ctx, unsigned char *digest);
void sha1_transform(SHA1_CTX *ctx, const unsigned char *data) {
uint32_t temp, w[80];
uint32_t a, b, c, d, e;
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
for (int i = 0; i < 16; i++) {
w[i] = ((uint32_t)data[i * 4] << 24) |
((uint32_t)data[i * 4 + 1] << 16) |
((uint32_t)data[i * 4 + 2] << 8) |
((uint32_t)data[i * 4 + 3]);
for (int i = 16; i < 80; i++) {
w[i] = ROTLEFT(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
}
for (int i = 0; i < 80; i++) {
if (i < 20)
temp = (b & c) | ((~b) & d);
else if (i < 40)
temp = b ^ c ^ d;
else if (i < 60)
temp = (b & c) | (b & d) | (c & d);
else
temp = b ^ c ^ d;
temp = ROTLEFT(a, 5) + temp + e + w[i] + 0x5A827999;
e = d;
d = c;
c = ROTLEFT(b, 30);
b = a;
a = temp;
}
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
}
void sha1_init(SHA1_CTX *ctx) {
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
ctx->count[0] = ctx->count[1] = 0;
}
void sha1_update(SHA1_CTX *ctx, const unsigned char *data, size_t len) {
size_t i;
for (i = 0; i < len; i++) {
ctx->buffer[ctx->count[1]++] = data[i];
if (ctx->count[1] == SHA1_BLOCK_SIZE) {
sha1_transform(ctx, ctx->buffer);
ctx->count[0] += SHA1_BLOCK_SIZE / 8; // Update count[0] by the
number of bits processed
ctx->count[1] = 0;
}
}
}
void sha1_final(SHA1_CTX *ctx, unsigned char *digest) {
uint32_t i;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((ctx->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) *
8)) & 255);
}
unsigned char c = 0x80;
sha1_update(ctx, &c, 1);
while ((ctx->count[1] & 63) != 56) {
c = 0;
sha1_update(ctx, finalcount, 8);
}
sha1_update(ctx, finalcount, 8);
sha1_update(ctx, (const unsigned char *)&ctx->count[1], 4); // Append the
length of the message
sha1_update(ctx, (const unsigned char *)&ctx->count[0], 4);
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}
}
int main() {
const char *text = "Akash Ipparthi";
size_t len = strlen(text);
SHA1_CTX ctx;
unsigned char digest[SHA1_DIGEST_SIZE];
sha1_init(&ctx);
sha1_update(&ctx, (const unsigned char *)text, len);
sha1_final(&ctx, digest);
printf("SHA-1 Digest: ");
for (int i = 0; i < SHA1_DIGEST_SIZE; i++) {
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
Output :
SHA-1 Digest: 6e3a07c3f4f70789ea805c2e30..
10)Calculate the message digest of a text using the MD5 algorithm
Program:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
const uint32_t k[] = {0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2};
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22,
7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20,
5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23,
4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21,
6, 10, 15, 21, 6, 10, 15, 21};
void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {
uint32_t h0, h1, h2, h3;
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
size_t new_len = ((((initial_len + 8) / 64) + 1) * 64) - 8;
uint8_t *msg = (uint8_t *)malloc(new_len + 64);
memcpy(msg, initial_msg, initial_len);
msg[initial_len] = 0x80;
uint32_t bits_len = 8 * initial_len;
memcpy(msg + new_len, &bits_len, 4);
for (int offset = 0; offset < new_len; offset += 64) {
uint32_t *w = (uint32_t *)(msg + offset);
uint32_t a = h0, b = h1, c = h2, d = h3;
for (int i = 0; i < 64; i++) {
uint32_t f, g;
if (i < 16) {
f = (b & c) | ((~b) & d);
g = i;
} else if (i < 32) {
f = (d & b) | ((~d) & c);
g = (5 * i + 1) % 16;
} else if (i < 48) {
f = b ^ c ^ d;
g = (3 * i + 5) % 16;
} else {
f = c ^ (b | (~d));
g = (7 * i) % 16;
}
uint32_t temp = d;
d = c;
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
a = temp;
}
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
free(msg);
memcpy(digest, &h0, sizeof(h0));
memcpy(digest + sizeof(h0), &h1, sizeof(h1));
memcpy(digest + sizeof(h0) + sizeof(h1), &h2, sizeof(h2));
memcpy(digest + sizeof(h0) + sizeof(h1) + sizeof(h2), &h3, sizeof(h3));
}
int main() {
char text[] = "Hello, world!";
uint8_t digest[16];
md5((uint8_t *)text, strlen(text), digest);
printf("MD5 digest of '%s': ", text);
for (int i = 0; i < 16; i++) {
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
Output : MD5 digest of 'Akash': 31308bd1847f0a2c85b4 bc16f8790dab
10) Implement the Signature Scheme using Digital Signature Standard
Program:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MESSAGE "HELLO,WORLD!"
static const uint32_t p = 101;
static const uint32_t q = 13;
static const uint32_t g = 23;
static const uint32_t x = 16;
static const uint32_t y = 19;
typedef struct {
uint32_t r;
uint32_t s;
} DSA_Signature;
void sha1(const char *message, uint8_t hash[20]) {
memcpy(hash, message, 20);
}
uint32_t mod_exp(uint32_t base, uint32_t exponent, uint32_t modulus) {
uint32_t result = 1;
while (exponent > 0) {
if (exponent % 2 == 1) {
result = (result * base) % modulus;
}
base = (base * base) % modulus;
exponent /= 2;
}
return result;
}
DSA_Signature dsa_sign(const char *message) {
uint8_t hash[20];
sha1(message, hash);
DSA_Signature Signature;
uint32_t k = rand() % (q - 1) + 1;
Signature.r = mod_exp(g, k, p) % q;
uint32_t k_inv = 0;
for (uint32_t i = 1; i < q; i++) {
if ((k * i) % q == 1) {
k_inv = i;
break;
}
}
Signature.s = (k_inv * (hash[0] + x * Signature.r)) % q;
return Signature;
}
int dsa_verify(const char *message, DSA_Signature Signature) {
uint8_t hash[20];
sha1(message, hash);
uint32_t w = 0;
for (uint32_t i = 1; i < q; i++) {
if ((Signature.s * i) % q == 1) {
w = i;
break;
}
}
uint32_t u1 = (hash[0] * w) % q;
uint32_t u2 = (Signature.r * w) % q;
uint32_t v = ((mod_exp(g, u1, p) * mod_exp(y, u2, p)) % p) % q;
return v;
}
int main() {
srand(time(NULL));
DSA_Signature Signature = dsa_sign(MESSAGE);
if (dsa_verify(MESSAGE, Signature)) {
printf("Signature verified Successfully \n");
} else {
printf("Signature Verification Failed \n");
}
return 0;
}
Output : Signature verified Successfully