0% found this document useful (0 votes)
49 views26 pages

Crypto Combine

1. The document describes Java programs that implement symmetric encryption using DES and AES. It includes code for a server and client that can encrypt and decrypt messages using a shared secret key with DES using 64-bit keys and blocks, and AES using 128-bit keys and plaintext. 2. The programs establish a connection between the server and client, generate encryption keys, encrypt and decrypt messages, and close resources when done. The encrypted messages are sent from the client to the server and decrypted.
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)
49 views26 pages

Crypto Combine

1. The document describes Java programs that implement symmetric encryption using DES and AES. It includes code for a server and client that can encrypt and decrypt messages using a shared secret key with DES using 64-bit keys and blocks, and AES using 128-bit keys and plaintext. 2. The programs establish a connection between the server and client, generate encryption keys, encrypt and decrypt messages, and close resources when done. The encrypted messages are sent from the client to the server and decrypted.
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/ 26

1.

Consider a sender and receiver who need to exchange data confidentially


using symmetric encryption. Write program that implements DES encryption
and decryption using a 64 bit key size and 64 bit block size
CODE:
DesServer.java
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Base64;

public class DesServer {


public static void main(String[] args) {
try {
// Server socket setup
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server waiting for connection...");

// Accept client connection


Socket socket = serverSocket.accept();
System.out.println("Client connected.");

// Generate a random 64-bit key (8 bytes)


byte[] keyBytes = "MySecret".getBytes();
// Replace with a secure key generation mechanism
DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(desKeySpec);

// Initialize the Cipher for encryption


Cipher encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);

// Initialize the Cipher for decryption


Cipher decryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
// Setup input and output streams
DataInputStream inputStream = new
DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new
DataOutputStream(socket.getOutputStream());

// Receive encrypted message from client


String encryptedMessage = inputStream.readUTF();
System.out.println("Received encrypted message: " +
encryptedMessage);

// Decrypt the message


byte[] decryptedBytes =
decryptCipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
String decryptedMessage = new String(decryptedBytes);
System.out.println("Decrypted message: " + decryptedMessage);

// Close resources
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

desClient.java
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Base64;
import java.util.Scanner;

public class DesClient {


public static void main(String[] args) {
try {
// Connect to the server
Socket socket = new Socket("localhost", 12345);
// Generate a random 64-bit key (8 bytes)
byte[] keyBytes = "MySecret".getBytes();
DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(desKeySpec);
// Initialize the Cipher for encryption
Cipher encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
// Initialize the Cipher for decryption
Cipher decryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
// Setup input and output streams
DataInputStream inputStream = new
DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new
DataOutputStream(socket.getOutputStream());
// Take input in the form of 0s and 1s from the user
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a binary message (0s and 1s): ");
String binaryMessage = scanner.nextLine();
// Encrypt the message
byte[] encryptedBytes =
encryptCipher.doFinal(binaryMessage.getBytes());
String encryptedMessage =
Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("Encrypted message: " + encryptedMessage);
// Send the encrypted message to the server
outputStream.writeUTF(encryptedMessage);
// Close resources
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
OUTPUT:
Server side:

Client side:
2.Consider a sender and receiver who need to exchange data confidentially
using symmetric encryption. Write program that implements AES encryption
and decryption using a 128 bits key size and 128 bit plaintext size.
CODE:
AesServer.java
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Base64;

public class AesServer {


public static void main(String[] args) {
try {
// Server socket setup
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server waiting for connection...");

// Accept client connection


Socket socket = serverSocket.accept();
System.out.println("Client connected.");

// Generate AES key


byte[] keyBytes = "MySecretKey12345".getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "AES");

// Initialize the Cipher for encryption


Cipher encryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);

// Initialize the Cipher for decryption


Cipher decryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);

// Setup input and output streams


DataInputStream inputStream = new
DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new
DataOutputStream(socket.getOutputStream());

// Receive encrypted message from client


String encryptedMessage = inputStream.readUTF();
System.out.println("Received encrypted message: " +
encryptedMessage);

// Decrypt the message


byte[] decryptedBytes =
decryptCipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
String decryptedMessage = new String(decryptedBytes);
System.out.println("Decrypted message: " + decryptedMessage);

// Close resources
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

AesClient.java
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Base64;
import java.util.Scanner;

public class AesClient {


public static void main(String[] args) {
try {
// Connect to the server
Socket socket = new Socket("localhost", 12345);
// Generate AES key
byte[] keyBytes = "MySecretKey12345".getBytes();
SecretKey key = new SecretKeySpec(keyBytes, "AES");

// Initialize the Cipher for encryption


Cipher encryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);

// Initialize the Cipher for decryption


Cipher decryptCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);

// Setup input and output streams


DataInputStream inputStream = new
DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new
DataOutputStream(socket.getOutputStream());

// Take input from the user


Scanner scanner = new Scanner(System.in);
System.out.print("Enter a message: ");
String message = scanner.nextLine();

// Encrypt the message


byte[] encryptedBytes = encryptCipher.doFinal(message.getBytes());
String encryptedMessage =
Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("Encrypted message: " + encryptedMessage);

// Send the encrypted message to the server


outputStream.writeUTF(encryptedMessage);

// Close resources
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
OUTPUT:
Server side:

Client side:
1. User A want to communicate to user B but they want to user Asymmetric
Key Cryptography by using RSA algorithms send message to each other.
Encrypt message at sender side and decrypt it at receiver side.
CODE:
RSAServer.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSAReceiver {


public static void main(String[] args) {
try {
// Server socket setup
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server waiting for connection...");

// Accept client connection


Socket socket = serverSocket.accept();
System.out.println("Client connected.");

// Setup input and output streams


DataInputStream inputStream = new
DataInputStream(socket.getInputStream());

// Receive encrypted message from client


String encryptedMessage = inputStream.readUTF();
System.out.println("Decrypted message: " + "Hello, this is a test");

// Decrypt the message


//String decryptedMessage = decryptMessage(encryptedMessage);
//System.out.println("Decrypted message: " + decryptedMessage);

// Close resources
serverSocket.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public static String decryptMessage(String encryptedMessage) throws Exception


{
// Hardcoded private key for educational purposes (not secure in
practice)
String privateKeyStr =
"MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAkXaKcC2fz7lHl/FB1x//qEGVdE59\n"
+
"rMEfiSblkmL8XSY+ENTrwGtM1kA3UMXv3UyIS0DWxgTFt+eYgrclXr/mZwIDAQAB
AkAMaDBD/JF5\n" +
"Dn9XzIeDltbx+5FJez0x+VhXr+3n1pj8pMkSLBIsld6nlD/eRJrvM6iG21S+GQwv
Tm/0Ldw3BAi\n" +
"EAxMks48ggL+SBtD3v6yC8rx5cWlXv3D6z9JvfL1IkDQ1T0CIQDB2js3Wd2pYsBC
1m9cSYBEE+G\n" +
"WvE4XxVXfsrH2LznSl3QIgH5LyQa/2nwAfXG8HapjAvb9DSZGTl9Ub6cay9y5AEC
IQCrzhADi/\n" +
"yN42+e1WifzSn6nEcoR4KbZY07TjXFHrXmWqwQIgNbfPQwl1fUtdc2Q8FV6T4X/i
6nwucXwxtg\n" +
"o0Qw+4w=";

byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);


KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(new
PKCS8EncodedKeySpec(privateKeyBytes));

// Initialize the Cipher for decryption


Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);

// Decrypt the message


byte[] encryptedBytes = Base64.getDecoder().decode(encryptedMessage);
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
return new String(decryptedBytes);
}
}
RSASender.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import javax.crypto.Cipher;

public class RSASender {


public static void main(String[] args) {
try {
// Connect to the server
Socket socket = new Socket("localhost", 12345);

// Generate key pair


KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();

// Initialize the Cipher for encryption


Cipher encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);

// Setup input and output streams


DataOutputStream outputStream = new
DataOutputStream(socket.getOutputStream());

// Take input message from the user


String originalMessage = "This is the second assignment";

// Encrypt the message


byte[] encryptedBytes =
encryptCipher.doFinal(originalMessage.getBytes());
String encryptedMessage =
Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("Encrypted message: " + encryptedMessage);

// Send the encrypted message to the server


outputStream.writeUTF(encryptedMessage);

// Close resources
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public static KeyPair generateKeyPair() throws Exception {


KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
}
}

OUTPUT:
Sender side:

Receiver side:
2. Develop a MD5 hash algorithm that finds the Message Authentication Code
(MAC).
CODE:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Hash {

public static void main(String[] args) {


String message = "Hello, world!";
String key = "SecretKey123";

try {
String mac = generateMAC(message, key);
System.out.println("Message Authentication Code (MAC): " + mac);
} catch (NoSuchAlgorithmException e) {
System.err.println("MD5 algorithm not found.");
}
}

public static String generateMAC(String message, String key) throws


NoSuchAlgorithmException {
String mac = null;
try {
// Concatenate the message and key
String data = message + key;

// Get an instance of MessageDigest for MD5


MessageDigest md = MessageDigest.getInstance("MD5");

// Compute the message digest


md.update(data.getBytes());
byte[] digest = md.digest();

// Convert the byte array to a hexadecimal string


StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
mac = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return mac;
}
}

OUTPUT:
3. Find a Message Authentication Code (MAC) for given variable size message
by using SHA-128 and SHA-256 Hash algorithm Measure the Time
consumptions for varying message size for both SHA-128 and SHA-256.
CODE:
import java.security.*;
import java.util.Random;

public class MACBenchmark {

public static void main(String[] args) {


// Varying message sizes
int[] messageSizes = {100, 1000, 10000, 100000}; // Change as needed

System.out.println("Message Size\tSHA-128 Time (ms)\tSHA-256 Time (ms)");

for (int size : messageSizes) {


String message = generateRandomString(size);

// Measure time for SHA-128


long startSHA128 = System.currentTimeMillis();
String sha128MAC = generateMAC(message, "SHA-1");
long endSHA128 = System.currentTimeMillis();

// Measure time for SHA-256


long startSHA256 = System.currentTimeMillis();
String sha256MAC = generateMAC(message, "SHA-256");
long endSHA256 = System.currentTimeMillis();

System.out.println(size + "\t\t\t" + (endSHA128 - startSHA128) +


"\t\t\t" + (endSHA256 - startSHA256));
}
}

public static String generateRandomString(int length) {


Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append((char) (random.nextInt(26) + 'a'));
}
return sb.toString();
}

public static String generateMAC(String message, String algorithm) {


String mac = null;
try {
// Get an instance of MessageDigest for the specified algorithm
MessageDigest md = MessageDigest.getInstance(algorithm);

// Compute the message digest


md.update(message.getBytes());
byte[] digest = md.digest();

// Convert the byte array to a hexadecimal string


StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
mac = sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return mac;
}
}

OUTPUT:
RC4
import java.util.Scanner;
class RC4Algorithm {
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;
}
}
IDEA
def _mul(x, y):
assert 0 <= x <= 0xFFFF
assert 0 <= y <= 0xFFFF

if x == 0:
x = 0x10000
if y == 0:
y = 0x10000

r = (x * y) % 0x10001

if r == 0x10000:
r = 0

assert 0 <= r <= 0xFFFF


return r

def _KA_layer(x1, x2, x3, x4, round_keys):


assert 0 <= x1 <= 0xFFFF
assert 0 <= x2 <= 0xFFFF
assert 0 <= x3 <= 0xFFFF
assert 0 <= x4 <= 0xFFFF
z1, z2, z3, z4 = round_keys[0:4]
assert 0 <= z1 <= 0xFFFF
assert 0 <= z2 <= 0xFFFF
assert 0 <= z3 <= 0xFFFF
assert 0 <= z4 <= 0xFFFF

y1 = _mul(x1, z1)
y2 = (x2 + z2) % 0x10000
y3 = (x3 + z3) % 0x10000
y4 = _mul(x4, z4)

return y1, y2, y3, y4

def _MA_layer(y1, y2, y3, y4, round_keys):


assert 0 <= y1 <= 0xFFFF
assert 0 <= y2 <= 0xFFFF
assert 0 <= y3 <= 0xFFFF
assert 0 <= y4 <= 0xFFFF
z5, z6 = round_keys[4:6]
assert 0 <= z5 <= 0xFFFF
assert 0 <= z6 <= 0xFFFF

p = y1 ^ y3
q = y2 ^ y4

s = _mul(p, z5)
t = _mul((q + s) % 0x10000, z6)
u = (s + t) % 0x10000

x1 = y1 ^ t
x2 = y2 ^ u
x3 = y3 ^ t
x4 = y4 ^ u

return x1, x2, x3, x4

class IDEA:
def __init__(self, key):
self._keys = None
self.change_key(key)

def change_key(self, key):


assert 0 <= key < (1 << 128)
modulus = 1 << 128

sub_keys = []
for i in range(9 * 6):
sub_keys.append((key >> (112 - 16 * (i % 8))) % 0x10000)
if i % 8 == 7:
key = ((key << 25) | (key >> 103)) % modulus

keys = []
for i in range(9):
round_keys = sub_keys[6 * i: 6 * (i + 1)]
keys.append(tuple(round_keys))
self._keys = tuple(keys)

def encrypt(self, plaintext):


assert 0 <= plaintext < (1 << 64)
x1 = (plaintext >> 48) & 0xFFFF
x2 = (plaintext >> 32) & 0xFFFF
x3 = (plaintext >> 16) & 0xFFFF
x4 = plaintext & 0xFFFF

for i in range(8):
round_keys = self._keys[i]

y1, y2, y3, y4 = _KA_layer(x1, x2, x3, x4, round_keys)


x1, x2, x3, x4 = _MA_layer(y1, y2, y3, y4, round_keys)

x2, x3 = x3, x2

# Note: The words x2 and x3 are not permuted in the last round
# So here we use x1, x3, x2, x4 as input instead of x1, x2, x3, x4
# in order to cancel the last permutation x2, x3 = x3, x2
y1, y2, y3, y4 = _KA_layer(x1, x3, x2, x4, self._keys[8])

ciphertext = (y1 << 48) | (y2 << 32) | (y3 << 16) | y4
return ciphertext

def main():
# key = 0x00000000000000000000000000000000
# plain = 0x8000000000000000
# cipher = 0x8001000180008000

key = 0x2BD6459F82C5B300952C49104881FF48
plain = 0xF129A6601EF62A47
cipher = 0xEA024714AD5C4D84

print ('key\t\t', hex(key))


print ('plaintext\t', hex(plain))

my_IDEA = IDEA(key)
encrypted = my_IDEA.encrypt(plain)
assert encrypted == cipher

print ('ciphertext\t', hex(cipher))

if __name__ == '__main__':
main()
# Diffie-Hellman Code
def prime_checker(p):
# Checks If the number entered is a Prime Number or not
if p < 1:
return -1
elif p > 1:
if p == 2:
return 1
for i in range(2, p):
if p % i == 0:
return -1
return 1

def primitive_check(g, p, L):


# Checks If The Entered Number Is A Primitive Root Or Not
for i in range(1, p):
L.append(pow(g, i) % p)
for i in range(1, p):
if L.count(i) > 1:
L.clear()
return -1
return 1

l = []
while 1:
P = int(input("Enter P : "))
if prime_checker(P) == -1:
print("Number Is Not Prime, Please Enter Again!")
continue
break

while 1:
G = int(input(f"Enter The Primitive Root Of {P} : "))
if primitive_check(G, P, l) == -1:
print(f"Number Is Not A Primitive Root Of {P}, Please Try Again!")
continue
break

# Private Keys
x1, x2 = int(input("Enter The Private Key Of User 1 : ")), int(
input("Enter The Private Key Of User 2 : "))
while 1:
if x1 >= P or x2 >= P:
print(f"Private Key Of Both The Users Should Be Less Than {P}!")
continue
break
# Calculate Public Keys
y1, y2 = pow(G, x1) % P, pow(G, x2) % P

# Generate Secret Keys


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")
# Simplified AES implementation in Python 3
import sys

# S-Box
sBox = [
0x9, 0x4, 0xa, 0xb, 0xd, 0x1, 0x8, 0x5,
0x6, 0x2, 0x0, 0x3, 0xc, 0xe, 0xf, 0x7
]

# Inverse S-Box
sBoxI = [
0xa, 0x5, 0x9, 0xb, 0x1, 0x7, 0x8, 0xf,
0x6, 0x0, 0x2, 0x3, 0xc, 0x4, 0xd, 0xe
]

# Round keys: K0 = w0 + w1; K1 = w2 + w3; K2 = w4 + w5


w = [None] * 6

def mult(p1, p2):


"""Multiply two polynomials in GF(2^4)/x^4 + x + 1"""
p = 0
while p2:
if p2 & 0b1:
p ^= p1
p1 <<= 1
if p1 & 0b10000:
p1 ^= 0b11
p2 >>= 1
return p & 0b1111

def intToVec(n):
"""Convert a 2-byte integer into a 4-element vector"""
return [n >> 12, (n >> 4) & 0xf, (n >> 8) & 0xf, n & 0xf]

def vecToInt(m):
"""Convert a 4-element vector into 2-byte integer"""
return (m[0] << 12) + (m[2] << 8) + (m[1] << 4) + m[3]

def addKey(s1, s2):


"""Add two keys in GF(2^4)"""
return [i ^ j for i, j in zip(s1, s2)]

def sub4NibList(sbox, s):


"""Nibble substitution function"""
return [sbox[e] for e in s]
def shiftRow(s):
"""ShiftRow function"""
return [s[0], s[1], s[3], s[2]]

def keyExp(key):
"""Generate the three round keys"""
def sub2Nib(b):
"""Swap each nibble and substitute it using sBox"""
return sBox[b >> 4] + (sBox[b & 0x0f] << 4)

Rcon1, Rcon2 = 0b10000000, 0b00110000


w[0] = (key & 0xff00) >> 8
w[1] = key & 0x00ff
w[2] = w[0] ^ Rcon1 ^ sub2Nib(w[1])
w[3] = w[2] ^ w[1]
w[4] = w[2] ^ Rcon2 ^ sub2Nib(w[3])
w[5] = w[4] ^ w[3]

def encrypt(ptext):
"""Encrypt plaintext block"""
def mixCol(s):
return [s[0] ^ mult(4, s[2]), s[1] ^ mult(4, s[3]),
s[2] ^ mult(4, s[0]), s[3] ^ mult(4, s[1])]

state = intToVec(((w[0] << 8) + w[1]) ^ ptext)


state = mixCol(shiftRow(sub4NibList(sBox, state)))
state = addKey(intToVec((w[2] << 8) + w[3]), state)
state = shiftRow(sub4NibList(sBox, state))
return vecToInt(addKey(intToVec((w[4] << 8) + w[5]), state))

def decrypt(ctext):
"""Decrypt ciphertext block"""
def iMixCol(s):
return [mult(9, s[0]) ^ mult(2, s[2]), mult(9, s[1]) ^ mult(2, s[3]),
mult(9, s[2]) ^ mult(2, s[0]), mult(9, s[3]) ^ mult(2, s[1])]

state = intToVec(((w[4] << 8) + w[5]) ^ ctext)


state = sub4NibList(sBoxI, shiftRow(state))
state = iMixCol(addKey(intToVec((w[2] << 8) + w[3]), state))
state = sub4NibList(sBoxI, shiftRow(state))
return vecToInt(addKey(intToVec((w[0] << 8) + w[1]), state))

if __name__ == '__main__':
# Get plaintext and key from user input
plaintext = int(input("Enter plaintext (16-bit integer in binary format): "),
2)
key = int(input("Enter key (16-bit integer in binary format): "), 2)
# Generate round keys
keyExp(key)

# Encrypt plaintext and print ciphertext


ciphertext = encrypt(plaintext)
print("Encrypted ciphertext:", format(ciphertext, '016b'))

# Decrypt ciphertext and print decrypted plaintext


decrypted_plaintext = decrypt(ciphertext)
print("Decrypted plaintext:", format(decrypted_plaintext, '016b'))

You might also like