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()