Modified Lab 2 IS

This commit is contained in:
sherlock 2025-08-06 00:19:31 +05:30
parent a1b2495e47
commit 47d2a871e9
4 changed files with 482 additions and 21 deletions

View file

@ -1,33 +1,196 @@
from crypto.Cipher import DES3
from Crypto.Cipher import DES, DES3, AES
from Crypto.Util.Padding import pad, unpad
import time
from bokeh.plotting import figure, show, output_file
from bokeh.models import HoverTool, ColumnDataSource
from bokeh.layouts import column, row
import bokeh.palettes as bp
def des_pad(text):
n = len(text) % 8
return text + (b' ' * n)
def pad_key(key, length):
return key.ljust(length)[:length].encode('utf-8')
def des_128(ptext, key):
cipher=DES.new(key, DES.MODE_ECB)
def encrypt_with_timing(cipher_func, ptext, key, *args):
# Use more precise timing for microsecond measurements
start_time = time.perf_counter()
result = cipher_func(ptext, key, *args)
end_time = time.perf_counter()
return result, end_time - start_time
def des_encrypt(ptext, key, mode):
key = pad_key(key, 8)
cipher = DES.new(key, mode)
padded_text = pad(ptext.encode('utf-8'), DES.block_size)
return cipher.encrypt(padded_text)
def des_192(ptext, key):
def des3_encrypt(ptext, key, key_size, mode):
if key_size == 128:
key = pad_key(key, 16)
elif key_size == 192:
key = pad_key(key, 24)
else: # 256 bit uses 192 bit key (DES3 limitation)
key = pad_key(key, 24)
def des_256(ptext, key):
cipher = DES3.new(key, mode)
padded_text = pad(ptext.encode('utf-8'), DES3.block_size)
return cipher.encrypt(padded_text)
def aes_128(ptext, key):
def aes_192(ptext, key):
def aes_256(ptext, key):
def aes_encrypt(ptext, key, key_size, mode):
if key_size == 128:
key = pad_key(key, 16)
elif key_size == 192:
key = pad_key(key, 24)
else: # 256
key = pad_key(key, 32)
def bokeh_graph():
cipher = AES.new(key, mode)
padded_text = pad(ptext.encode('utf-8'), AES.block_size)
return cipher.encrypt(padded_text)
def des_128(ptext, key, mode=DES.MODE_ECB):
return des_encrypt(ptext, key, mode)
def des_192(ptext, key, mode=DES3.MODE_ECB):
return des3_encrypt(ptext, key, 192, mode)
def des_256(ptext, key, mode=DES3.MODE_ECB):
return des3_encrypt(ptext, key, 256, mode)
def aes_128(ptext, key, mode=AES.MODE_ECB):
return aes_encrypt(ptext, key, 128, mode)
def aes_192(ptext, key, mode=AES.MODE_ECB):
return aes_encrypt(ptext, key, 192, mode)
def aes_256(ptext, key, mode=AES.MODE_ECB):
return aes_encrypt(ptext, key, 256, mode)
def bokeh_graph(timing_data):
output_file("encryption_performance.html")
from bokeh.models import LinearColorMapper, ColorBar, BasicTicker, PrintfTickFormatter
from bokeh.transform import transform
import math
algorithms = list(timing_data.keys())
messages = [f"Msg {i+1}" for i in range(len(next(iter(timing_data.values()))))]
# Convert all times to microseconds for better visibility
def to_microseconds(seconds):
return seconds * 1_000_000
# Chart 2: Performance variability - Box plot style using circles and lines
p2 = figure(x_range=algorithms, title="Performance Distribution Across Messages",
toolbar_location=None, tools="", width=800, height=400)
for i, algo_name in enumerate(algorithms):
times_us = [to_microseconds(t) for t in timing_data[algo_name]]
# Calculate statistics
mean_time = sum(times_us) / len(times_us)
min_time = min(times_us)
max_time = max(times_us)
# Plot range line
p2.line([i, i], [min_time, max_time], line_width=2, color=colors[i], alpha=0.6)
# Plot individual points
y_positions = times_us
x_positions = [i + (j - 2) * 0.1 for j in range(len(times_us))] # Spread points horizontally
p2.circle(x_positions, y_positions, size=8, color=colors[i], alpha=0.8)
# Plot mean as a diamond
p2.diamond([i], [mean_time], size=12, color=colors[i], line_color="black", line_width=1)
p2.xaxis.major_label_orientation = 45
p2.yaxis.axis_label = "Execution Time (microseconds)"
p2.xaxis.axis_label = "Encryption Algorithm"
p2.xaxis.ticker = BasicTicker()
p2.xaxis.formatter = PrintfTickFormatter(format="%s")
hover2 = HoverTool(tooltips=[("Time (μs)", "@y{0.00}")], mode='vline')
p2.add_tools(hover2)
# Chart 4: Relative performance comparison (normalized to fastest)
p4 = figure(x_range=algorithms, title="Relative Performance (Normalized to Fastest Algorithm)",
toolbar_location=None, tools="", width=800, height=400)
# Find the fastest average time
fastest_avg = min(avg_times)
relative_times = [avg / fastest_avg for avg in avg_times]
bars4 = p4.vbar(x=algorithms, top=relative_times, width=0.6, color=colors, alpha=0.8)
# Add reference line at 1.0
p4.line([-0.5, len(algorithms)-0.5], [1, 1], line_dash="dashed", line_width=2, color="red", alpha=0.7)
p4.xaxis.major_label_orientation = 45
p4.yaxis.axis_label = "Relative Performance (1.0 = fastest)"
p4.xaxis.axis_label = "Encryption Algorithm"
hover4 = HoverTool(tooltips=[("Algorithm", "@x"), ("Relative Speed", "@top{0.00}x")], renderers=[bars4])
p4.add_tools(hover4)
# Layout all charts
layout = column(
row(p2),
row(p4)
)
show(layout)
def main():
print("The AES/DES Encryptor")
ptext = input("Enter plaintext: ")
key = b'input("Enter key: ")'
print("DES 128 Bit Cyphertext: ", des_128(ptext, key))
print("DES 192 Bit Cyphertext: ", des_192(ptext, key))
print("DES 256 Bit Cyphertext: ", des_256(ptext, key))
print("AES 128 Bit Cyphertext: ", aes_128(ptext, key))
print("AES 192 Bit Cyphertext: ", aes_192(ptext, key))
print("AES 256 Bit Cyphertext: ", aes_256(ptext, key))
print("The AES/DES Encryptor with Performance Analysis")
# Get exactly 5 messages from user
messages = []
print("\nEnter exactly 5 messages to encrypt:")
for i in range(5):
while True:
message = input(f"Message {i+1}: ")
if message.strip(): # Only accept non-empty messages
messages.append(message)
break
else:
print("Please enter a non-empty message.")
key = input("\nEnter key: ")
# Define algorithms to test (using ECB mode only)
algorithms = [
('DES', des_128, DES.MODE_ECB),
('DES3-192', des_192, DES3.MODE_ECB),
('AES-128', aes_128, AES.MODE_ECB),
('AES-192', aes_192, AES.MODE_ECB),
('AES-256', aes_256, AES.MODE_ECB)
]
timing_data = {}
print("\nEncrypting messages and measuring performance...\n")
# Run each message through each algorithm multiple times for better precision
for algo_name, algo_func, mode in algorithms:
timing_data[algo_name] = []
print(f"=== {algo_name} ===")
for i, message in enumerate(messages):
print(f"Message {i+1}: {message[:30]}...")
# Run multiple times and take the best time to reduce noise
best_time = float('inf')
for _ in range(10): # 10 runs for better precision
ctext, exec_time = encrypt_with_timing(algo_func, message, key, mode)
best_time = min(best_time, exec_time)
print(f"{algo_name}: {best_time:.8f}s ({best_time*1000000:.2f}μs)")
timing_data[algo_name].append(best_time)
print()
# Generate performance graphs
print("Generating performance visualization...")
bokeh_graph(timing_data)
print("Performance graphs saved to 'encryption_performance.html'")
if __name__ == '__main__':
main()

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,176 @@
import time
import numpy as np
from Crypto.Cipher import AES, DES
from Crypto.Util.Padding import pad, unpad
from bokeh.plotting import figure, show
from bokeh.models import HoverTool
from bokeh.layouts import column
from bokeh.palettes import Category10
def aes_cipher(key):
return AES.new(key.encode('utf-8'), AES.MODE_ECB)
def aes_en(ptext, key):
cipher = aes_cipher(key)
ptext = pad(ptext.encode('utf-8'), AES.block_size)
return cipher.encrypt(ptext)
def aes_de(ctext, key):
cipher = aes_cipher(key)
decrypted = cipher.decrypt(ctext)
return unpad(decrypted, AES.block_size).decode('utf-8')
def aes256_pad_key(key):
return key.ljust(32)[:32]
def des_cipher(key):
return DES.new(key.encode('utf-8'), DES.MODE_ECB)
def des_en(ptext, key):
cipher = des_cipher(key)
ptext = pad(ptext.encode('utf-8'), DES.block_size)
return cipher.encrypt(ptext)
def des_de(ctext, key):
cipher = des_cipher(key)
decrypted = cipher.decrypt(ctext)
return unpad(decrypted, DES.block_size).decode('utf-8')
def des_pad_key(key):
return key.ljust(8)[:8]
def time_encryption_progressive(encrypt_func, plaintext, key, max_iterations=1000):
"""Time encryption across different iteration counts"""
iteration_counts = np.logspace(1, np.log10(max_iterations), 10, dtype=int)
times_per_iteration = []
for iterations in iteration_counts:
start_time = time.time()
for _ in range(iterations):
encrypt_func(plaintext, key)
end_time = time.time()
total_time = end_time - start_time
times_per_iteration.append(total_time / iterations)
return iteration_counts, times_per_iteration
def time_decryption_progressive(decrypt_func, ciphertext, key, max_iterations=1000):
"""Time decryption across different iteration counts"""
iteration_counts = np.logspace(1, np.log10(max_iterations), 10, dtype=int)
times_per_iteration = []
for iterations in iteration_counts:
start_time = time.time()
for _ in range(iterations):
decrypt_func(ciphertext, key)
end_time = time.time()
total_time = end_time - start_time
times_per_iteration.append(total_time / iterations)
return iteration_counts, times_per_iteration
def benchmark_ciphers(plaintext, raw_key, max_iterations=1000):
# Prepare keys
aes_key = aes256_pad_key(raw_key)
des_key = des_pad_key(raw_key)
# Get ciphertexts for decryption timing
aes_ciphertext = aes_en(plaintext, aes_key)
des_ciphertext = des_en(plaintext, des_key)
# Time encryption progressively
aes_enc_iterations, aes_enc_times = time_encryption_progressive(aes_en, plaintext, aes_key, max_iterations)
des_enc_iterations, des_enc_times = time_encryption_progressive(des_en, plaintext, des_key, max_iterations)
# Time decryption progressively
aes_dec_iterations, aes_dec_times = time_decryption_progressive(aes_de, aes_ciphertext, aes_key, max_iterations)
des_dec_iterations, des_dec_times = time_decryption_progressive(des_de, des_ciphertext, des_key, max_iterations)
return {
'aes_enc_iterations': aes_enc_iterations,
'aes_enc_times': aes_enc_times,
'des_enc_iterations': des_enc_iterations,
'des_enc_times': des_enc_times,
'aes_dec_iterations': aes_dec_iterations,
'aes_dec_times': aes_dec_times,
'des_dec_iterations': des_dec_iterations,
'des_dec_times': des_dec_times
}
def create_plot(title, plaintext_length):
return figure(
title=f"{title}\nPlaintext length: {plaintext_length} chars",
x_axis_label="Number of Iterations",
y_axis_label="Time per Operation (seconds)",
x_axis_type="log",
y_axis_type="log",
width=800,
height=400,
background_fill_color="#fafafa",
border_fill_color="whitesmoke"
)
def add_line_and_markers(plot, x_data, y_data, color, label):
plot.line(x_data, y_data, line_width=3, color=color, alpha=0.8, legend_label=label)
plot.scatter(x_data, y_data, size=8, color=color, alpha=0.8)
def plot_results(results, plaintext_length):
colors = Category10[4]
# Create plots
p1 = create_plot("Encryption Performance: Time per Operation", plaintext_length)
p2 = create_plot("Decryption Performance: Time per Operation", plaintext_length)
# Add data to plots
add_line_and_markers(p1, results['aes_enc_iterations'], results['aes_enc_times'], colors[0], "AES-256 Encryption")
add_line_and_markers(p1, results['des_enc_iterations'], results['des_enc_times'], colors[1], "DES Encryption")
add_line_and_markers(p2, results['aes_dec_iterations'], results['aes_dec_times'], colors[2], "AES-256 Decryption")
add_line_and_markers(p2, results['des_dec_iterations'], results['des_dec_times'], colors[3], "DES Decryption")
# Add hover tools and styling
hover = HoverTool(tooltips=[("Algorithm", "@legend_label"), ("Iterations", "@x"), ("Time per Op", "@y{0.0000000} sec")])
for p in [p1, p2]:
p.add_tools(hover)
p.legend.location = "top_right"
p.legend.click_policy = "hide"
p.legend.background_fill_alpha = 0.8
p.grid.grid_line_alpha = 0.3
show(column(p1, p2))
def main():
print("AES-256 vs DES Performance Comparison")
print("=====================================")
plaintext = input("Enter plaintext: ")
key = input("Enter key: ")
max_iterations = int(input("Enter maximum number of iterations (default 1000): ") or "1000")
print(f"\nBenchmarking across iteration ranges up to {max_iterations}...")
results = benchmark_ciphers(plaintext, key, max_iterations)
# Calculate average times for comparison
avg_aes_enc = np.mean(results['aes_enc_times'])
avg_des_enc = np.mean(results['des_enc_times'])
avg_aes_dec = np.mean(results['aes_dec_times'])
avg_des_dec = np.mean(results['des_dec_times'])
print("\nAverage Results (time per operation):")
print(f"AES-256 Encryption: {avg_aes_enc:.8f} seconds")
print(f"DES Encryption: {avg_des_enc:.8f} seconds")
print(f"AES-256 Decryption: {avg_aes_dec:.8f} seconds")
print(f"DES Decryption: {avg_des_dec:.8f} seconds")
print("\nSpeed comparison:")
if avg_aes_enc < avg_des_enc:
ratio = avg_des_enc / avg_aes_enc
print(f"AES-256 encryption is {ratio:.2f}x faster than DES")
else:
ratio = avg_aes_enc / avg_des_enc
print(f"DES encryption is {ratio:.2f}x faster than AES-256")
plot_results(results, len(plaintext))
if __name__ == '__main__':
main()

File diff suppressed because one or more lines are too long