Sfoglia il codice sorgente

Clean 'SimulationProject' (start)

master
Thibauld Feneuil 4 anni fa
parent
commit
771a50792e
5 ha cambiato i file con 130 aggiunte e 97 eliminazioni
  1. 3
    2
      elmo/__main__.py
  2. 5
    1
      elmo/config.py
  3. 8
    2
      elmo/executor.py
  4. 113
    91
      elmo/project_base.py
  5. 1
    1
      test.py

+ 3
- 2
elmo/__main__.py Vedi File

@@ -52,9 +52,10 @@ if command == 'create-simulation':

if command == 'run-server':
from .executor import launch_executor
from .config import DEFAULT_HOST, DEFAULT_PORT
host = sys.argv[2] if len(sys.argv) >= 3 else 'localhost'
port = int(sys.argv[3]) if len(sys.argv) >= 4 else 5000
host = sys.argv[2] if len(sys.argv) >= 3 else DEFAULT_HOST
port = int(sys.argv[3]) if len(sys.argv) >= 4 else DEFAULT_PORT

launch_executor(host, port)
exit()

+ 5
- 1
elmo/config.py Vedi File

@@ -11,4 +11,8 @@ ELMO_INPUT_FILE_NAME = 'input.txt'

MODULE_PATH = os.path.dirname(os.path.abspath(__file__))

SEARCH_EXCLUSION_TAG = 'EXCLUDE-FROM-SIMULATION-SEARCH'
SEARCH_EXCLUSION_TAG = 'EXCLUDE-FROM-SIMULATION-SEARCH'

# ELMO Server
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 5000

+ 8
- 2
elmo/executor.py Vedi File

@@ -4,7 +4,13 @@ import sys
from .server.servicethread import OneShotServiceThread
from .config import MODULE_PATH, ELMO_TOOL_REPOSITORY, ELMO_INPUT_FILE_NAME
from .config import (
MODULE_PATH,
ELMO_TOOL_REPOSITORY,
ELMO_INPUT_FILE_NAME,
DEFAULT_HOST,
DEFAULT_PORT,
)
from .project_base import SimulationProject
from .manage import execute_simulation
@@ -78,7 +84,7 @@ class Executor(OneShotServiceThread):
self.protocol.close()
def launch_executor(host, port, waiting_function=True):
def launch_executor(host=DEFAULT_HOST, port=DEFAULT_PORT, waiting_function=True):
from .server.servicethread import ListeningThread
def do_main_program():

+ 113
- 91
elmo/project_base.py Vedi File

@@ -1,7 +1,14 @@
import os, re
import numpy as np
from os.path import join as pjoin
from .config import MODULE_PATH, ELMO_TOOL_REPOSITORY
from .config import (
MODULE_PATH,
ELMO_TOOL_REPOSITORY,
ELMO_INPUT_FILE_NAME,
DEFAULT_HOST,
DEFAULT_PORT,
)
from .utils import write
class SimulationProject:
@@ -47,7 +54,7 @@ class SimulationProject:
### Tools to realize the simulation of the project
def __init__(self, challenges=None):
self.elmo_folder = os.path.join(MODULE_PATH, ELMO_TOOL_REPOSITORY)
self.elmo_folder = pjoin(MODULE_PATH, ELMO_TOOL_REPOSITORY)
self.challenges = challenges
self.reset()
@@ -55,6 +62,7 @@ class SimulationProject:
self.is_executed = False
self.has_been_online = False
self._nb_traces = None
self._complete_asmtrace = None
self._complete_results = None
self._complete_printed_data = None
@@ -66,11 +74,18 @@ class SimulationProject:
raise NotImplementedError()
def set_challenges(self, challenges):
self.reset()
self.challenges = challenges
def get_writable_input_file(self):
return open('{}/input.txt'.format(self.elmo_folder), 'w')
def get_input_filename(self):
return pjoin(self.elmo_folder, ELMO_INPUT_FILE_NAME)
def get_printed_data_filename(self):
return pjoin(self.elmo_folder, 'output', 'printdata.txt')
def get_asmtrace_filename(self):
return pjoin(self.elmo_folder, 'output', 'asmoutput', 'asmtrace00001.txt')
def set_input_for_each_challenge(self, input, challenge):
format = self.get_challenge_format()
@@ -98,15 +113,18 @@ class SimulationProject:
def run(self):
self.reset()
with open('{}/input.txt'.format(self.elmo_folder), 'w') as _input:
with open(self.get_input_filename(), 'w') as _input:
self.set_input(_input)
from .manage import execute_simulation
res = execute_simulation(self)
self.is_executed = True
self.has_been_online = False
self._nb_traces = res['nb_traces']
return res
def run_online(self, host='localhost', port=5000):
def run_online(self, host=DEFAULT_HOST, port=DEFAULT_PORT):
from .server.protocol import SocketTool
import socket
@@ -144,6 +162,7 @@ class SimulationProject:
self.is_executed = True
self.has_been_online = True
self._nb_traces = data['nb_traces']
self._complete_asmtrace = data['asmtrace']
self._complete_results = data['results']
self._complete_printed_data = data['printed_data']
@@ -152,112 +171,115 @@ class SimulationProject:
if key not in ['results', 'asmtrace', 'printed_data']
}
### Manipulate the ASM trace
def get_asmtrace_filename(self):
return '{}/output/asmoutput/asmtrace00001.txt'.format(self.elmo_folder)
def get_asmtrace(self):
if self._complete_asmtrace is None:
with open(self.get_asmtrace_filename(), 'r') as _file:
self._complete_asmtrace = ''.join(_file.readlines())
return self._complete_asmtrace.split('\n')
def get_indexes_of(self, condition):
return [i for i, instr in enumerate(self.get_asmtrace()) if condition(instr)]
### Manipulate the results
def get_number_of_traces(self):
def get_number_of_challenges(self):
return len(self.challenges)
def get_number_of_traces(self):
assert self.is_executed
return self._nb_traces
def get_results(self, only_filenames=False, reorganise=None, indexes=None):
def get_results_filenames(self):
assert self.is_executed
assert not self.has_been_online
nb_traces = self.get_number_of_traces()
output_path = os.path.join(self.elmo_folder, 'output')
filenames = []
for i in range(nb_traces):
filename = os.path.join(output_path, 'traces', 'trace%05d.trc' % (i+1))
assert os.path.isfile(filename)
filenames.append(filename)
return filenames
def get_results(self):
"""
Warning: The output list is the same object stored in the instance.
If you change this object, it will change in the instance too, and the
next call to 'get_results' will return the changed object.
"""
assert self.is_executed
nb_traces = self.get_number_of_traces()
if only_filenames and self.has_been_online:
raise Exception('Impossible to get the filenames for an online execution')
if only_filenames or self._complete_results is None:
trace_filenames = []
for filename in os.listdir('{}/output/traces/'.format(self.elmo_folder)):
if re.search(r'^trace\d+\.trc$', filename):
trace_filenames.append('{}/output/traces/{}'.format(self.elmo_folder, filename))
if len(trace_filenames) >= nb_traces:
break
assert len(trace_filenames) == nb_traces
if only_filenames:
return reorganise(trace_filenames) if reorganise is not None else trace_filenames
# Load the power traces
if self._complete_results is None:
self._complete_results = []
for filename in trace_filenames:
for filename in self.get_results_filenames():
with open(filename, 'r') as _file:
self._complete_results.append(list(map(float, _file.readlines())))
results = self._complete_results
if indexes is not None:
for i in range(len(self._complete_results)):
results[i] = results[i][indexes]
if reorganise is not None:
results = reorganise(results)
return results
return self._complete_results
def get_traces(self, reorganise=None, indexes=None):
results = self.get_results(only_filenames=False, reorganise=reorganise, indexes=indexes)
def get_traces(self, indexes=None):
"""
"""
assert self.is_executed
results = self.get_results()
nb_traces = self.get_number_of_traces()
trace_length = len(results[0])
if indexes is None:
traces = np.zeros((nb_traces, trace_length))
for i in range(nb_traces):
traces[i,:] = results[i]
return traces
else:
traces = np.zeros((nb_traces, len(indexes)))
for i in range(nb_traces):
traces[i,:] = results[i][indexes]
return traces
traces = np.zeros((nb_traces, trace_length))
for i in range(nb_traces):
traces[i,:] = results[i]
### Manipulate the ASM trace
def get_asmtrace(self):
""" Get the ASM trace of the last simulation
The ASM trace is the list of the leaking assembler instructions,
one instruction each point of the leakage power trace
"""
assert self.is_executed
if reorganise is not None:
traces = reorganise(traces)
# Load the ASM trace
if self._complete_asmtrace is None:
with open(self.get_asmtrace_filename(), 'r') as _file:
self._complete_asmtrace = _file.read()
if type(self._complete_asmtrace):
self._complete_asmtrace = self._complete_asmtrace.split('\n')
return traces
return self._complete_asmtrace
def get_indexes_of(self, condition):
""" Get the list of indexes of the instructions
verifying the 'condition' in the ASM trace
:condition: Boolean function with ASM instruction (string) for input
"""
assert self.is_executed
return [i for i, instr in enumerate(self.get_asmtrace()) if condition(instr)]
### Manipulate the Printed Data
def get_printed_data(self):
def get_printed_data(self, per_trace=True):
""" Get the printed data of the last simulation
A printed data is a data which has been given to the function 'printbyte'
during the simulation
:per_trace: If True (default), split equally the printed data in a table
with a length equal to the number of simulated power traces
"""
assert self.is_executed
# Load the printed data
if self._complete_printed_data is None:
with open('{}/output/printdata.txt'.format(self.elmo_folder), 'r') as _file:
with open(self.get_printed_data_filename(), 'r') as _file:
self._complete_printed_data = list(map(lambda x: int(x, 16), _file.readlines()))
data = self._complete_printed_data
nb_traces = self.get_number_of_traces()
nb_data_per_trace = len(data) // nb_traces
return [data[nb_data_per_trace*i:nb_data_per_trace*(i+1)] for i in range(nb_traces)]
if per_trace:
# Return printed data for each trace
data = self._complete_printed_data
nb_traces = self.get_number_of_traces()
nb_data_per_trace = len(data) // nb_traces
### Other
def analyse_operands(self, num_line, num_trace=1):
num_str = str(num_trace)
num_str = '0'*(5-len(num_str)) + num_str
return [data[nb_data_per_trace*i:nb_data_per_trace*(i+1)] for i in range(nb_traces)]
operands_filename = self.elmo_folder + '/output/operands/operands{}.txt'.format(num_str)
trace_filename = self.elmo_folder + '/output/traces/trace0000{}.trc'.format(num_trace)
is_multiple = (type(num_line) is list)
if not is_multiple:
num_line = [num_line]
output = [{}]*len(num_line)
with open(operands_filename, 'r') as _file:
lines = _file.readlines()
for i, num in enumerate(num_line):
line = lines[num].split()
data = list(map(int, line[0:7]))
output[i]['previous'] = data[0:2]
output[i]['current'] = data[2:4]
output[i]['triplet'] = data[4:7]
output[i]['other'] = list(map(float, line[7:]))
with open(trace_filename, 'r') as _file:
lines = _file.readlines()
for i, num in enumerate(num_line):
line = lines[num]
output[i]['power'] = float(line)
return output if is_multiple else output[0]
else:
# Return printed data
return self._complete_printed_data

+ 1
- 1
test.py Vedi File

@@ -91,7 +91,7 @@ def test_online_server():

from elmo.executor import launch_executor
# Launch the server and realize the test
res = launch_executor('localhost', 5000, waiting_function=test_online_server)
res = launch_executor(waiting_function=test_online_server)

assert not res['error']
assert res['nb_traces'] == 10

Loading…
Annulla
Salva