Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/cp and minizinc models merging #281

Merged
merged 9 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions claasp/cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,9 @@ def get_model(self, technique, problem):
- ``technique`` -- **string** ; sat, smt, milp or cp
- ``problem`` -- **string** ; xor_differential, xor_linear, cipher_model (more to be added as more model types are added to the library)
"""
if technique == 'cp':
technique = 'mzn'
formalism = 'cp'
if problem == 'xor_differential':
constructor_name = f'{technique[0].capitalize()}{technique[1:]}XorDifferentialModel'
elif problem == "xor_linear":
Expand All @@ -1058,6 +1061,8 @@ def get_model(self, technique, problem):
constructor_name = f'{technique[0].capitalize()}{technique[1:]}CipherModel'

module_name = f'claasp.cipher_modules.models.{technique}.{technique}_models.{technique}_{problem}_model'
if technique == 'mzn':
module_name = f'claasp.cipher_modules.models.{formalism}.{technique}_models.{technique}_{problem}_model'

module = importlib.import_module(module_name)
constructor = getattr(module, constructor_name)
Expand Down
575 changes: 0 additions & 575 deletions claasp/cipher_modules/models/cp/cp_model.py

This file was deleted.

892 changes: 892 additions & 0 deletions claasp/cipher_modules/models/cp/mzn_model.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
from minizinc import Status

from claasp.cipher_modules.graph_generator import split_cipher_graph_into_top_bottom
from claasp.cipher_modules.models.minizinc.utils.mzn_bct_predicates import get_bct_operations
from claasp.cipher_modules.models.minizinc.minizinc_models.minizinc_xor_differential_model import \
MinizincXorDifferentialModel
from claasp.cipher_modules.models.minizinc.utils.utils import group_strings_by_pattern
from claasp.cipher_modules.models.cp.minizinc_utils.mzn_bct_predicates import get_bct_operations
from claasp.cipher_modules.models.cp.mzn_models.mzn_xor_differential_model_arx_optimized import \
MznXorDifferentialModelARXOptimized
from claasp.cipher_modules.models.cp.minizinc_utils.utils import group_strings_by_pattern


class MinizincBoomerangModel(MinizincXorDifferentialModel):
class MznBoomerangModelARXOptimized(MznXorDifferentialModelARXOptimized):
def __init__(self, cipher, top_end_ids, bottom_start_ids, middle_ids, window_size_list=None, sat_or_milp='sat'):
self.top_end_ids = top_end_ids
self.bottom_start_ids = bottom_start_ids
Expand All @@ -51,14 +51,14 @@ def remove_empty_rounds(cipher):
@staticmethod
def reduce_cipher(new_cipher, original_cipher, graph):
for round_number in range(new_cipher.number_of_rounds):
MinizincBoomerangModel.remove_components_not_in_graph(new_cipher, original_cipher, round_number, graph)
MznBoomerangModelARXOptimized.remove_components_not_in_graph(new_cipher, original_cipher, round_number, graph)

@staticmethod
def remove_components_not_in_graph(new_cipher, original_cipher, round_number, graph):
round_object = original_cipher.rounds.round_at(round_number)
for component in round_object.components:
if component.id not in graph.nodes:
MinizincBoomerangModel.remove_component(new_cipher, component)
MznBoomerangModelARXOptimized.remove_component(new_cipher, component)

@staticmethod
def remove_component(new_cipher, component):
Expand Down Expand Up @@ -117,18 +117,18 @@ def create_top_and_bottom_ciphers_from_subgraphs(self):
self.bottom_cipher = self.create_bottom_cipher(self.original_cipher)

def create_bottom_cipher(self, original_cipher):
bottom_cipher = MinizincBoomerangModel.initialize_bottom_cipher(original_cipher)
bottom_cipher = MznBoomerangModelARXOptimized.initialize_bottom_cipher(original_cipher)
self.setup_bottom_cipher_inputs(bottom_cipher, original_cipher)
MinizincBoomerangModel.reduce_cipher(bottom_cipher, original_cipher, self.bottom_graph)
MinizincBoomerangModel.remove_empty_rounds(bottom_cipher)
MinizincBoomerangModel.reset_round_ids(bottom_cipher)
MznBoomerangModelARXOptimized.reduce_cipher(bottom_cipher, original_cipher, self.bottom_graph)
MznBoomerangModelARXOptimized.remove_empty_rounds(bottom_cipher)
MznBoomerangModelARXOptimized.reset_round_ids(bottom_cipher)
return bottom_cipher

def create_top_cipher(self, original_cipher):
top_cipher = deepcopy(original_cipher)
top_cipher._id = f'{original_cipher.id}_top'
MinizincBoomerangModel.reduce_cipher(top_cipher, original_cipher, self.top_graph)
MinizincBoomerangModel.remove_empty_rounds(top_cipher)
MznBoomerangModelARXOptimized.reduce_cipher(top_cipher, original_cipher, self.top_graph)
MznBoomerangModelARXOptimized.remove_empty_rounds(top_cipher)
return top_cipher

@staticmethod
Expand All @@ -150,15 +150,15 @@ def objective_generator(mzn_top_cipher, mzn_bottom_cipher):
return objective_string

def create_boomerang_model(self, fixed_variables_for_top_cipher, fixed_variables_for_bottom_cipher):
self.differential_model_top_cipher = MinizincXorDifferentialModel(
self.differential_model_top_cipher = MznXorDifferentialModelARXOptimized(
self.top_cipher, window_size_list=[0 for _ in range(self.top_cipher.number_of_rounds)],
sat_or_milp='sat', include_word_operations_mzn_file=False
)
self.differential_model_top_cipher.build_xor_differential_trail_model(
-1, fixed_variables_for_top_cipher
)

self.differential_model_bottom_cipher = MinizincXorDifferentialModel(
self.differential_model_bottom_cipher = MznXorDifferentialModelARXOptimized(
self.bottom_cipher, window_size_list=[0 for _ in range(self.bottom_cipher.number_of_rounds)],
sat_or_milp='sat', include_word_operations_mzn_file=False
)
Expand All @@ -172,7 +172,7 @@ def create_boomerang_model(self, fixed_variables_for_top_cipher, fixed_variables
self.differential_model_bottom_cipher.add_constraint_from_str(bct_mzn_model)

self.differential_model_bottom_cipher.extend_model_constraints(
MinizincBoomerangModel.objective_generator(self.differential_model_top_cipher,
MznBoomerangModelARXOptimized.objective_generator(self.differential_model_top_cipher,
self.differential_model_bottom_cipher)
)
self.differential_model_bottom_cipher.extend_model_constraints(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
# ****************************************************************************


from claasp.cipher_modules.models.cp.cp_model import CpModel, solve_satisfy
from claasp.cipher_modules.models.cp.mzn_model import MznModel, solve_satisfy
from claasp.name_mappings import (CIPHER_OUTPUT, INTERMEDIATE_OUTPUT, MIX_COLUMN, LINEAR_LAYER, WORD_OPERATION,
CONSTANT, SBOX)


class CpCipherModel(CpModel):
class MznCipherModel(MznModel):

def __init__(self, cipher):
super().__init__(cipher)
Expand Down Expand Up @@ -50,11 +50,11 @@ def build_cipher_model(self, fixed_variables=[], second=False):

EXAMPLES::

sage: from claasp.cipher_modules.models.cp.cp_models.cp_cipher_model import CpCipherModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_cipher_model import MznCipherModel
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 = CpCipherModel(speck)
sage: cp = MznCipherModel(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_cipher_model(fixed_variables)
Expand Down Expand Up @@ -105,9 +105,9 @@ def final_constraints(self):
EXAMPLES::

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.cp.cp_models.cp_cipher_model import CpCipherModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_cipher_model import MznCipherModel
sage: speck = SpeckBlockCipher()
sage: cp = CpCipherModel(speck)
sage: cp = MznCipherModel(speck)
sage: cp.final_constraints()[:-1]
['solve satisfy;']
"""
Expand Down Expand Up @@ -135,9 +135,9 @@ def input_constraints(self):
EXAMPLES::

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.cp.cp_models.cp_cipher_model import CpCipherModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_cipher_model import MznCipherModel
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=4)
sage: cp = CpCipherModel(speck)
sage: cp = MznCipherModel(speck)
sage: cp.input_constraints()
['array[0..31] of var 0..1: plaintext;',
...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
# ****************************************************************************


from claasp.cipher_modules.models.minizinc.minizinc_model import MinizincModel
from claasp.cipher_modules.models.cp.mzn_model import MznModel
from claasp.name_mappings import CIPHER_OUTPUT, INTERMEDIATE_OUTPUT, WORD_OPERATION


class MinizincCipherModel(MinizincModel):
class MznCipherModelARXOptimized(MznModel):

def __init__(self, cipher, window_size_list=None, probability_weight_per_round=None, sat_or_milp='sat'):
super().__init__(cipher, window_size_list, probability_weight_per_round, sat_or_milp)
Expand All @@ -41,15 +41,15 @@ def build_cipher_model(self, fixed_variables=[]):
EXAMPLES::

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules.models.minizinc.minizinc_models.minizinc_cipher_model import MinizincCipherModel
sage: from claasp.cipher_modules.models.cp.mzn_models.mzn_cipher_model_arx_optimized import MznCipherModelARXOptimized
sage: speck = SpeckBlockCipher(number_of_rounds=22)
sage: minizinc = MinizincCipherModel(speck)
sage: minizinc = MznCipherModelARXOptimized(speck)
sage: minizinc.build_cipher_model()
...
"""
self._variables_list = []
variables = []
constraints = self.fix_variables_value_constraints(fixed_variables)
constraints = self.fix_variables_value_constraints_for_ARX(fixed_variables)
self._model_constraints = constraints
component_types = [CIPHER_OUTPUT, INTERMEDIATE_OUTPUT, WORD_OPERATION]
operation_types = ['ROTATE', 'SHIFT', 'XOR']
Expand Down
Loading
Loading