Modified Lab 2 IS
This commit is contained in:
		
							parent
							
								
									a1b2495e47
								
							
						
					
					
						commit
						47d2a871e9
					
				
					 4 changed files with 482 additions and 21 deletions
				
			
		|  | @ -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() | ||||
|  |  | |||
							
								
								
									
										61
									
								
								IS/Lab/Lab2/des_vs_aes256.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								IS/Lab/Lab2/des_vs_aes256.html
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -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() | ||||
							
								
								
									
										61
									
								
								IS/Lab/Lab2/encryption_performance.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								IS/Lab/Lab2/encryption_performance.html
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue