From d274024778b40205b718517d7c916ef2766ec484 Mon Sep 17 00:00:00 2001
From: Viken <v.karaboghossian@student.isae-supaero.fr>
Date: Wed, 30 Aug 2023 15:19:02 +0200
Subject: [PATCH] auj
---
instruction.md | 47 ++++---------
main.py | 68 +++++++++----------
.../stream_cipher/AES_measuring.py | 3 +-
src/scenarios.py | 59 ++++++++--------
4 files changed, 75 insertions(+), 102 deletions(-)
diff --git a/instruction.md b/instruction.md
index 86df49b..76ef81f 100644
--- a/instruction.md
+++ b/instruction.md
@@ -12,54 +12,31 @@ This has been written in Python3 in the context of Viken KARABOGHOSSIAN's projec
The project contains the following files:
* `requirements.txt`: the list of all required Python3 packages.
* `instruction.md`: this file, which contains the instructions to better understand and use the scripts.
-* ```interative_plots.py``` : command line tool to interactively decide which algorithms, operations and metrics to visualize.
-* ```automated_plots.py```: an automated script to generate and save automatically the required plots.
-* ```scenarios.py```: command line tool to interactively create scenario, where a scenario is defined by two end users, a bandwidth and a latency. An end user is defined by its : memory/RAM capacity, plaintext size (size of the transmitted package), and a processor frequency.
-* ```main.py```: command line tool to study a scenario and save the result in csv file
+* ```main.py```: command line tool to interactively do the comparative study.
* `/plots`: a folder in which the plots will be saved.
-* `/ciphers_src`: a folder that contains the python implementation of the ciphers we study.
+* `/src`: a folder that contains both the python implementation of the ciphers we study and utils fonction for the orrect execution of the main script.
* `/doc`: a folder that contains the documentation generated by sphinx.
+* `/Litterature`: a folder that contains litterature for the internship.
-## Usage (interactive ploting)
+## Usage
1. Open the root folder of your project in a terminal. This folder should contain:
- * The ```interactive_plots.py``` script
- * The csv file containing the results you want to plot (delimiter = ',')
+ * The ```main.py``` script
* This file (`instructions.md`)
-2. You will be prompted questions. Answer them and click `enter`.
-
-## Usage (automated ploting)
-1. Open the root folder of your project in a terminal. This folder should contain:
- * The ```automated_plots.py``` script
- * The csv file containing the results you want to plot (delimiter = ',')
- * This file (`instructions.md`)
-2. Before executing the script, check the following parameters:
- * filepath
- * metrics_choices
- * operation_choices
- * algo_choices
-3. Then type: ```python3 automated_plots.py```
-4. Check your results in `/results`
-
-## Usage (main)
-
+2. Execute the ```main.py``` script by typing ```python3 main.py```. You will be prompted questions. Answer them and click `enter`.
+3. If you decided to save the plot, check them in `/plots`
## Content
-The tool was designed to take as input a csv file containing information about the performance evaluation of encryption schemes. As the project studied block cipher and stream cipher, the tool can handle the two following lists of headers:
-* Block cipher:
-|algo|key_length|block_length|operation|integrity|implementation_size|ram_consumption|throughput|execution_time|memory_usage|encrypted_file_size|
-
-* Stream cipher:
-|algo|key_length|nonce_length|operation|integrity|implementation_size|ram_consumption|throughput|execution_time|memory_usage|encrypted_file_size|
+The tool was designed to make a comparative study between a set of symmetric encryption cipher.
+It is based on the comparisons of the costs of each cipher in a given scenario (a scebario is a set of two node), where ciher's cost is a weighted summation of the cipher's performances.
------------
## Improvement and future work:
-
-* Render the program more flexible. E.g., take csv for which the headers are not known.
-* Add autocompletion for paremeter selection (rich.prompt Completion)
+* Render the program more flexible.
+* Improve the measurments of ciphers' perfomance.
## More to come:
-...
+
# PROGRAM STARTS
\ No newline at end of file
diff --git a/main.py b/main.py
index 596a24b..78128f1 100644
--- a/main.py
+++ b/main.py
@@ -10,8 +10,6 @@ from rich.prompt import Prompt
from rich.console import Console
from rich.markdown import Markdown
import matplotlib.pyplot as plt
-import datetime
-
class Transmission:
@@ -29,21 +27,25 @@ class Transmission:
self.plaintext_size = len(self.plaintext)
###### Set up the scenario
- choice = Prompt.ask("\nChoose between the following scenarios:\n1: end_to_end\n2: ground_to_satellite\n3: satellite_to_satellite\n",
- choices=['1', '2', '3'], default='1')
+ choice = Prompt.ask("\nChoose between the following scenarios:\n0: default \n1: end_to_end\n2: ground_to_satellite\n3: satellite_to_satellite\n",
+ choices=['0', '1', '2', '3'], default='0')
+ if choice == '0':
+ self.scene = 'default'
+ default = node(1, 1, 1/self.plaintext_size, self.plaintext)
+ self.scenarii = scenario(default, default, 1, 1, 1, self.plaintext)
if choice == '1':
self.scene = 'end_to_end'
end_user = node(16e9, 8e9, 3.5e9, self.plaintext)
- self.scenarii = scenario(end_user, end_user, 13e9, 1600e3, self.plaintext)
+ self.scenarii = scenario(end_user, end_user, 13e9, 1600e3, 3 * 10 ** 8, self.plaintext)
elif choice == '2':
self.scene = 'ground_to_satellite'
satellite = node(2e9, 512e6, 100e6, self.plaintext)
ground_station = node(1e12, 32e9, 4e9, self.plaintext)
- self.scenarii = scenario(ground_station, satellite, 13e9, 500e3, self.plaintext)
+ self.scenarii = scenario(ground_station, satellite, 13e9, 500e3, 3 * 10 ** 8, self.plaintext)
elif choice == '3':
self.scene = 'satellite_to_satellite'
satellite = node(2e9, 512e6, 100e6, self.plaintext)
- self.scenarii = scenario(satellite, satellite, 281.7e12, 7371e3, self.plaintext)
+ self.scenarii = scenario(satellite, satellite, 281.7e12, 7371e3, 3 * 10 ** 8, self.plaintext)
def run_analysis(self):
@@ -57,46 +59,38 @@ class Transmission:
for cipher in self.scenarii.costs[mode].keys():
for combination in self.scenarii.costs[mode][cipher].keys():
plt.barh(combination, self.scenarii.costs[mode][cipher][combination])
+ plt.ylabel("Algorithm-key_size/nonce_block_size")
+ plt.xlabel("Cost")
+ plt.yticks(fontsize=9)
+ plt.title(f"Comparative anaysis for a {self.plaintext_size}byte long message")
+ plt.tight_layout() # Ensures labels don't overlap
plt.show()
- # Automatic saving
- if Prompt.ask("Do you want to save the plot?", choices=['y', 'n'], default='n') == "y":
- date = datetime.datetime.now()
- for mode in self.scenarii.costs.keys():
- for cipher in self.scenarii.costs[mode].keys():
- for combination in self.scenarii.costs[mode][cipher].keys():
- plt.barh(combination, self.scenarii.costs[mode][cipher][combination])
- plt.savefig('plots/' + 'cost_' + self.scene + '-' + str(date.year) + str(date.month) +
- str(date.day) + '-' + str(date.hour) + str(date.minute) + '.png')
-
- # Clear after saving
- plt.clf()
- plt.cla()
-
# Keep only the best combinations
self.scenarii.choose_the_better()
plt.figure('Now only the best combination for each cipher in a ' + self.scene + ' scenario')
+
for mode in self.scenarii.costs.keys():
for cipher in self.scenarii.costs[mode].keys():
- for combination in self.scenarii.costs[mode][cipher].keys():
- plt.barh(combination, self.scenarii.costs[mode][cipher][combination])
+ combinations = list(self.scenarii.costs[mode][cipher].keys())
+ costs = list(self.scenarii.costs[mode][cipher].values())
+
+ bars = plt.barh(combinations, costs)
+
+ # Adding text labels for each bar
+ for bar, cost in zip(bars, costs):
+ label = f'{cost:.6f}' if cost > 0.000001 else f'{cost:.2e}'
+ plt.text(bar.get_width(), bar.get_y() + bar.get_height()/2, label,
+ va='center', fontsize=8, color='black', fontweight='bold')
+
+ plt.ylabel("Algorithm-key_size/nonce_block_size")
+ plt.xlabel("Cost")
+ plt.yticks(fontsize=9)
+ plt.title(f"Comparative analysis for a {self.plaintext_size} byte long message")
+ plt.tight_layout() # Ensures labels don't overlap
plt.show()
- # Automatic saving
- if Prompt.ask("Do you want to save the plot?", choices=['y', 'n'], default='n') == "y":
- date = datetime.datetime.now()
- for mode in self.scenarii.costs.keys():
- for cipher in self.scenarii.costs[mode].keys():
- for combination in self.scenarii.costs[mode][cipher].keys():
- plt.barh(combination, self.scenarii.costs[mode][cipher][combination])
- plt.savefig('plots/' + 'cost_' + self.scene + '-' + str(date.year) + str(date.month) +
- str(date.day) + '-' + str(date.hour) + str(date.minute) + '.png')
-
- # Clear after saving
- plt.clf()
- plt.cla()
-
if __name__ == "__main__":
diff --git a/src/ciphers_src/stream_cipher/AES_measuring.py b/src/ciphers_src/stream_cipher/AES_measuring.py
index 6108aab..d42374a 100644
--- a/src/ciphers_src/stream_cipher/AES_measuring.py
+++ b/src/ciphers_src/stream_cipher/AES_measuring.py
@@ -14,7 +14,8 @@ from src.ciphers_src.util import measure_software_performance
MODE = AES.MODE_CTR
-LENGTHS = [[16,nonce] for nonce in range(16)] + [[24 , nonce] for nonce in range(16)] + [[32,nonce] for nonce in range(16)]
+#LENGTHS = [[16,nonce] for nonce in range(16)] + [[24 , nonce] for nonce in range(16)] + [[32,nonce] for nonce in range(16)]
+LENGTHS = [[16,nonce] for nonce in [8,12]] + [[24 , nonce] for nonce in [8,12]] + [[32,nonce] for nonce in [8,12]]
KEY_SIZES = [length[0] for length in LENGTHS]
NONCE_SIZES = [length[1] for length in LENGTHS]
KEYS = [os.urandom(key_size) for key_size in KEY_SIZES] # Generate a random N-byte long key
diff --git a/src/scenarios.py b/src/scenarios.py
index 29f2e77..4705cea 100644
--- a/src/scenarios.py
+++ b/src/scenarios.py
@@ -28,14 +28,12 @@ CIPHER = {
}
}
-SIGNAL_CELERITY = 3 * 10 ** 8 # OEM signal celerity
class node :
def __init__(self,storage_capacity, RAM_capacity, processor_frequency, plaintext) -> None:
self.storage_capacity = storage_capacity
self.RAM_capacity = RAM_capacity
self.processor_frequency = processor_frequency
-
stream = self._cipher_analysis('stream', plaintext)
block = self._cipher_analysis('block', plaintext)
integrity = (stream[1]==block[1]) == True
@@ -44,6 +42,7 @@ class node :
"stream" : stream[0],
"block" : block[0]
}
+ self.normalization()
def _cipher_analysis(self, mode, plaintext):
@@ -140,12 +139,12 @@ class node :
for mode in ['stream','block']:
min_max_metrics = {
- 'encrytion' : {
+ 'encryption' : {
"implementation_size": [],
"ram_consumption": [],
"throughput": [],
"execution_time": [],
- "memory_usage": [],
+ #"memory_usage": [],
"encrypted_file_size": [],
#"cpu_cycles": [encryption[6], decryption[6], encryption[6]+ decryption[6]],
},
@@ -154,7 +153,7 @@ class node :
"ram_consumption": [],
"throughput": [],
"execution_time": [],
- "memory_usage": [],
+ #"memory_usage": [],
"encrypted_file_size": [],
#"cpu_cycles": [encryption[6], decryption[6], encryption[6]+ decryption[6]],
},
@@ -163,7 +162,7 @@ class node :
"ram_consumption": [],
"throughput": [],
"execution_time": [],
- "memory_usage": [],
+ #"memory_usage": [],
"encrypted_file_size": [],
#"cpu_cycles": [encryption[6], decryption[6], encryption[6]+ decryption[6]],
},
@@ -171,32 +170,36 @@ class node :
# add them all in a min_max_metrics dictionnary
for cipher in self.ciphers_data[mode].keys() :
- for operation in self.ciphers_data[mode][cipher].keys():
- for metric in self.ciphers_data[mode][cipher][operation].keys():
- min_max_metrics[operation][metric].append(self.ciphers_data[mode][cipher][operation][metric])
+ for combinaison in self.ciphers_data[mode][cipher].keys():
+ for operation in self.ciphers_data[mode][cipher][combinaison].keys():
+ if operation != "integrity":
+ for metric in self.ciphers_data[mode][cipher][combinaison][operation].keys():
+ min_max_metrics[operation][metric].append(self.ciphers_data[mode][cipher][combinaison][operation][metric])
# just keep the max and min value
for operation in min_max_metrics.keys():
for metric in min_max_metrics[operation].keys():
- max = max(min_max_metrics[operation][metric])
- min = min(min_max_metrics[operation][metric])
- min_max_metrics[operation][metric] = [min, max]
+ maxim = max(min_max_metrics[operation][metric])
+ minim = min(min_max_metrics[operation][metric])
+ min_max_metrics[operation][metric] = [minim, maxim]
# now normalize
for cipher in self.ciphers_data[mode].keys() :
- for operation in self.ciphers_data[mode][cipher].keys():
- for metric in self.ciphers_data[mode][cipher][operation].keys():
- maxim = min_max_metrics[operation][metric][1]
- minim = min_max_metrics[operation][metric][0]
- if [max, min] == [0,0]:
- pass
- if not (metric == "throughput") :
- self.ciphers_data[mode][cipher][operation][metric] -= minim
- else :
- self.ciphers_data[mode][cipher][operation][metric] = \
- maxim - self.ciphers_data[mode][cipher][operation][metric]
-
- self.ciphers_data[mode][cipher][operation][metric] /= (maxim-minim)
+ for combinaison in self.ciphers_data[mode][cipher].keys():
+ for operation in self.ciphers_data[mode][cipher][combinaison].keys():
+ if operation != "integrity":
+ for metric in self.ciphers_data[mode][cipher][combinaison][operation].keys():
+ maxim = min_max_metrics[operation][metric][1]
+ minim = min_max_metrics[operation][metric][0]
+ if [maxim, minim] != [0,0]:
+ if maxim == minim :
+ minim=0
+ if not (metric == "throughput") :
+ self.ciphers_data[mode][cipher][combinaison][operation][metric] -= minim
+ else :
+ self.ciphers_data[mode][cipher][combinaison][operation][metric] = \
+ maxim - self.ciphers_data[mode][cipher][combinaison][operation][metric]
+ self.ciphers_data[mode][cipher][combinaison][operation][metric] /= (maxim-minim)
@@ -204,12 +207,12 @@ class node :
class scenario :
- def __init__(self, node1, node2, bandwidth, distance, plaintext) -> None:
+ def __init__(self, node1, node2, bandwidth, distance, signal_celerity, plaintext) -> None:
self.node1 = node1
self.node2 = node2
self.bandwidth = bandwidth
self.distance = distance
- self.latency = distance/SIGNAL_CELERITY
+ self.latency = distance/signal_celerity
self.weights = self._weights(plaintext)
self.costs = {
@@ -217,8 +220,6 @@ class scenario :
'block' : self._ciphers_cost('block', plaintext)
}
-
-
def _weights(self, message):
--
GitLab