0% found this document useful (0 votes)
3 views24 pages

Cryptography

The document is a lab report on Cryptography and Network Security, prepared by Pranta Routh for Md. Mehrab Hossain. It includes algorithms and code implementations for various topics such as GCD calculation, prime checking using the sieve method, prime factorization, hash functions, parity checks, the Merkle-Damgård construction, and Simplified DES encryption and decryption.

Uploaded by

rafiuljim339
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views24 pages

Cryptography

The document is a lab report on Cryptography and Network Security, prepared by Pranta Routh for Md. Mehrab Hossain. It includes algorithms and code implementations for various topics such as GCD calculation, prime checking using the sieve method, prime factorization, hash functions, parity checks, the Merkle-Damgård construction, and Simplified DES encryption and decryption.

Uploaded by

rafiuljim339
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Lab Report

On
Cryptography And Network
Security Sessional
Computer Science And Engineering
Sylhet Engineering College
Prepared For
Md. Mehrab Hossain
Adjunct Lecturer
Department: CSE

Prepared By
Pranta Routh
Reg: 2020331524

Cryptography And Network


Security Sessional
(CSE 610)
Date: 22/05/25
Sylhet Engineering College
1.Calculating GCD:

Algorithm:

Given two integers a and b:

1. If b == 0, then GCD(a, b) = a.
2. Otherwise, compute GCD(b, a % b) recursively.

Code:
#include <iostream>
using namespace std;

int gcd(int a, int b) {


if (b == 0)

return a;
return gcd(b, a % b);

}
int main() {

int a, b;

cout << "Enter two positive integers: ";


cin >> a >> b;
int result = gcd(a, b);
cout << "GCD of " << a << " and " << b << " is: " << result << endl;

return 0;

Input:

Output:
2.Prime Checking Using Seive:

Algorithm:

1. Create a boolean array isPrime[] of size n+1, initialized as true.

2. Set isPrime[0] = false and isPrime[1] = false.

3. Start from p = 2 to sqrt(n):

- If isPrime[p] is true, mark all multiples of p (i.e., p*p, p*p + p, ... ≤ n) as false.

4. After the loop, isPrime[i] == true means i is a prime number.

Code:
#include <iostream>

#include <vector>

using namespace std;

void sieve(int n, vector<bool> &isPrime) {

isPrime.assign(n + 1, true);

isPrime[0] = isPrime[1] = false;


for (int p = 2; p * p <= n; p++) {

if (isPrime[p]) {

for (int i = p * p; i <= n; i += p)

isPrime[i] = false;

int main() {

int limit, num;

cout << "Enter the upper limit for primes (e.g., 1000): ";

cin >> limit;

vector<bool> isPrime;

sieve(limit, isPrime);

cout << "Enter a number to check if it's prime (<= " << limit << "): ";

cin >> num;

if (num <= limit) {


if (isPrime[num])

cout << num << " is a prime number." << endl;

else

cout << num << " is not a prime number." << endl;

} else {

cout << "Number exceeds the sieve limit. Increase the limit." << endl;

return 0;

Input:

Output:
3. Prime Factorization:

Algorithm:

1. Divide n by 2 until it’s odd.

2. Then, try dividing n by all odd numbers from 3 up to √n.

3. Each time a factor is found, divide n and store the factor.

4. If n becomes > 1, it's also a prime factor.

Code:
#include <iostream>
#include <vector>
using namespace std;

vector<int> primeFactorization(int n) {

vector<int> factors;

// Step 1: Factor out 2s


while (n % 2 == 0) {

factors.push_back(2);
n /= 2;

}
for (int i = 3; i * i <= n; i += 2) {
while (n % i == 0) {
factors.push_back(i);

n /= i;
}

}
if (n > 2)

factors.push_back(n);

return factors;
}

int main() {

int num;
cout << "Enter a positive integer to factor: ";

cin >> num;

vector<int> factors = primeFactorization(num);


cout << "Prime factors of " << num << " are: ";

for (int f : factors)


cout << f << " ";

cout << endl;

return 0;
}
Input:

Output:
4.Normal Hash Function:

Algorithm:
A normal (non-secure) hash function for demonstration:

1. Initialize a hash value (e.g., 0).


2. For each character in the input:

- Multiply the current hash by a prime (e.g., 31 or 101).

- Add the ASCII value of the character.

- Take modulo of a large number to avoid overflow.

This is not secure for real-world cryptography but useful for learning purposes.

Code:

#include <iostream>
#include <string>

using namespace std;

unsigned int simpleHash(string input) {


unsigned int hash = 0;

int prime = 31; // A small prime number

for (char ch : input) {


hash = (hash * prime + ch) % 1000000007; // Use a large prime modulus

}
return hash;

int main() {
string text;

cout << "Enter a string to hash: ";

getline(cin, text);

unsigned int hashedValue = simpleHash(text);

cout << "Hashed value: " << hashedValue << endl;

return 0;
}
Input:

Output:
5.Parity Check Code:

Algorithm:

1. Take the input string (binary or ASCII).

2. Count the number of 1s in the binary representation of the data.

3. If the number of 1s is even, set parity bit to 0.

4. If the number of 1s is odd, set parity bit to 1.

5. Append the parity bit to the data (for transmission or hashing).

Code:

#include <iostream>

#include <string>

using namespace std;

int computeParity(string input) {

int countOnes = 0;

for (char ch : input) {

unsigned char byte = ch;

while (byte) {
countOnes += byte & 1;

byte >>= 1;

return countOnes % 2;

int main() {

string data;

cout << "Enter a string: ";

getline(cin, data);

int parityBit = computeParity(data);

cout << "Computed parity bit (even parity): " << parityBit << endl;

return 0;

}
Input:

Output:
6. Merkle – Damgard :

Algorithm:

1. Let h0 be an initial value (IV).


2. Split the input message into n blocks: M1, M2, ..., Mn.
3. For each block Mi, compute:

4. Final hash = hn

Code:
#include <iostream>
#include <string>

#include <vector>
#include <iomanip>
using namespace std;

unsigned int compress(unsigned int h, unsigned int block) {

h ^= block;
h = (h << 3) | (h >> (32 - 3)); // Left rotate by 3

return h;
}
unsigned int blockToInt(const string& block) {
unsigned int val = 0;

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


val = (val << 8) + (i < block.size() ? (unsigned char)block[i] : 0);

}
return val;

string merkleDamgardHash(string message) {


while (message.size() % 4 != 0)

message += '\0';

unsigned int h = 0xabcdef12; // Initial hash value (IV)

for (size_t i = 0; i < message.size(); i += 4) {


string block = message.substr(i, 4);

unsigned int blockInt = blockToInt(block);


h = compress(h, blockInt);

stringstream ss;
ss << hex << setfill('0') << setw(8) << h;

return ss.str();
}
int main() {

string input;
cout << "Enter a string to hash using Merkle–Damgård: ";

getline(cin, input);

string hashValue = merkleDamgardHash(input);


cout << "Hash value: " << hashValue << endl;

return 0;

Input:

Output:
7. Simplified DES (SDES):

Algorithm:

1. Key Generation (from 10-bit key)

 P10: Permutation of the 10-bit key.


 LS-1: Left-shift both halves by 1 → generate K1 via P8.
 LS-2: Left-shift both halves by 2 → generate K2 via P8.

2. Initial Permutation (IP) on 8-bit plaintext

3. First Round

 Expansion/Permutation (EP) of right half


 XOR with K1
 S-Boxes (S0, S1)
 P4 permutation
 XOR with left half

4. Swap the two halves

5. Second Round

 Same steps, but use K2

6. Inverse Initial Permutation (IP⁻¹) on the result


Code:

#include <iostream>

#include <bitset>
#include <vector>

using namespace std;

int permute(int input, const int* perm, int n) {


int output = 0;

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


output <<= 1;

output |= (input >> (10 - perm[i])) & 1;


}

return output;
}

int SBOX[2][4][4] = {

{ {1,0,3,2}, {3,2,1,0}, {0,2,1,3}, {3,1,3,2} },


{ {0,1,2,3}, {2,0,1,3}, {3,0,1,0}, {2,1,0,3} }

};

void generateKeys(int key10, int &k1, int &k2) {


const int P10[10] = {3,5,2,7,4,10,1,9,8,6};

const int P8[8] = {6,3,7,4,8,5,10,9};


int p10 = permute(key10, P10, 10);
int left = (p10 >> 5) & 0b11111;
int right = p10 & 0b11111;

left = ((left << 1) | (left >> 4)) & 0b11111;


right = ((right << 1) | (right >> 4)) & 0b11111;

k1 = permute((left << 5) | right, P8, 8);


left = ((left << 2) | (left >> 3)) & 0b11111;

right = ((right << 2) | (right >> 3)) & 0b11111;


k2 = permute((left << 5) | right, P8, 8);

int sbox(int input) {


int left = (input >> 4) & 0xF;

int right = input & 0xF;

int row = ((left & 0x8) >> 2) | (left & 1);


int col = (left >> 1) & 0x3;

int s0 = SBOX[0][row][col];

row = ((right & 0x8) >> 2) | (right & 1);


col = (right >> 1) & 0x3;

int s1 = SBOX[1][row][col];

return (s0 << 2) | s1;


}
int fK(int input, int subkey) {
const int EP[8] = {4,1,2,3,2,3,4,1};

const int P4[4] = {2,4,3,1};

int left = (input >> 4) & 0xF;


int right = input & 0xF;

int ep = permute(right, EP, 8);


int xorOut = ep ^ subkey;

int sb = sbox(xorOut);

int p4 = permute(sb, P4, 4);


return ((left ^ p4) << 4) | right;

int SDES_encrypt(int plaintext, int key10) {


const int IP[8] = {2,6,3,1,4,8,5,7};

const int IP1[8] = {4,1,3,5,7,2,8,6};

int k1, k2;


generateKeys(key10, k1, k2);

int ip = permute(plaintext, IP, 8);


int round1 = fK(ip, k1);

round1 = ((round1 & 0xF) << 4) | ((round1 >> 4) & 0xF);


int round2 = fK(round1, k2);
int cipher = permute(round2, IP1, 8);

return cipher;
}

int SDES_decrypt(int ciphertext, int key10) {


const int IP[8] = {2,6,3,1,4,8,5,7};

const int IP1[8] = {4,1,3,5,7,2,8,6};

int k1, k2;


generateKeys(key10, k1, k2);

int ip = permute(ciphertext, IP, 8);

int round1 = fK(ip, k2);


round1 = ((round1 & 0xF) << 4) | ((round1 >> 4) & 0xF);

int round2 = fK(round1, k1);

int plain = permute(round2, IP1, 8);

return plain;
}

int main() {

int plaintext, key10;

cout << "Enter 8-bit plaintext (in decimal, 0-255): ";


cin >> plaintext;

cout << "Enter 10-bit key (in decimal, 0-1023): ";


cin >> key10;

int ciphertext = SDES_encrypt(plaintext, key10);


cout << "Encrypted ciphertext: " << bitset<8>(ciphertext) << " (" << ciphertext
<< ")\n";

int decrypted = SDES_decrypt(ciphertext, key10);


cout << "Decrypted plaintext : " << bitset<8>(decrypted) << " (" << decrypted
<< ")\n";

return 0;

Input:

Output:

You might also like