import time
import gc
import os
import uos
time.sleep(0.1) # Wait for USB to become ready
substitution_box_dict = {'0000':'1','0001':'0','0010':'8','0011':'C',
'0100':'A','0101':'B','0110':'4','0111':'5',
'1000':'9','1001':'2','1010':'3','1011':'D',
'1100':'6','1101':'7','1110':'E','1111':'F'
}
reverse_substitution_box_dict={'1':'0000','0':'0001','8':'0010','C':'0011',
'A':'0100','B':'0101','4':'0110','5':'0111',
'9':'1000','2':'1001','3':'1010','D':'1011',
'6':'1100','7':'1101','E':'1110','F':'1111'
}
#Common Code
def get_storage_usage():
total_bytes = uos.statvfs('/')[0] # Total bytes in the filesystem
free_bytes = uos.statvfs('/')[4] # Free bytes in the filesystem
used_bytes = total_bytes - free_bytes
return total_bytes, used_bytes, free_bytes
def print_storage_usage():
total, used, free = get_storage_usage()
print("Total space: {} bytes".format(total))
print("Used space: {} bytes".format(used))
print("Free space: {} bytes".format(free))
def split_binary_into_chunks(binary_string,chunk_size):
return [binary_string[i:i+chunk_size] for i in range(0, len(binary_string), chunk_size)]
def merge_chunks_into_binary(chunk_list):
return ''.join(chunk_list)
def xor_binary_strings(binary_str1, binary_str2):
# Perform XOR operation on binary strings
result = ''.join(str(int(bit1) ^ int(bit2)) for bit1, bit2 in zip(binary_str1, binary_str2))
return result
#Encryption functions
def encrypt_string_to_decimal(input_str):
decimal_values_concatenated = 0 # Initialize as integer
for char in input_str:
decimal_values_concatenated = decimal_values_concatenated * 1000 + ord(char) # Convert character to ASCII value and concatenate
return decimal_values_concatenated
def decimal_to_multiple_128bit_binary(decimal_number):
# Convert decimal number to binary
binary_number = bin(decimal_number)[2:]
# Calculate the number of bits needed to make it a multiple of 128
padding_length = (128 - len(binary_number) % 128) % 128
# Add padding zeros to make it a multiple of 128 bits
padded_binary_number = '0' * padding_length + binary_number
return padded_binary_number
def NOT_gate_32_bit(input_bits):
# Ensure the input is exactly 32 bits long
if len(input_bits) != 32:
raise ValueError("Input must be 32 bits long")
# Perform the NOT operation on each bit of the input
output_bits = ''.join(['1' if bit == '0' else '0' for bit in input_bits])
return output_bits
def split_and_swap_32_to_64(input_block):
# Ensure the input block is exactly 32 bits
if len(input_block) != 32:
raise ValueError("Input block must be 32 bits long")
# Split the input block into left and right halves (16 bits each)
left_half = input_block[:16]
right_half = input_block[16:]
#Generate the middle part of 32 bits compliment using function
middle_element=NOT_gate_32_bit(input_block)
element_0=right_half+middle_element+left_half
return element_0
def substitution_box(input_bits):
s_box_output=""
for i in range(0, len(input_bits),4):
s_box_output+=substitution_box_dict[input_bits[i:i+4]]
return s_box_output
def permute(input_text):
output_text=input_text[7]+input_text[0]+input_text[6]+input_text[4]+input_text[5]+input_text[3]+input_text[2]+input_text[1]
return output_text
def permutation_box(input_text):
to_return=""
for i in range(0,len(input_text),8):
chunk = input_text[i:i+8]
to_add=permute(chunk)
to_return+=to_add
return to_return
# Encryption
def encryption(input_text, k1):
a= decimal_to_multiple_128bit_binary(encrypt_string_to_decimal(input_text))
b=split_binary_into_chunks(a,32)
arr=[]
for i in b:
temp=split_and_swap_32_to_64(i)
temp= xor_binary_strings(temp,k1)
arr.append(temp)
to_return=merge_chunks_into_binary(arr)
to_return=substitution_box(to_return)
# to_return=permutation_box(to_return)
return to_return
def calculate_cpu_usage(idle_time, busy_time, measurement_duration_ms):
idle_fraction = idle_time / measurement_duration_ms
busy_fraction = busy_time / measurement_duration_ms
cpu_usage = (busy_fraction / (idle_fraction + busy_fraction)) * 100
return cpu_usage
a1,b1,c1=get_storage_usage()
print_storage_usage()
plain_text=input("Enter the text to encrypt: ")
key_1='1010000001101010101000000010101010000000010010101001010101100010'
# print(len(key_1))
start_time=time.time_ns()
gc.collect()
initial_free = gc.mem_free()
Encrypted_text=encryption(plain_text, key_1)
a2,b2,c2 = get_storage_usage()
print_storage_usage()
print("Total storage usage: ", b2-b1)
end_time = time.time_ns()
gc.collect()
final_free = gc.mem_free()
execution_time=end_time-start_time
print("Execution time: ", execution_time)
ram_used = initial_free - final_free
print("RAM used by the program:", ram_used, " bytes.")
print("Original text is: ",plain_text)
print("Original text is of ",len(plain_text)," bits")
print("Key for encryption: ", key_1)
print("Key is of ",len(key_1), " bits")
print("Encrypted text is: ",Encrypted_text)
print("Encrypted text is of ",len(Encrypted_text)," bits")