-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
550 lines (458 loc) · 21.8 KB
/
main.py
File metadata and controls
550 lines (458 loc) · 21.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
from tkinter import Tk, Label, Button, Entry, Text, messagebox, filedialog, END, Toplevel
import os
import sys
import random
import time
class Encryption:
def __init__(self, data):
self.data = data
self._ciphertext = ""
def flatten_matrix(self, matrix):
# Flattening the matrix
flattened_list = [str(element) for row in matrix for element in row]
return "".join(flattened_list)
def print_matrix(self, matrix):
# Printing the matrix
for row in matrix:
print(" ".join(f"{element}" for element in row))
class AESEncryption(Encryption):
def __init__(self):
super().__init__(None)
self.final_state = None
def encrypt(self, cc_number, num_rounds):
start_time = time.time()
# Start measuring time
if not self.is_valid(cc_number):
return "Invalid input, please try again using the format specified."
# Returning error message if input is invalid
credit_number = self.create_matrix(cc_number)
round_key_decimal = self.create_round_key()
for i in range(num_rounds):
final_state = self.xor(credit_number, round_key_decimal)
credit_number = final_state
print("\nAdd Round Key:")
self.print_matrix(round_key_decimal)
# Printing round key matrix
print("\nFinal State Matrix:")
self.print_matrix(final_state)
# Printing final state matrix
final_state = self.shift_rows(final_state)
# Shifting rows of final state matrix
print("\nShift Rows:")
self.print_matrix(final_state)
# Printing shifted final state matrix
constant_matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
new_final_state_matrix = [[final_state[i][j] * constant_matrix[i][j] for j in range(4)] for i in range(4)]
print("\nConstant Matrix:")
self.print_matrix(constant_matrix)
# Printing constant matrix
round_key_decimal = self.create_round_key()
# Generating new round key
end_time = time.time()
# Stop measuring time
encryption_time = end_time - start_time
# Calculate encryption time
print("\nNew Final State Matrix:")
# Print new final state matrix
self.print_matrix(new_final_state_matrix)
encrypted_list = self.flatten_matrix(new_final_state_matrix)
# Flatten new final state matrix to a list
print("\n\n---------------------\nEncrypted message(AES):")
# Print encrypted message header
print(encrypted_list)
# Print encrypted message
messagebox.askyesno("Save Encrypted Message", "Do you want to save the encrypted message?")
# Ask user if they want to save encrypted message
file_name = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
# Get file name for saving
if file_name:
with open(file_name, "w") as file:
file.write(encrypted_list)
# Write encrypted message to file
return f"AES Encryption:\nTime complexity: {encryption_time:.2f} seconds\nSpace complexity : 133 lines\nNumber Of Rounds : 150\nSee console for encrypted message"
# Return AES encryption details
def is_valid(self, num):
# Check if the credit card number is valid
return len(num) == 19 and num.replace(" ", "").isdigit() and num[4] == " " and num[9] == " " and num[14] == " "
# Returns True if the credit card number is valid, False otherwise
def create_matrix(self, number):
# Create a matrix from the credit card number
number = number.replace(" ", "")
# Remove spaces from the credit card number
matrix = []
# Initialize an empty matrix
for i in range(0, 16, 4):
# Iterate over the credit card number in blocks of 4 digits
row = list(map(int, number[i:i + 4]))
# Convert each block of 4 digits to integers and create a list
matrix.append(row)
# Append the row to the matrix
return matrix
# Return the created matrix
def create_round_key(self):
# Create a round key matrix
return [[1, 5, 3, 5], [4, 1, 2, 4], [2, 4, 2, 1], [4, 5, 3, 2]]
# Return a predefined round key matrix
def xor(self, matrix1, matrix2):
# Perform XOR operation on two matrices
result_matrix = []
# Initialize an empty matrix to store the result
for i in range(4):
# Iterate over the rows of the matrices
row = []
# Initialize an empty row
for j in range(4):
# Iterate over the elements of the rows
result = matrix1[i][j] ^ matrix2[i][j]
# Perform XOR operation on corresponding elements of the matrices
row.append(result)
# Append the result to the row
result_matrix.append(row)
# Append the row to the result matrix
return result_matrix
# Return the result matrix
def shift_rows(self, state):
# Shift rows of the state matrix
for i in range(1, 4):
# Iterate over the rows of the matrix except the first one
state[i] = state[i][i:] + state[i][:i]
# Shift the elements of the row cyclically to the left
return state
# Return the shifted state matrix
class RSAEncryption(Encryption):
def __init__(self):
# Initialize RSAEncryption object
super().__init__(None)
# Call superclass initialization with None data
self.finished = False
# Flag indicating whether encryption process is finished
self.public_key = None
# Public key for RSA encryption
self.__private_key = None
# Private key for RSA encryption
def encrypt(self, credit_card_number):
# Encrypt the credit card number using RSA algorithm
start_time = time.time()
# Start measuring time
p = self.generate_prime()
# Generate a prime number p
q = self.generate_prime()
# Generate a prime number q
n = p * q
# Compute n as the product of p and q
num = (p - 1) * (q - 1)
# Compute num as (p-1)*(q-1)
e = self.find_coprime(num)
# Find a coprime e relative to num
d = self.calculate_private_key(e, num)
# Calculate the private key d
credit_card_number = credit_card_number.replace(" ", "")
# Remove spaces from the credit card number
if self.is_valid_credit_number(credit_card_number):
# Check if the credit card number is valid
credit_card_number_int = int(credit_card_number)
# Convert the credit card number to an integer
c = (credit_card_number_int**e) % n
print(f"Encrypted message : {c}")
# Encrypt the credit card number using RSA encryption
self.public_key = (n, e)
# Set the public key
self.__private_key = (n, d)
# Set the private key
end_time = time.time()
# Stop measuring time
elapsed_time = end_time - start_time
# Calculate encryption time
encrypted_cc = str(c)
# Convert the encrypted credit card number to a string
print(f"Public Key: {self.public_key}")
# Print the public key
print(f"Private Key: {self.__private_key}")
# Print the private key
self.finished = True
# Set the flag indicating encryption process is finished
return {
"message": f"RSA Encryption:\nTime complexity: {elapsed_time:.2f} seconds\nSpace complexity : 98 lines\nSee console for encrypted message",
# Return encryption message with time and space complexity information
"public_key": self.public_key,
# Return the public key
"private_key": self.__private_key,
# Return the private key
"save_message": messagebox.askyesno("Save Encrypted Message", "Do you want to save the encrypted message?"),
# Ask user if they want to save the encrypted message
"save_keys": messagebox.askyesno("Save Keys", "Do you want to save the public and private keys?"),
# Ask user if they want to save the keys
"encrypted_cc": encrypted_cc
# Return the encrypted credit card number
}
else:
# If the credit card number is invalid
return None
# Return None
def calculate_private_key(self, e, num):
# Calculate the private key d using extended Euclidean algorithm
d = 2
# Initialize d to 2
while True:
# Repeat until condition is met
if (d * e) % num == 1:
# If d is the multiplicative inverse of e modulo num
break
# Break the loop
d += 1
# Increment d
return d
# Return the private key
def gcd(self, a, b):
# Compute the greatest common divisor (GCD) of two integers
while b:
# Repeat until b is not zero
a, b = b, a % b
# Update a to b, and b to the remainder of a divided by b
return a
# Return the GCD
def find_coprime(self, number):
# Find a coprime relative to a given number
candidate = number - 1
# Initialize candidate to number - 1
while self.gcd(number, candidate) != 1:
# Repeat until a coprime is found
candidate -= 1
# Decrement the candidate
return candidate
# Return the coprime
def is_valid_credit_number(self, credit_card_number):
# Check if the credit card number is valid (has 16 digits)
credit_card_number = credit_card_number.replace(" ", "")
# Remove spaces from the credit card number
return len(credit_card_number) == 16
# Return True if the length of the credit card number is 16, False otherwise
def generate_prime(self):
# Generate a prime number between 100 and 1000
while True:
# Repeat until condition is met
num = random.randint(100, 1000)
# Generate a random number between 100 and 1000
if self.is_prime(num):
# If the generated number is prime
return num
# Return the prime number
def is_prime(self, num):
# Check if a number is prime
if num <= 1:
# If the number is less than or equal to 1, it's not prime
return False
# Return False
if num <= 3:
# If the number is 2 or 3, it's prime
return True
# Return True
if num % 2 == 0 or num % 3 == 0:
# If the number is divisible by 2 or 3, it's not prime
return False
# Return False
i = 5
# Start with 5 for checking prime numbers
while i * i <= num:
# Repeat until i*i is less than or equal to the number
if num % i == 0 or num % (i + 2) == 0:
# If the number is divisible by i or i+2, it's not prime
return False
# Return False
i += 6
# Increment i by 6 (considering only prime numbers can be of the form 6k ± 1)
return True
# Return True if the number is prime
class FileManager:
@staticmethod
def open_file():
# Static method to open a file dialog and read the content of the selected file
file_name = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
# Open a file dialog and get the selected file name
if file_name:
# If a file is selected
with open(file_name, "r") as file:
# Open the selected file for reading
content = file.read()
# Read the content of the file
return content
# Return the content of the file
return None
# If no file is selected, return None
@staticmethod
def save_to_file(content):
# Static method to save content to a file
file_name = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
# Open a file dialog to select a file to save content, with default extension ".txt"
if file_name:
# If a file name is provided
with open(file_name, "w") as file:
# Open the file for writing
file.write(content)
# Write the content to the file
messagebox.showinfo("Message Saved", "Content saved to file successfully.")
# Show a message box indicating that the content is saved successfully
class GUI(FileManager):
def __init__(self):
# Initialize the GUI window
self.window = Tk()
self.window.title("Encryption Comparison") # Set window title
self.window.geometry("500x350") # Set window size
self.credit_card_number = None # Initialize credit card number variable
self.aes = AESEncryption() # Initialize AES encryption object
self.rsa = RSAEncryption() # Initialize RSA encryption object
self.history_stack = [] # Initialize history stack to store operations
self.create_widgets() # Call method to create GUI widgets
def create_widgets(self):
# Create GUI widgets
title_label = Label(self.window, text="Encryption Comparison", font=("Helvetica", 16, "bold"))
title_label.pack(pady=10) # Pack title label widget
cc_label = Label(self.window, text="Enter Credit Card Number:")
cc_label.pack() # Pack credit card label widget
self.cc_entry = Entry(self.window, width=30)
self.cc_entry.pack() # Pack credit card entry widget
aes_button = Button(self.window, text="Encrypt with AES", command=self.encrypt_aes)
aes_button.pack(pady=10) # Pack AES encryption button widget
rsa_button = Button(self.window, text="Encrypt with RSA", command=self.encrypt_rsa)
rsa_button.pack(pady=5) # Pack RSA encryption button widget
compare_button = Button(self.window, text="Compare Results", command=self.compare_results)
compare_button.pack(pady=5) # Pack comparison button widget
view_history_button = Button(self.window, text="View History", command=self.view_history)
view_history_button.pack(pady=5) # Pack view history button widget
open_files_button = Button(self.window, text="Open Files", command=self.open_files)
open_files_button.pack(pady=5) # Pack open files button widget
exit_button = Button(self.window, text="Exit and Restart", command=self.exit_restart)
exit_button.pack(pady=5) # Pack exit and restart button widget
self.result_text = Text(self.window, height=5, width=50)
self.result_text.pack(pady=10) # Pack result text widget
def open_files(self):
# Open files and display their content
content = FileManager.open_file()
if content:
self.display_file_content(content)
def display_file_content(self, content):
# Display file content in a new window
file_window = Toplevel(self.window)
file_window.title("File Content") # Set window title
file_window.geometry("400x300") # Set window size
file_text = Text(file_window, height=10, width=50)
file_text.pack(pady=10) # Pack text widget
file_text.insert(END, content) # Insert file content
def view_history(self):
# View history of operations
history_window = Toplevel(self.window)
history_window.title("History") # Set window title
history_window.geometry("400x300") # Set window size
history_text = Text(history_window, height=10, width=50)
history_text.pack(pady=10) # Pack text widget
for operation in reversed(self.history_stack):
history_text.insert(END, operation + "\n") # Insert operation into history text widget
prev_button = Button(history_window, text="Previous", command=lambda: self.navigate_history(history_text))
prev_button.pack(pady=5) # Pack previous button widget
def navigate_history(self, history_text):
# Navigate through history
history_text.delete(1.0, END) # Delete previous history
if self.history_stack:
self.history_stack.pop() # Remove last operation from history stack
for operation in reversed(self.history_stack):
history_text.insert(END, operation + "\n") # Insert remaining operations into history text widget
def encrypt_aes(self):
# Encrypt credit card number using AES encryption
credit_card_number = self.cc_entry.get()
self.credit_card_number = credit_card_number # Store credit card number
result = self.aes.encrypt(credit_card_number, 128) # Encrypt credit card number using AES
self.history_stack.append(result) # Add encryption result to history stack
self.display_result(result) # Display encryption result
if "saved to file" in result:
messagebox.showinfo("Message Saved", "Encrypted message saved to file successfully.")
def encrypt_rsa(self):
# Encrypt credit card number using RSA encryption
credit_card_number = self.cc_entry.get()
self.credit_card_number = credit_card_number # Store credit card number
start_time = time.time()
result = self.rsa.encrypt(credit_card_number) # Encrypt credit card number using RSA
end_time = time.time()
if result:
if isinstance(result, str):
self.history_stack.append(result) # Add encryption result to history stack
self.display_result(result) # Display encryption result
else:
self.history_stack.append(result["message"]) # Add encryption result to history stack
self.display_result(result["message"]) # Display encryption result
if result["save_message"]:
self.save_encrypted_message(result["encrypted_cc"]) # Save encrypted message to file
if result["save_keys"]:
self.save_rsa_keys(result["public_key"], result["private_key"]) # Save RSA keys to file
def save_rsa_keys(self, public_key, private_key):
# Save RSA keys to file
content = f"Public Key: {public_key}\nPrivate Key: {private_key}\n"
FileManager.save_to_file(content) # Save keys to file
messagebox.showinfo("Keys Saved", "RSA keys saved to file successfully.")
# Method to compare encryption results
def compare_results(self):
aes_time_complexity = "Time Complexity (AES): O(N)"
aes_space_complexity = "Space Complexity (AES): O(1)"
rsa_time_complexity = "Time Complexity (RSA): O(1)"
rsa_space_complexity = "Space Complexity (RSA): O(1)"
comparison_result = "Comparison Result:\n"
# Determine if AES and RSA operations have been performed and update their time attributes
if hasattr(self, 'aes_time'):
aes_time = self.aes_time
else:
aes_time = 0
if hasattr(self, 'rsa_time'):
rsa_time = self.rsa_time
else:
rsa_time = 0
# Determine which encryption method is faster
if aes_time < rsa_time:
comparison_result += "AES is faster.\n"
elif aes_time > rsa_time:
comparison_result += "RSA is faster.\n"
else:
comparison_result += "Both AES and RSA have similar encryption times.\n"
# Determine which encryption method is more memory efficient
if aes_space_complexity < rsa_space_complexity:
comparison_result += "AES is more memory efficient.\n"
elif aes_space_complexity > rsa_space_complexity:
comparison_result += "RSA is more memory efficient.\n"
else:
comparison_result += "Both AES and RSA have similar memory efficiencies.\n"
# Determine which encryption method is stronger
comparison_result += "AES and RSA encryption are both strong encryption methods.\n"
# Display comparison results on GUI
self.history_stack.append(comparison_result) # Add comparison result to history
self.display_result(comparison_result) # Display comparison result
# Save comparison results to a file
file_name = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
if file_name:
with open(file_name, "w") as file:
file.write(comparison_result)
messagebox.showinfo("Message Saved", "Comparison results saved successfully.")
def exit_restart(self):
# Exit GUI and restart the application
self.delete_files() # Delete temporary files
self.window.destroy() # Destroy GUI window
python = sys.executable # Get Python executable path
os.execl(python, python, *sys.argv) # Restart the application
def delete_files(self):
# Delete temporary files
files = os.listdir()
for file in files:
if file.endswith(".txt"):
os.remove(file) # Remove file
def save_encrypted_message(self, encrypted_cc):
# Save encrypted message to file
FileManager.save_to_file(encrypted_cc) # Save encrypted message to file
messagebox.showinfo("Message Saved", "Encrypted credit card number saved successfully.")
def display_result(self, result):
# Display result on GUI
self.result_text.delete(1.0, END) # Delete previous result
self.result_text.insert(END, result) # Insert new result
def run(self):
# Run the GUI application
self.window.mainloop() # Run the GUI main loop
if __name__ == '__main__':
# Create and run GUI instance
gui = GUI()
gui.run()