Merge remote-tracking branch 'origin/main'
# Conflicts: # IS/Lab/Lab2/des_vs_aes256.py
This commit is contained in:
		
						commit
						4ca2829e4e
					
				
					 13 changed files with 1201 additions and 87 deletions
				
			
		
							
								
								
									
										28
									
								
								ES/Lab/Lab2/array_reversal.asm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ES/Lab/Lab2/array_reversal.asm
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
	AREA RESET, DATA, READONLY
 | 
			
		||||
	EXPORT __Vectors
 | 
			
		||||
__Vectors
 | 
			
		||||
	DCD 0x10001000
 | 
			
		||||
	DCD Reset_Handler
 | 
			
		||||
	ALIGN
 | 
			
		||||
	AREA mycode,CODE,READONLY
 | 
			
		||||
	ENTRY
 | 
			
		||||
	EXPORT Reset_Handler
 | 
			
		||||
	
 | 
			
		||||
Reset_Handler
 | 
			
		||||
	MOV R2, #5
 | 
			
		||||
	LDR R0, =SRC          
 | 
			
		||||
	LDR R1, =SRC + 36
 | 
			
		||||
Loop
 | 
			
		||||
	LDR R3, [R0]
 | 
			
		||||
	LDR R4, [R1]
 | 
			
		||||
	STR R3, [R1], #-4
 | 
			
		||||
	STR R4, [R0], #4
 | 
			
		||||
	SUBS R2, #1
 | 
			
		||||
    
 | 
			
		||||
	BNE Loop             
 | 
			
		||||
 | 
			
		||||
STOP
 | 
			
		||||
	B STOP                
 | 
			
		||||
	AREA mydate, DATA, READWRITE
 | 
			
		||||
SRC DCD 0x00000032, 0x12345644, 0x00000005, 0x00000098, 0x000000AB, 0x000000CD, 0x00000055, 0x00000032, 0x000000CA, 0x00000045
 | 
			
		||||
	END
 | 
			
		||||
							
								
								
									
										34
									
								
								ES/Lab/Lab3/ADDER.asm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ES/Lab/Lab3/ADDER.asm
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
	AREA RESET, DATA, READONLY
 | 
			
		||||
	EXPORT __Vectors
 | 
			
		||||
 | 
			
		||||
__Vectors
 | 
			
		||||
	DCD 0x10001000
 | 
			
		||||
	DCD Reset_Handler
 | 
			
		||||
	ALIGN
 | 
			
		||||
	AREA MYCODE, CODE, READONLY
 | 
			
		||||
	ENTRY
 | 
			
		||||
	EXPORT Reset_Handler
 | 
			
		||||
 | 
			
		||||
Reset_Handler
 | 
			
		||||
	LDR R0, =SRC
 | 
			
		||||
	MOV R3, #10
 | 
			
		||||
	
 | 
			
		||||
UP
 | 
			
		||||
	LDR R1, [R0], #4
 | 
			
		||||
	ADDS R2, R1
 | 
			
		||||
	ADC R5, #0
 | 
			
		||||
	SUBS R3, #1
 | 
			
		||||
	BNE UP;
 | 
			
		||||
	
 | 
			
		||||
	LDR R4, =Result
 | 
			
		||||
	STR R2, [R4]
 | 
			
		||||
	STR R5, [R4]
 | 
			
		||||
	
 | 
			
		||||
SRC DCD 0x12345678, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 0x00000008, 0x00000009
 | 
			
		||||
	
 | 
			
		||||
	AREA mydata, DATA, READWRITE
 | 
			
		||||
	
 | 
			
		||||
Result
 | 
			
		||||
	DCD 0
 | 
			
		||||
	
 | 
			
		||||
	END
 | 
			
		||||
							
								
								
									
										44
									
								
								ES/Lab/Lab3/add128bit.asm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								ES/Lab/Lab3/add128bit.asm
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
	AREA RESET, DATA, READONLY
 | 
			
		||||
	EXPORT __Vectors
 | 
			
		||||
	
 | 
			
		||||
__Vectors
 | 
			
		||||
	DCD 0x10001000
 | 
			
		||||
	DCD Reset_Handler
 | 
			
		||||
	
 | 
			
		||||
	ALIGN
 | 
			
		||||
	
 | 
			
		||||
	AREA MYCODE, CODE, READONLY
 | 
			
		||||
	ENTRY
 | 
			
		||||
	
 | 
			
		||||
	EXPORT Reset_Handler
 | 
			
		||||
 | 
			
		||||
Reset_Handler
 | 
			
		||||
	LDR R1, =N1
 | 
			
		||||
	LDR R2, =N2
 | 
			
		||||
	MOV R3, #4
 | 
			
		||||
	
 | 
			
		||||
UP 
 | 
			
		||||
	LDR R4, [R1], #4
 | 
			
		||||
	LDR R5, [R2], #4
 | 
			
		||||
	ADCS R6, R5, R4
 | 
			
		||||
	SUB R3, #1
 | 
			
		||||
	TEQ R3, #0
 | 
			
		||||
	BNE UP;
 | 
			
		||||
	
 | 
			
		||||
	LDR R8, =Result
 | 
			
		||||
	STR R2, [R8], #4
 | 
			
		||||
	STR R5, [R8]
 | 
			
		||||
 | 
			
		||||
STOP
 | 
			
		||||
	B STOP
 | 
			
		||||
	ALIGN
 | 
			
		||||
	
 | 
			
		||||
N1 DCD 0x10002000, 0x30004000, 0x50006000, 0x70008000
 | 
			
		||||
N2 DCD 0x10002000, 0x30004000, 0x50006000, 0x70008000
 | 
			
		||||
	
 | 
			
		||||
	AREA mydata, DATA, READWRITE
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
Result DCD 0
 | 
			
		||||
 | 
			
		||||
	END
 | 
			
		||||
| 
						 | 
				
			
			@ -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
											
										
									
								
							| 
						 | 
				
			
			@ -1,87 +1,176 @@
 | 
			
		|||
from Crypto.Cipher import DES, AES
 | 
			
		||||
from Crypto.Util.Padding import pad, unpad
 | 
			
		||||
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 ColumnDataSource
 | 
			
		||||
from bokeh.io import output_file
 | 
			
		||||
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 benchmark_encryption_decryption(cipher_func, data, key):
 | 
			
		||||
    # Measure encryption time
 | 
			
		||||
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()
 | 
			
		||||
    encrypted = cipher_func(data, key)
 | 
			
		||||
    encrypt_time = time.time() - start_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)
 | 
			
		||||
 | 
			
		||||
    # Measure decryption time
 | 
			
		||||
    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()
 | 
			
		||||
    decrypted = cipher_func(encrypted, key, decrypt=True)
 | 
			
		||||
    decrypt_time = time.time() - start_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 encrypt_time, decrypt_time
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
def des_cipher(data, key, decrypt=False):
 | 
			
		||||
    cipher = DES.new(key.encode('utf-8'), DES.MODE_ECB)
 | 
			
		||||
    if decrypt:
 | 
			
		||||
        return unpad(cipher.decrypt(data), DES.block_size).decode('utf-8')
 | 
			
		||||
    else:
 | 
			
		||||
        padded_data = pad(data.encode('utf-8'), DES.block_size)
 | 
			
		||||
        return cipher.encrypt(padded_data)
 | 
			
		||||
    # 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)
 | 
			
		||||
 | 
			
		||||
def aes_cipher(data, key, decrypt=False):
 | 
			
		||||
    cipher = AES.new(key.encode('utf-8'), AES.MODE_ECB)
 | 
			
		||||
    if decrypt:
 | 
			
		||||
        return unpad(cipher.decrypt(data), AES.block_size).decode('utf-8')
 | 
			
		||||
    else:
 | 
			
		||||
        padded_data = pad(data.encode('utf-8'), AES.block_size)
 | 
			
		||||
        return cipher.encrypt(padded_data)
 | 
			
		||||
    # 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():
 | 
			
		||||
    message = "Performance Testing of Encryption Algorithms"
 | 
			
		||||
    print("AES-256 vs DES Performance Comparison")
 | 
			
		||||
    print("=====================================")
 | 
			
		||||
 | 
			
		||||
    # Test with different key sizes
 | 
			
		||||
    des_key = "12345678"  # 8 bytes for DES
 | 
			
		||||
    aes_key = "12345678901234567890123456789012"  # 32 bytes for AES-256
 | 
			
		||||
    plaintext = input("Enter plaintext: ")
 | 
			
		||||
    key = input("Enter key: ")
 | 
			
		||||
    max_iterations = int(input("Enter maximum number of iterations (default 1000): ") or "1000")
 | 
			
		||||
 | 
			
		||||
    # Benchmark DES
 | 
			
		||||
    des_encrypt_time, des_decrypt_time = benchmark_encryption_decryption(des_cipher, message, des_key)
 | 
			
		||||
    print(f"\nBenchmarking across iteration ranges up to {max_iterations}...")
 | 
			
		||||
    results = benchmark_ciphers(plaintext, key, max_iterations)
 | 
			
		||||
 | 
			
		||||
    # Benchmark AES-256
 | 
			
		||||
    aes_encrypt_time, aes_decrypt_time = benchmark_encryption_decryption(aes_cipher, message, aes_key)
 | 
			
		||||
    # 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 results
 | 
			
		||||
    print("Performance Results:")
 | 
			
		||||
    print("-" * 40)
 | 
			
		||||
    print(f"DES Encryption: {des_encrypt_time:.9f} seconds")
 | 
			
		||||
    print(f"DES Decryption: {des_decrypt_time:.9f} seconds")
 | 
			
		||||
    print(f"AES-256 Encryption: {aes_encrypt_time:.9f} seconds")
 | 
			
		||||
    print(f"AES-256 Decryption: {aes_decrypt_time:.9f} seconds")
 | 
			
		||||
    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")
 | 
			
		||||
 | 
			
		||||
    # Create Bokeh visualization
 | 
			
		||||
    algorithms = ['DES', 'AES-256']
 | 
			
		||||
    encrypt_times = [des_encrypt_time, aes_encrypt_time]
 | 
			
		||||
    decrypt_times = [des_decrypt_time, aes_decrypt_time]
 | 
			
		||||
 | 
			
		||||
    # Create the plot
 | 
			
		||||
    p = figure(x_range=algorithms, height=400, title="Encryption/Decryption Performance Comparison",
 | 
			
		||||
               toolbar_location=None, responsive=True)
 | 
			
		||||
 | 
			
		||||
    p.vbar(x='algorithm', top='encrypt_time', width=0.4, color='blue', alpha=0.7, legend_label="Encryption",
 | 
			
		||||
           source=ColumnDataSource(data=dict(algorithm=algorithms, encrypt_time=encrypt_times)))
 | 
			
		||||
    p.vbar(x='algorithm', top='decrypt_time', width=0.4, color='red', alpha=0.7, legend_label="Decryption",
 | 
			
		||||
           source=ColumnDataSource(data=dict(algorithm=algorithms, decrypt_time=decrypt_times)))
 | 
			
		||||
 | 
			
		||||
    p.legend.location = "top_right"
 | 
			
		||||
    p.xaxis.axis_label = "Algorithm"
 | 
			
		||||
    p.yaxis.axis_label = "Time (seconds)"
 | 
			
		||||
    p.title.text_font_size = "14px"
 | 
			
		||||
 | 
			
		||||
    # Save and show the plot
 | 
			
		||||
    output_file("encryption_performance.html")
 | 
			
		||||
    show(p)
 | 
			
		||||
    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
											
										
									
								
							
							
								
								
									
										61
									
								
								IS/Lab/Lab2/multiround_aes_192
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								IS/Lab/Lab2/multiround_aes_192
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
from Crypto.Cipher import AES
 | 
			
		||||
from Crypto.Util.Padding import pad, unpad
 | 
			
		||||
 | 
			
		||||
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 aespad_key(key):
 | 
			
		||||
        return key.ljust(24)[:24]
 | 
			
		||||
 | 
			
		||||
def aes_en_trace(ptext, key):
 | 
			
		||||
    key = aespad_key(key)
 | 
			
		||||
    key_bytes = key.encode('utf-8')
 | 
			
		||||
    cipher = AES.new(key_bytes, AES.MODE_ECB)
 | 
			
		||||
    blocks = pad(ptext.encode('utf-8'), AES.block_size)
 | 
			
		||||
 | 
			
		||||
    print("AES-192 (ECB) concise steps:")
 | 
			
		||||
    print("  • Key expansion: Nk=6, Nb=4, Nr=12 → 13 round keys")
 | 
			
		||||
    print("  • Initial round: AddRoundKey")
 | 
			
		||||
    print("  • Main rounds (1..11): SubBytes → ShiftRows → MixColumns → AddRoundKey")
 | 
			
		||||
    print("  • Final round (12): SubBytes → ShiftRows → AddRoundKey\n")
 | 
			
		||||
 | 
			
		||||
    out = bytearray()
 | 
			
		||||
    for i in range(0, len(blocks), 16):
 | 
			
		||||
        block = blocks[i:i+16]
 | 
			
		||||
        print(f"Block {i//16} plaintext: {block.hex()}")
 | 
			
		||||
        print("  Round 0: AddRoundKey")
 | 
			
		||||
        for r in range(1, 12):
 | 
			
		||||
            print(f"  Round {r}: SubBytes → ShiftRows → MixColumns → AddRoundKey")
 | 
			
		||||
        print("  Round 12: SubBytes → ShiftRows → AddRoundKey")
 | 
			
		||||
        cblock = cipher.encrypt(block)
 | 
			
		||||
        print(f"  Ciphertext block: {cblock.hex()}\n")
 | 
			
		||||
        out.extend(cblock)
 | 
			
		||||
    return bytes(out)
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    default_pt = "MIT AES DEMO"        
 | 
			
		||||
    default_key = "MIT-AES-192-DEMO-KEY-24!"  
 | 
			
		||||
 | 
			
		||||
    ptext = input(f"Enter plaintext (blank={default_pt}): ").strip()
 | 
			
		||||
    key = input(f"Enter key (blank={default_key}): ").strip()
 | 
			
		||||
    if not ptext:
 | 
			
		||||
        ptext = default_pt
 | 
			
		||||
    if not key:
 | 
			
		||||
        key = default_key
 | 
			
		||||
 | 
			
		||||
    ctext = aes_en_trace(ptext, key)
 | 
			
		||||
    print("Ciphertext:", ctext.hex())
 | 
			
		||||
    print("Decrypted:", aes_de(ctext, aespad_key(key)))
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										120
									
								
								IS/Lab/Lab3/DiffieHellman.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								IS/Lab/Lab3/DiffieHellman.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
import time
 | 
			
		||||
from dataclasses import dataclass
 | 
			
		||||
 | 
			
		||||
from Crypto.Hash import SHA256
 | 
			
		||||
from Crypto.Protocol.KDF import HKDF
 | 
			
		||||
from Crypto.Util import number
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def rfc3526_group14() -> tuple[int, int]:
 | 
			
		||||
    """
 | 
			
		||||
    Return the 2048-bit MODP Group (Group 14) parameters from RFC 3526.
 | 
			
		||||
 | 
			
		||||
    g = 2
 | 
			
		||||
    p is the safe prime specified in RFC 3526, section 3.
 | 
			
		||||
    """
 | 
			
		||||
    # RFC 3526 Group 14 (2048-bit MODP) prime (hex, concatenated)
 | 
			
		||||
    p_hex = (
 | 
			
		||||
        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
 | 
			
		||||
        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
 | 
			
		||||
        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
 | 
			
		||||
        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
 | 
			
		||||
        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
 | 
			
		||||
        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
 | 
			
		||||
        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
 | 
			
		||||
        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
 | 
			
		||||
        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
 | 
			
		||||
        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
 | 
			
		||||
        "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
 | 
			
		||||
    )
 | 
			
		||||
    p = int(p_hex, 16)
 | 
			
		||||
    g = 2
 | 
			
		||||
    return p, g
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def int_to_fixed_length_bytes(value: int, length_bits: int) -> bytes:
 | 
			
		||||
    length_bytes = (length_bits + 7) // 8
 | 
			
		||||
    return value.to_bytes(length_bytes, byteorder="big")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_keypair(p: int, g: int, private_bits: int = 256) -> tuple[int, int]:
 | 
			
		||||
    """
 | 
			
		||||
    Generate a Diffie-Hellman private/public key pair.
 | 
			
		||||
 | 
			
		||||
    - private_bits controls the size of the secret exponent for performance and security.
 | 
			
		||||
      256 bits is a common choice for Group 14.
 | 
			
		||||
    """
 | 
			
		||||
    a = 0
 | 
			
		||||
    while a < 2:
 | 
			
		||||
        a = number.getRandomNBitInteger(private_bits)
 | 
			
		||||
    A = pow(g, a, p)
 | 
			
		||||
    return a, A
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def derive_shared_key(peer_public: int, private: int, p: int, key_len: int = 32) -> bytes:
 | 
			
		||||
    """
 | 
			
		||||
    Compute the shared secret and derive a symmetric key using HKDF-SHA256.
 | 
			
		||||
    Returns key_len bytes (default 32 bytes = 256-bit key).
 | 
			
		||||
    """
 | 
			
		||||
    shared_secret = pow(peer_public, private, p)
 | 
			
		||||
    # Use fixed-length big-endian encoding of the shared secret for KDF input
 | 
			
		||||
    shared_bytes = int_to_fixed_length_bytes(shared_secret, p.bit_length())
 | 
			
		||||
    key = HKDF(shared_bytes, key_len, salt=None, hashmod=SHA256, context=b"DH key")
 | 
			
		||||
    return key
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
class TimingResult:
 | 
			
		||||
    alice_keygen_s: float
 | 
			
		||||
    bob_keygen_s: float
 | 
			
		||||
    alice_exchange_s: float
 | 
			
		||||
    bob_exchange_s: float
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def measure_timings(p: int, g: int, private_bits: int = 256) -> TimingResult:
 | 
			
		||||
    start = time.perf_counter()
 | 
			
		||||
    a_priv, a_pub = generate_keypair(p, g, private_bits)
 | 
			
		||||
    alice_keygen_s = time.perf_counter() - start
 | 
			
		||||
 | 
			
		||||
    start = time.perf_counter()
 | 
			
		||||
    b_priv, b_pub = generate_keypair(p, g, private_bits)
 | 
			
		||||
    bob_keygen_s = time.perf_counter() - start
 | 
			
		||||
 | 
			
		||||
    # Exchange
 | 
			
		||||
    start = time.perf_counter()
 | 
			
		||||
    a_key = derive_shared_key(b_pub, a_priv, p)
 | 
			
		||||
    alice_exchange_s = time.perf_counter() - start
 | 
			
		||||
 | 
			
		||||
    start = time.perf_counter()
 | 
			
		||||
    b_key = derive_shared_key(a_pub, b_priv, p)
 | 
			
		||||
    bob_exchange_s = time.perf_counter() - start
 | 
			
		||||
 | 
			
		||||
    # Sanity check
 | 
			
		||||
    if a_key != b_key:
 | 
			
		||||
        raise RuntimeError("Derived keys do not match. Check parameters.")
 | 
			
		||||
 | 
			
		||||
    return TimingResult(
 | 
			
		||||
        alice_keygen_s=alice_keygen_s,
 | 
			
		||||
        bob_keygen_s=bob_keygen_s,
 | 
			
		||||
        alice_exchange_s=alice_exchange_s,
 | 
			
		||||
        bob_exchange_s=bob_exchange_s,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    p, g = rfc3526_group14()
 | 
			
		||||
 | 
			
		||||
    timings = measure_timings(p, g, private_bits=256)
 | 
			
		||||
 | 
			
		||||
    print("Diffie-Hellman (RFC3526 Group 14, g=2)")
 | 
			
		||||
    print(f"Prime bits: {p.bit_length()}\n")
 | 
			
		||||
 | 
			
		||||
    print("Timings (seconds):")
 | 
			
		||||
    print(f"- Alice key generation: {timings.alice_keygen_s:.6f}")
 | 
			
		||||
    print(f"- Bob   key generation: {timings.bob_keygen_s:.6f}")
 | 
			
		||||
    print(f"- Alice key exchange:   {timings.alice_exchange_s:.6f}")
 | 
			
		||||
    print(f"- Bob   key exchange:   {timings.bob_exchange_s:.6f}")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										58
									
								
								IS/Lab/Lab3/ECC.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								IS/Lab/Lab3/ECC.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
from Crypto.PublicKey import ECC
 | 
			
		||||
from Crypto.Cipher import AES
 | 
			
		||||
from Crypto.Hash import SHA256
 | 
			
		||||
import binascii
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_keygen(curve: str = 'P-256') -> ECC.EccKey:
 | 
			
		||||
    return ECC.generate(curve=curve)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_encrypt(plaintext: str, recipient_public_key: ECC.EccKey):
 | 
			
		||||
    eph_private = ECC.generate(curve=recipient_public_key.curve)
 | 
			
		||||
    shared_point = recipient_public_key.pointQ * eph_private.d
 | 
			
		||||
    shared_x = int(shared_point.x)
 | 
			
		||||
    aes_key = SHA256.new(shared_x.to_bytes(32, 'big')).digest()
 | 
			
		||||
 | 
			
		||||
    cipher = AES.new(aes_key, AES.MODE_GCM)
 | 
			
		||||
    ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8'))
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        'ephemeral_pub_der': eph_private.public_key().export_key(format='DER'),
 | 
			
		||||
        'nonce': cipher.nonce,
 | 
			
		||||
        'tag': tag,
 | 
			
		||||
        'ciphertext': ciphertext,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_decrypt(enc: dict, recipient_private_key: ECC.EccKey) -> str:
 | 
			
		||||
    eph_public = ECC.import_key(enc['ephemeral_pub_der'])
 | 
			
		||||
    shared_point = eph_public.pointQ * recipient_private_key.d
 | 
			
		||||
    shared_x = int(shared_point.x)
 | 
			
		||||
    aes_key = SHA256.new(shared_x.to_bytes(32, 'big')).digest()
 | 
			
		||||
 | 
			
		||||
    cipher = AES.new(aes_key, AES.MODE_GCM, nonce=enc['nonce'])
 | 
			
		||||
    plaintext = cipher.decrypt_and_verify(enc['ciphertext'], enc['tag'])
 | 
			
		||||
    return plaintext.decode('utf-8')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    print('Welcome to ECC (ECIES-style)')
 | 
			
		||||
    ptext = input('Enter plaintext: ')
 | 
			
		||||
 | 
			
		||||
    priv_key = ecc_keygen()
 | 
			
		||||
    pub_key = priv_key.public_key()
 | 
			
		||||
 | 
			
		||||
    print('\nPublic Key (Qx, Qy):')
 | 
			
		||||
    print('Qx =', hex(int(pub_key.pointQ.x)))
 | 
			
		||||
    print('Qy =', hex(int(pub_key.pointQ.y)))
 | 
			
		||||
 | 
			
		||||
    enc = ecc_encrypt(ptext, pub_key)
 | 
			
		||||
    print("\nYour ciphertext (hex):", binascii.hexlify(enc['ciphertext']).decode())
 | 
			
		||||
 | 
			
		||||
    decrypted = ecc_decrypt(enc, priv_key)
 | 
			
		||||
    print('Your decrypted plaintext:', decrypted)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										57
									
								
								IS/Lab/Lab3/ElGamal.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								IS/Lab/Lab3/ElGamal.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
import random
 | 
			
		||||
from Crypto.Util.number import getPrime
 | 
			
		||||
 | 
			
		||||
def elgamal_keygen(bits=512):
 | 
			
		||||
    p = getPrime(bits)
 | 
			
		||||
    g = random.randint(2, p-1)
 | 
			
		||||
    x = random.randint(1, p-2)  # private key
 | 
			
		||||
    h = pow(g, x, p)  # public key component
 | 
			
		||||
    return (p, g, h), x
 | 
			
		||||
 | 
			
		||||
def elgamal_encrypt(message, pub_key):
 | 
			
		||||
    p, g, h = pub_key
 | 
			
		||||
    m = int.from_bytes(message.encode('utf-8'), 'big')
 | 
			
		||||
    if m >= p:
 | 
			
		||||
        raise ValueError("Message too large for key size")
 | 
			
		||||
    
 | 
			
		||||
    k = random.randint(1, p-2)
 | 
			
		||||
    c1 = pow(g, k, p)
 | 
			
		||||
    c2 = (m * pow(h, k, p)) % p
 | 
			
		||||
    return (c1, c2)
 | 
			
		||||
 | 
			
		||||
def elgamal_decrypt(ciphertext, priv_key, pub_key):
 | 
			
		||||
    c1, c2 = ciphertext
 | 
			
		||||
    p, g, h = pub_key
 | 
			
		||||
    x = priv_key
 | 
			
		||||
    
 | 
			
		||||
    s = pow(c1, x, p)
 | 
			
		||||
    s_inv = pow(s, p-2, p)  # modular inverse
 | 
			
		||||
    m = (c2 * s_inv) % p
 | 
			
		||||
    
 | 
			
		||||
    return m.to_bytes((m.bit_length() + 7) // 8, 'big').decode('utf-8')
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    print("Welcome to ElGamal")
 | 
			
		||||
    ptext = input("Enter plaintext: ")
 | 
			
		||||
    
 | 
			
		||||
    # Generate keys
 | 
			
		||||
    pub_key, priv_key = elgamal_keygen()
 | 
			
		||||
    p, g, h = pub_key
 | 
			
		||||
    
 | 
			
		||||
    print(f"\nPublic Key (p, g, h):")
 | 
			
		||||
    print(f"p = {hex(p)}")
 | 
			
		||||
    print(f"g = {g}")
 | 
			
		||||
    print(f"h = {hex(h)}")
 | 
			
		||||
    
 | 
			
		||||
    # Encrypt
 | 
			
		||||
    ctext = elgamal_encrypt(ptext, pub_key)
 | 
			
		||||
    print(f"\nCiphertext (c1, c2):")
 | 
			
		||||
    print(f"c1 = {hex(ctext[0])}")
 | 
			
		||||
    print(f"c2 = {hex(ctext[1])}")
 | 
			
		||||
    
 | 
			
		||||
    # Decrypt
 | 
			
		||||
    decrypted = elgamal_decrypt(ctext, priv_key, pub_key)
 | 
			
		||||
    print(f"Decrypted: {decrypted}")
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										299
									
								
								IS/Lab/Lab3/FileTransfer.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								IS/Lab/Lab3/FileTransfer.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,299 @@
 | 
			
		|||
import os
 | 
			
		||||
import time
 | 
			
		||||
import binascii
 | 
			
		||||
from Crypto.PublicKey import RSA, ECC
 | 
			
		||||
from Crypto.Cipher import PKCS1_OAEP, AES
 | 
			
		||||
from Crypto.Hash import SHA256
 | 
			
		||||
from Crypto.Util.Padding import pad, unpad
 | 
			
		||||
from Crypto.Random import get_random_bytes
 | 
			
		||||
from bokeh.plotting import figure, show, output_file
 | 
			
		||||
from bokeh.layouts import gridplot
 | 
			
		||||
from bokeh.models import HoverTool
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_test_file(size_mb):
 | 
			
		||||
    """Generate test file of specified size in MB"""
 | 
			
		||||
    filename = f"test_file_{size_mb}MB.txt"
 | 
			
		||||
    with open(filename, 'wb') as f:
 | 
			
		||||
        # Write random data
 | 
			
		||||
        for _ in range(size_mb * 1024):  # 1MB = 1024KB
 | 
			
		||||
            f.write(get_random_bytes(1024))
 | 
			
		||||
    return filename
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def rsa_keygen_timed():
 | 
			
		||||
    """Generate RSA key pair and measure time"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    key = RSA.generate(2048)
 | 
			
		||||
    gen_time = time.time() - start
 | 
			
		||||
    return key, gen_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_keygen_timed():
 | 
			
		||||
    """Generate ECC key pair and measure time"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    key = ECC.generate(curve='secp256r1')
 | 
			
		||||
    gen_time = time.time() - start
 | 
			
		||||
    return key, gen_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def rsa_encrypt_file(filename, pub_key):
 | 
			
		||||
    """Encrypt file using RSA with AES hybrid encryption"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    
 | 
			
		||||
    # Generate AES key
 | 
			
		||||
    aes_key = get_random_bytes(32)  # 256-bit AES key
 | 
			
		||||
    
 | 
			
		||||
    # Encrypt AES key with RSA
 | 
			
		||||
    rsa_cipher = PKCS1_OAEP.new(pub_key)
 | 
			
		||||
    encrypted_aes_key = rsa_cipher.encrypt(aes_key)
 | 
			
		||||
    
 | 
			
		||||
    # Encrypt file with AES
 | 
			
		||||
    aes_cipher = AES.new(aes_key, AES.MODE_CBC)
 | 
			
		||||
    iv = aes_cipher.iv
 | 
			
		||||
    
 | 
			
		||||
    with open(filename, 'rb') as f:
 | 
			
		||||
        plaintext = f.read()
 | 
			
		||||
    
 | 
			
		||||
    padded_plaintext = pad(plaintext, AES.block_size)
 | 
			
		||||
    ciphertext = aes_cipher.encrypt(padded_plaintext)
 | 
			
		||||
    
 | 
			
		||||
    enc_time = time.time() - start
 | 
			
		||||
    
 | 
			
		||||
    encrypted_data = {
 | 
			
		||||
        'encrypted_aes_key': encrypted_aes_key,
 | 
			
		||||
        'iv': iv,
 | 
			
		||||
        'ciphertext': ciphertext
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return encrypted_data, enc_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def rsa_decrypt_file(encrypted_data, priv_key):
 | 
			
		||||
    """Decrypt file using RSA with AES hybrid decryption"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    
 | 
			
		||||
    # Decrypt AES key with RSA
 | 
			
		||||
    rsa_cipher = PKCS1_OAEP.new(priv_key)
 | 
			
		||||
    aes_key = rsa_cipher.decrypt(encrypted_data['encrypted_aes_key'])
 | 
			
		||||
    
 | 
			
		||||
    # Decrypt file with AES
 | 
			
		||||
    aes_cipher = AES.new(aes_key, AES.MODE_CBC, encrypted_data['iv'])
 | 
			
		||||
    padded_plaintext = aes_cipher.decrypt(encrypted_data['ciphertext'])
 | 
			
		||||
    plaintext = unpad(padded_plaintext, AES.block_size)
 | 
			
		||||
    
 | 
			
		||||
    dec_time = time.time() - start
 | 
			
		||||
    return plaintext, dec_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_encrypt_file(filename, pub_key):
 | 
			
		||||
    """Encrypt file using ECC with AES hybrid encryption"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    
 | 
			
		||||
    # Generate ephemeral key pair
 | 
			
		||||
    eph_private = ECC.generate(curve='secp256r1')
 | 
			
		||||
    
 | 
			
		||||
    # Compute shared secret
 | 
			
		||||
    shared_point = pub_key.pointQ * eph_private.d
 | 
			
		||||
    shared_x = int(shared_point.x)
 | 
			
		||||
    aes_key = SHA256.new(shared_x.to_bytes(32, 'big')).digest()
 | 
			
		||||
    
 | 
			
		||||
    # Encrypt file with AES
 | 
			
		||||
    aes_cipher = AES.new(aes_key, AES.MODE_GCM)
 | 
			
		||||
    
 | 
			
		||||
    with open(filename, 'rb') as f:
 | 
			
		||||
        plaintext = f.read()
 | 
			
		||||
    
 | 
			
		||||
    ciphertext, tag = aes_cipher.encrypt_and_digest(plaintext)
 | 
			
		||||
    
 | 
			
		||||
    enc_time = time.time() - start
 | 
			
		||||
    
 | 
			
		||||
    encrypted_data = {
 | 
			
		||||
        'ephemeral_pub_der': eph_private.public_key().export_key(format='DER'),
 | 
			
		||||
        'nonce': aes_cipher.nonce,
 | 
			
		||||
        'tag': tag,
 | 
			
		||||
        'ciphertext': ciphertext
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return encrypted_data, enc_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ecc_decrypt_file(encrypted_data, priv_key):
 | 
			
		||||
    """Decrypt file using ECC with AES hybrid decryption"""
 | 
			
		||||
    start = time.time()
 | 
			
		||||
    
 | 
			
		||||
    # Import ephemeral public key
 | 
			
		||||
    eph_public = ECC.import_key(encrypted_data['ephemeral_pub_der'])
 | 
			
		||||
    
 | 
			
		||||
    # Compute shared secret
 | 
			
		||||
    shared_point = eph_public.pointQ * priv_key.d
 | 
			
		||||
    shared_x = int(shared_point.x)
 | 
			
		||||
    aes_key = SHA256.new(shared_x.to_bytes(32, 'big')).digest()
 | 
			
		||||
    
 | 
			
		||||
    # Decrypt file with AES
 | 
			
		||||
    aes_cipher = AES.new(aes_key, AES.MODE_GCM, nonce=encrypted_data['nonce'])
 | 
			
		||||
    plaintext = aes_cipher.decrypt_and_verify(encrypted_data['ciphertext'], encrypted_data['tag'])
 | 
			
		||||
    
 | 
			
		||||
    dec_time = time.time() - start
 | 
			
		||||
    return plaintext, dec_time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def measure_performance(file_sizes):
 | 
			
		||||
    """Measure performance for both RSA and ECC"""
 | 
			
		||||
    results = {
 | 
			
		||||
        'file_sizes': file_sizes,
 | 
			
		||||
        'rsa_keygen': [],
 | 
			
		||||
        'ecc_keygen': [],
 | 
			
		||||
        'rsa_encrypt': [],
 | 
			
		||||
        'rsa_decrypt': [],
 | 
			
		||||
        'ecc_encrypt': [],
 | 
			
		||||
        'ecc_decrypt': [],
 | 
			
		||||
        'rsa_key_size': 0,
 | 
			
		||||
        'ecc_key_size': 0
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    print("Performance Testing - RSA vs ECC File Transfer")
 | 
			
		||||
    print("=" * 50)
 | 
			
		||||
    
 | 
			
		||||
    # Generate keys once
 | 
			
		||||
    rsa_key, rsa_keygen_time = rsa_keygen_timed()
 | 
			
		||||
    ecc_key, ecc_keygen_time = ecc_keygen_timed()
 | 
			
		||||
    
 | 
			
		||||
    # Calculate key sizes
 | 
			
		||||
    results['rsa_key_size'] = len(rsa_key.export_key('DER'))
 | 
			
		||||
    results['ecc_key_size'] = len(ecc_key.export_key(format='DER'))
 | 
			
		||||
    
 | 
			
		||||
    print(f"RSA Key Generation Time: {rsa_keygen_time:.4f} seconds")
 | 
			
		||||
    print(f"ECC Key Generation Time: {ecc_keygen_time:.4f} seconds")
 | 
			
		||||
    print(f"RSA Key Size: {results['rsa_key_size']} bytes")
 | 
			
		||||
    print(f"ECC Key Size: {results['ecc_key_size']} bytes")
 | 
			
		||||
    print()
 | 
			
		||||
    
 | 
			
		||||
    for size in file_sizes:
 | 
			
		||||
        print(f"Testing {size}MB file...")
 | 
			
		||||
        
 | 
			
		||||
        # Generate test file
 | 
			
		||||
        filename = generate_test_file(size)
 | 
			
		||||
        
 | 
			
		||||
        try:
 | 
			
		||||
            # RSA performance
 | 
			
		||||
            rsa_pub = rsa_key.publickey()
 | 
			
		||||
            encrypted_rsa, rsa_enc_time = rsa_encrypt_file(filename, rsa_pub)
 | 
			
		||||
            decrypted_rsa, rsa_dec_time = rsa_decrypt_file(encrypted_rsa, rsa_key)
 | 
			
		||||
            
 | 
			
		||||
            # ECC performance
 | 
			
		||||
            ecc_pub = ecc_key.public_key()
 | 
			
		||||
            encrypted_ecc, ecc_enc_time = ecc_encrypt_file(filename, ecc_pub)
 | 
			
		||||
            decrypted_ecc, ecc_dec_time = ecc_decrypt_file(encrypted_ecc, ecc_key)
 | 
			
		||||
            
 | 
			
		||||
            # Store results
 | 
			
		||||
            results['rsa_keygen'].append(rsa_keygen_time)
 | 
			
		||||
            results['ecc_keygen'].append(ecc_keygen_time)
 | 
			
		||||
            results['rsa_encrypt'].append(rsa_enc_time)
 | 
			
		||||
            results['rsa_decrypt'].append(rsa_dec_time)
 | 
			
		||||
            results['ecc_encrypt'].append(ecc_enc_time)
 | 
			
		||||
            results['ecc_decrypt'].append(ecc_dec_time)
 | 
			
		||||
            
 | 
			
		||||
            print(f"  RSA - Encrypt: {rsa_enc_time:.4f}s, Decrypt: {rsa_dec_time:.4f}s")
 | 
			
		||||
            print(f"  ECC - Encrypt: {ecc_enc_time:.4f}s, Decrypt: {ecc_dec_time:.4f}s")
 | 
			
		||||
            
 | 
			
		||||
        finally:
 | 
			
		||||
            # Clean up test file
 | 
			
		||||
            if os.path.exists(filename):
 | 
			
		||||
                os.remove(filename)
 | 
			
		||||
        
 | 
			
		||||
        print()
 | 
			
		||||
    
 | 
			
		||||
    return results
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_performance_graphs(results):
 | 
			
		||||
    """Create performance comparison graphs using Bokeh"""
 | 
			
		||||
    output_file("file_transfer_performance.html")
 | 
			
		||||
    
 | 
			
		||||
    file_sizes = results['file_sizes']
 | 
			
		||||
    
 | 
			
		||||
    # Encryption time comparison
 | 
			
		||||
    p1 = figure(title="Encryption Time Comparison", x_axis_label="File Size (MB)", 
 | 
			
		||||
                y_axis_label="Time (seconds)", width=400, height=300)
 | 
			
		||||
    p1.line(file_sizes, results['rsa_encrypt'], legend_label="RSA", line_color="red", line_width=2)
 | 
			
		||||
    p1.circle(file_sizes, results['rsa_encrypt'], color="red", size=6)
 | 
			
		||||
    p1.line(file_sizes, results['ecc_encrypt'], legend_label="ECC", line_color="blue", line_width=2)
 | 
			
		||||
    p1.circle(file_sizes, results['ecc_encrypt'], color="blue", size=6)
 | 
			
		||||
    p1.legend.location = "top_left"
 | 
			
		||||
    
 | 
			
		||||
    # Decryption time comparison
 | 
			
		||||
    p2 = figure(title="Decryption Time Comparison", x_axis_label="File Size (MB)", 
 | 
			
		||||
                y_axis_label="Time (seconds)", width=400, height=300)
 | 
			
		||||
    p2.line(file_sizes, results['rsa_decrypt'], legend_label="RSA", line_color="red", line_width=2)
 | 
			
		||||
    p2.circle(file_sizes, results['rsa_decrypt'], color="red", size=6)
 | 
			
		||||
    p2.line(file_sizes, results['ecc_decrypt'], legend_label="ECC", line_color="blue", line_width=2)
 | 
			
		||||
    p2.circle(file_sizes, results['ecc_decrypt'], color="blue", size=6)
 | 
			
		||||
    p2.legend.location = "top_left"
 | 
			
		||||
    
 | 
			
		||||
    # Key generation comparison
 | 
			
		||||
    p3 = figure(title="Key Generation Time", x_axis_label="Algorithm", 
 | 
			
		||||
                y_axis_label="Time (seconds)", width=400, height=300,
 | 
			
		||||
                x_range=["RSA", "ECC"])
 | 
			
		||||
    p3.vbar(x=["RSA", "ECC"], top=[results['rsa_keygen'][0], results['ecc_keygen'][0]], 
 | 
			
		||||
            width=0.5, color=["red", "blue"])
 | 
			
		||||
    
 | 
			
		||||
    # Key size comparison
 | 
			
		||||
    p4 = figure(title="Key Size Comparison", x_axis_label="Algorithm", 
 | 
			
		||||
                y_axis_label="Size (bytes)", width=400, height=300,
 | 
			
		||||
                x_range=["RSA", "ECC"])
 | 
			
		||||
    p4.vbar(x=["RSA", "ECC"], top=[results['rsa_key_size'], results['ecc_key_size']], 
 | 
			
		||||
            width=0.5, color=["red", "blue"])
 | 
			
		||||
    
 | 
			
		||||
    # Create grid layout
 | 
			
		||||
    grid = gridplot([[p1, p2], [p3, p4]])
 | 
			
		||||
    show(grid)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_security_analysis():
 | 
			
		||||
    """Print security analysis and comparison"""
 | 
			
		||||
    print("\nSecurity Analysis - RSA vs ECC")
 | 
			
		||||
    print("=" * 50)
 | 
			
		||||
    print("RSA (2048-bit):")
 | 
			
		||||
    print("  • Security Level: ~112 bits")
 | 
			
		||||
    print("  • Key Size: Large (2048+ bits)")
 | 
			
		||||
    print("  • Resistance: Integer factorization problem")
 | 
			
		||||
    print("  • Quantum Threat: Vulnerable to Shor's algorithm")
 | 
			
		||||
    print("  • Computational Overhead: High for large keys")
 | 
			
		||||
    print()
 | 
			
		||||
    print("ECC (secp256r1):")
 | 
			
		||||
    print("  • Security Level: ~128 bits")
 | 
			
		||||
    print("  • Key Size: Small (256 bits)")
 | 
			
		||||
    print("  • Resistance: Elliptic curve discrete logarithm problem")
 | 
			
		||||
    print("  • Quantum Threat: Vulnerable to modified Shor's algorithm")
 | 
			
		||||
    print("  • Computational Overhead: Lower than equivalent RSA")
 | 
			
		||||
    print()
 | 
			
		||||
    print("Summary:")
 | 
			
		||||
    print("  • ECC provides equivalent security with smaller keys")
 | 
			
		||||
    print("  • ECC is more efficient for mobile/embedded systems")
 | 
			
		||||
    print("  • RSA is more widely supported and established")
 | 
			
		||||
    print("  • Both require post-quantum alternatives for future security")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    """Main function to run the file transfer comparison"""
 | 
			
		||||
    file_sizes = [1, 5, 10]  # MB
 | 
			
		||||
    
 | 
			
		||||
    print("Secure File Transfer System - RSA vs ECC Comparison")
 | 
			
		||||
    print("=" * 60)
 | 
			
		||||
    
 | 
			
		||||
    # Measure performance
 | 
			
		||||
    results = measure_performance(file_sizes)
 | 
			
		||||
    
 | 
			
		||||
    # Create performance graphs
 | 
			
		||||
    create_performance_graphs(results)
 | 
			
		||||
    
 | 
			
		||||
    # Print security analysis
 | 
			
		||||
    print_security_analysis()
 | 
			
		||||
    
 | 
			
		||||
    print(f"\nPerformance graphs saved to: file_transfer_performance.html")
 | 
			
		||||
    print("Open the HTML file in your browser to view the interactive graphs.")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										39
									
								
								IS/Lab/Lab3/RSA.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								IS/Lab/Lab3/RSA.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
from Crypto.PublicKey import RSA
 | 
			
		||||
from Crypto.Cipher import PKCS1_OAEP
 | 
			
		||||
import binascii
 | 
			
		||||
 | 
			
		||||
def rsa_keygen(bits=2048):
 | 
			
		||||
    key = RSA.generate(bits)
 | 
			
		||||
    return key
 | 
			
		||||
 | 
			
		||||
def rsa_en(ptext, pub_key):
 | 
			
		||||
    cipher = PKCS1_OAEP.new(pub_key)
 | 
			
		||||
    ctext = cipher.encrypt(ptext.encode('utf-8'))
 | 
			
		||||
    return ctext
 | 
			
		||||
 | 
			
		||||
def rsa_de(ctext, priv_key):
 | 
			
		||||
    cipher = PKCS1_OAEP.new(priv_key)
 | 
			
		||||
    decrypted = cipher.decrypt(ctext)
 | 
			
		||||
    return decrypted.decode('utf-8')
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    print("Welcome to RSA")
 | 
			
		||||
    ptext = input("Enter plaintext: ")
 | 
			
		||||
 | 
			
		||||
    # RSA key pair
 | 
			
		||||
    key = rsa_keygen()
 | 
			
		||||
    pub_key = key.publickey()
 | 
			
		||||
    priv_key = key
 | 
			
		||||
 | 
			
		||||
    print("\nPublic Key (n, e):")
 | 
			
		||||
    print("n =", hex(pub_key.n))
 | 
			
		||||
    print("e =", pub_key.e)
 | 
			
		||||
 | 
			
		||||
    ctext = rsa_en(ptext, pub_key)
 | 
			
		||||
    print("\nYour ciphertext (hex):", binascii.hexlify(ctext).decode())
 | 
			
		||||
 | 
			
		||||
    decrypted = rsa_de(ctext, priv_key)
 | 
			
		||||
    print("Your decrypted plaintext:", decrypted)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main()
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue