Skip to content

Commit

Permalink
FIX/Fix: doctest
Browse files Browse the repository at this point in the history
  • Loading branch information
SimoPez committed Sep 24, 2024
1 parent f226914 commit 46df364
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 230 deletions.
31 changes: 14 additions & 17 deletions claasp/cipher_modules/models/cp/mzn_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,10 @@ def fix_variables_value_constraints_for_ARX(self, fixed_variables=[]):
EXAMPLES::
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model_arx_optimized import MznXorDifferentialModelARXOptimized
sage: from claasp.ciphers.block_ciphers.raiden_block_cipher import RaidenBlockCipher
sage: raiden = RaidenBlockCipher(number_of_rounds=1)
sage: minizinc = MznXorDifferentialModel(raiden)
sage: minizinc = MznXorDifferentialModelARXOptimized(raiden)
sage: minizinc.build_xor_differential_trail_model()
sage: fixed_variables = [{
....: 'component_id': 'key',
Expand All @@ -371,7 +371,7 @@ def fix_variables_value_constraints_for_ARX(self, fixed_variables=[]):
....: 'bit_positions': [0, 1, 2, 3],
....: 'operator': '>',
....: 'value': '0' }]
sage: minizinc.fix_variables_value_constraints(fixed_variables)[0]
sage: minizinc.fix_variables_value_constraints_for_ARX(fixed_variables)[0]
'constraint plaintext_y0+plaintext_y1+plaintext_y2+plaintext_y3>0;'
"""
def equal_operator(constraints_, fixed_variables_object_):
Expand Down Expand Up @@ -508,7 +508,7 @@ def parse_solver_information(self, output_to_parse, truncated=False, solve_exter
return components_values, memory, time
return components_values, memory, time, total_weight

def _parse_solver_output(self, output_to_parse, model_type, truncated = False, solve_external = True, solver_name = SOLVER_DEFAULT):
def _parse_solver_output(self, output_to_parse, model_type, truncated = False, solve_external = False, solver_name = SOLVER_DEFAULT):
"""
Parse solver solution (if needed).
Expand All @@ -519,11 +519,11 @@ def _parse_solver_output(self, output_to_parse, model_type, truncated = False, s
EXAMPLES::
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_trail_search_model import MznXorDifferentialTrailSearchModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.utils import set_fixed_variables, integer_to_bit_list, write_model_to_file
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=4)
sage: cp = MznXorDifferentialTrailSearchModel(speck)
sage: cp = MznXorDifferentialModel(speck)
sage: fixed_variables = [set_fixed_variables('key', 'equal', range(64), integer_to_bit_list(0, 64, 'little'))]
sage: fixed_variables.append(set_fixed_variables('plaintext', 'equal', range(32), integer_to_bit_list(0, 32, 'little')))
sage: cp.build_xor_differential_trail_model(-1, fixed_variables)
Expand All @@ -533,7 +533,7 @@ def _parse_solver_output(self, output_to_parse, model_type, truncated = False, s
sage: solver_process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
sage: os.remove('doctesting_file.mzn')
sage: solver_output = solver_process.stdout.splitlines()
sage: cp._parse_solver_output(solver_output) # random
sage: cp._parse_solver_output(solver_output, model_type = 'xor_differential_one_solution', solve_external = True) # random
(0.018,
...
'cipher_output_3_12': {'value': '0', 'weight': 0}}},
Expand Down Expand Up @@ -614,7 +614,7 @@ def set_component_solution_value(self, component_solution, truncated, value):
else:
component_solution['value'] = value

def solve(self, model_type, solver_name=SOLVER_DEFAULT, solve_external=True, timeout_in_seconds_=None,
def solve(self, model_type, solver_name=SOLVER_DEFAULT, solve_external=False, timeout_in_seconds_=None,
processes_=None, nr_solutions_=None, random_seed_=None,
all_solutions_=False, intermediate_solutions_=False,
free_search_=False, optimisation_level_=None):
Expand Down Expand Up @@ -643,20 +643,17 @@ def solve(self, model_type, solver_name=SOLVER_DEFAULT, solve_external=True, tim
EXAMPLES::
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_trail_search_model import MznXorDifferentialTrailSearchModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.utils import set_fixed_variables, integer_to_bit_list
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=4)
sage: cp = MznXorDifferentialTrailSearchModel(speck)
sage: cp = MznXorDifferentialModel(speck)
sage: fixed_variables = [set_fixed_variables('key', 'equal', list(range(64)), integer_to_bit_list(0, 64, 'little')), set_fixed_variables('plaintext', 'not_equal', list(range(32)), integer_to_bit_list(0, 32, 'little'))]
sage: cp.build_xor_differential_trail_model(-1, fixed_variables)
sage: cp.solve('xor_differential', 'Chuffed') # random
sage: cp.solve('xor_differential', 'chuffed') # random
[{'cipher_id': 'speck_p32_k64_o32_r4',
...
'total_weight': '7'},
{'cipher_id': 'speck_p32_k64_o32_r4',
...
'total_weight': '5'}]
'total_weight': '5.0'}]
"""
truncated = False
if model_type in ['deterministic_truncated_xor_differential',
Expand Down Expand Up @@ -755,9 +752,9 @@ def solve_for_ARX(self, solver_name=None, timeout_in_seconds_=30,
EXAMPLES::
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model_arx_optimized import MznXorDifferentialModelARXOptimized
sage: speck = SpeckBlockCipher(number_of_rounds=5, block_bit_size=32, key_bit_size=64)
sage: minizinc = MznXorDifferentialModel(speck)
sage: minizinc = MznXorDifferentialModelARXOptimized(speck)
sage: bit_positions = [i for i in range(speck.output_bit_size)]
sage: bit_positions_key = list(range(64))
sage: fixed_variables = [{ 'component_id': 'plaintext',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def find_lowest_varied_patterns_bitwise_deterministic_truncated_xor_differential
....: constraint_type='equal',
....: bit_positions=range(64),
....: bit_values=[0]*64)
sage: cp.find_one_deterministic_truncated_xor_differential_trail(1, [plaintext,key], 'Chuffed') # random
sage: cp.find_one_deterministic_truncated_xor_differential_trail(1, [plaintext,key], 'chuffed') # random
[{'cipher_id': 'speck_p32_k64_o32_r1',
'components_values': {'cipher_output_0_6': {'value': '22222222222222212222222222222220',
'weight': 0},
Expand Down Expand Up @@ -248,7 +248,7 @@ def find_all_deterministic_truncated_xor_differential_trails(self, number_of_rou
....: constraint_type='equal',
....: bit_positions=range(64),
....: bit_values=[0]*64)
sage: cp.find_all_deterministic_truncated_xor_differential_trails(3, [plaintext,key], 'Chuffed') # random
sage: cp.find_all_deterministic_truncated_xor_differential_trails(3, [plaintext,key], 'chuffed') # random
[{'cipher_id': 'speck_p32_k64_o32_r3',
'components_values': {'cipher_output_2_12': {'value': '22222222222222202222222222222222',
'weight': 0},
Expand Down Expand Up @@ -300,7 +300,7 @@ def find_one_deterministic_truncated_xor_differential_trail(self, number_of_roun
....: constraint_type='equal',
....: bit_positions=range(64),
....: bit_values=[0]*64)
sage: cp.find_one_deterministic_truncated_xor_differential_trail(1, [plaintext,key], 'Chuffed') # random
sage: cp.find_one_deterministic_truncated_xor_differential_trail(1, [plaintext,key], 'chuffed') # random
[{'cipher_id': 'speck_p32_k64_o32_r1',
'components_values': {'cipher_output_0_6': {'value': '22222222222222212222222222222220',
'weight': 0},
Expand Down Expand Up @@ -446,177 +446,3 @@ def propagate_deterministically(self, component, wordwise=False):
variables, constraints = component.cp_wordwise_deterministic_truncated_xor_differential_constraints(self)

return variables, constraints

'''
def format_component_value(self, component_id, string):
if f'{component_id}_i' in string:
value = string.replace(f'{component_id}_i', '')
elif f'{component_id}_o' in string:
value = string.replace(f'{component_id}_o', '')
elif f'inverse_{component_id}' in string:
value = string.replace(f'inverse_{component_id}', '')
elif f'{component_id}' in string:
value = string.replace(component_id, '')
value = value.replace('= [', '')
value = value.replace(']', '')
value = value.replace(',', '')
value = value.replace(' ', '')
return value
def parse_solver_information(self, output_to_parse):
memory = -1
time = -1
string_total_weight = []
components_values = {}
number_of_solutions = 1
for string in output_to_parse:
if 'time=' in string:
time_string = string
time = float(time_string.replace("%%%mzn-stat: time=", ""))
elif 'solveTime=' in string:
time_string = string
time = float(time_string.replace("%%%mzn-stat: solveTime=", ""))
elif 'trailMem=' in string:
memory_string = string
memory = float(memory_string.replace("%%%mzn-stat: trailMem=", ""))
elif '----------' in string:
string_total_weight.append("0")
components_values[f'solution{number_of_solutions}'] = {}
number_of_solutions += 1
if number_of_solutions == 1:
components_values = {}
return components_values, memory, time
def _parse_solver_output(self, output_to_parse, model_type):
"""
Parse solver solution (if needed).
INPUT:
- ``output_to_parse`` -- **list**; strings that represents the solver output
- ``truncated`` -- **boolean** (default: `False`)
EXAMPLES::
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.utils import set_fixed_variables, integer_to_bit_list, write_model_to_file
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=4)
sage: cp = CpXorDifferentialModel(speck)
sage: fixed_variables = [set_fixed_variables('key', 'equal', range(64), integer_to_bit_list(0, 64, 'little'))]
sage: fixed_variables.append(set_fixed_variables('plaintext', 'equal', range(32), integer_to_bit_list(0, 32, 'little')))
sage: cp.build_xor_differential_trail_model(-1, fixed_variables)
sage: write_model_to_file(cp._model_constraints,'doctesting_file.mzn')
sage: command = ['minizinc', '--solver-statistics', '--solver', 'Chuffed', 'doctesting_file.mzn']
sage: import subprocess
sage: solver_process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
sage: os.remove('doctesting_file.mzn')
sage: solver_output = solver_process.stdout.splitlines()
sage: cp._parse_solver_output(solver_output) # random
(0.018,
...
'cipher_output_3_12': {'value': '0', 'weight': 0}}},
['0'])
"""
components_values, memory, time = self.parse_solver_information(output_to_parse)
all_components = [*self._cipher.inputs, *self._cipher.get_all_components_ids()]
for component_id in all_components:
solution_number = 1
for j, string in enumerate(output_to_parse):
if f'{component_id}' in string or f'{component_id}_i' in string or f'{component_id}_o' in string or f'inverse_{component_id}' in string:
value = self.format_component_value(component_id, string)
component_solution = {}
component_solution['value'] = value
self.add_solution_to_components_values(component_id, component_solution, components_values, j,
output_to_parse, solution_number, string)
elif '----------' in string:
solution_number += 1
if 'impossible' in model_type and solution_number > 1:
for nsol in components_values.keys():
components_values[nsol] = self.extract_incompatibilities_from_output(components_values[nsol])
return time, memory, components_values
def solve(self, model_type, solver_name=SOLVER_DEFAULT, num_of_processors=None, timelimit=None):
"""
Return the solution of the model.
INPUT:
- ``model_type`` -- **string**; the model to solve:
* 'cipher'
* 'xor_differential'
* 'xor_differential_one_solution'
* 'xor_linear'
* 'xor_linear_one_solution'
* 'deterministic_truncated_xor_differential'
* 'deterministic_truncated_xor_differential_one_solution'
* 'impossible_xor_differential'
- ``solver_name`` -- **string** (default: `None`); the name of the solver. Available values are:
* ``'Chuffed'``
* ``'Gecode'``
* ``'COIN-BC'``
- ``num_of_processors`` -- **integer**; the number of processors to be used
- ``timelimit`` -- **integer**; time limit to output a result
EXAMPLES::
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model import MznXorDifferentialModel
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.utils import set_fixed_variables, integer_to_bit_list
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=4)
sage: cp = CpXorDifferentialModel(speck)
sage: fixed_variables = [set_fixed_variables('key', 'equal', list(range(64)), integer_to_bit_list(0, 64, 'little')), set_fixed_variables('plaintext', 'not_equal', list(range(32)), integer_to_bit_list(0, 32, 'little'))]
sage: cp.build_xor_differential_trail_model(-1, fixed_variables)
sage: cp.solve('xor_differential', 'Chuffed') # random
[{'cipher_id': 'speck_p32_k64_o32_r4',
...
'total_weight': '7'},
{'cipher_id': 'speck_p32_k64_o32_r4',
...
'total_weight': '5'}]
"""
cipher_name = self.cipher_id
input_file_path = f'{MODEL_DEFAULT_PATH}/{cipher_name}_Mzn_{model_type}_{solver_name}.mzn'
command = self.get_command_for_solver_process(
input_file_path, model_type, solver_name, num_of_processors, timelimit
)
solver_process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
os.remove(input_file_path)
if solver_process.returncode >= 0:
solutions = []
solver_output = solver_process.stdout.splitlines()
if model_type in ['deterministic_truncated_xor_differential',
'deterministic_truncated_xor_differential_one_solution',
'impossible_xor_differential',
'impossible_xor_differential_one_solution']:
solve_time, memory, components_values = self._parse_solver_output(solver_output, model_type)
total_weight = 0
else:
solve_time, memory, components_values, total_weight = self._parse_solver_output(solver_output, model_type)
if components_values == {}:
solution = convert_solver_solution_to_dictionary(self.cipher_id, model_type, solver_name,
solve_time, memory,
components_values, total_weight)
if 'UNSATISFIABLE' in solver_output[0]:
solution['status'] = 'UNSATISFIABLE'
else:
solution['status'] = 'SATISFIABLE'
solutions.append(solution)
else:
self.add_solutions_from_components_values(components_values, memory, model_type, solutions, solve_time,
solver_name, solver_output)
if model_type in ['xor_differential_one_solution',
'xor_linear_one_solution',
'deterministic_truncated_one_solution',
'impossible_xor_differential_one_solution']:
return solutions[0]
else:
return solutions
'''
Loading

0 comments on commit 46df364

Please sign in to comment.