Skip to content

Commit

Permalink
Merge branch 'develop' into extend_milp_impossible_trail_search_to_un…
Browse files Browse the repository at this point in the history
…specificed_component_level
  • Loading branch information
p-huynh committed Jan 10, 2024
2 parents 5c9776c + 9cee1cd commit bf61f03
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 45 deletions.
6 changes: 0 additions & 6 deletions claasp/cipher_modules/code_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ def generate_bit_based_vectorized_python_code_string(cipher, store_intermediate_

code.extend([f' {cipher.inputs[i]}=input[{i}]' for i in range(len(cipher.inputs))])
for component in cipher.get_all_components():
start = time.time()
params = prepare_input_bit_based_vectorized_python_code_string(component)
component_types_allowed = ['constant', 'linear_layer', 'concatenate', 'mix_column',
'sbox', 'cipher_output', 'intermediate_output', 'fsr']
Expand All @@ -260,8 +259,6 @@ def generate_bit_based_vectorized_python_code_string(cipher, store_intermediate_
name = component.id
if verbosity and component.type != 'constant':
code.append(f' bit_vector_print_as_hex_values("{name}_output", {name})')
end=time.time()
print(f'{component.id} time = {end-start}')
if store_intermediate_outputs:
code.append(' return intermediateOutputs')
elif CIPHER_INVERSE_SUFFIX in cipher.id:
Expand Down Expand Up @@ -319,7 +316,6 @@ def generate_byte_based_vectorized_python_code_string(cipher, store_intermediate
code.append(f' {cipher.inputs[i]}=input[{i}]')
bit_sizes[cipher.inputs[i]] = cipher.inputs_bit_size[i]
for component in cipher.get_all_components():
start = time.time()
params = prepare_input_byte_based_vectorized_python_code_string(bit_sizes, component)
bit_sizes[component.id] = component.output_bit_size
component_types_allowed = ['constant', 'linear_layer', 'concatenate', 'mix_column',
Expand All @@ -335,8 +331,6 @@ def generate_byte_based_vectorized_python_code_string(cipher, store_intermediate
if verbosity and component.type != 'constant':
code.append(f' byte_vector_print_as_hex_values("{name}_input", {params})')
code.append(f' byte_vector_print_as_hex_values("{name}_output", {name})')
end=time.time()
print(f'{component.id} time = {end-start}')
if store_intermediate_outputs:
code.append(' return intermediateOutputs')
elif CIPHER_INVERSE_SUFFIX in cipher.id:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,27 +286,9 @@ def add_constraints_to_build_fully_automatic_model_in_sage_milp_class(self, fixe
backward_components = set(self._backward_cipher.get_all_components()) - set(self._backward_cipher.get_component_from_id(key_flow_id) for key_flow_id in backward_key_flow)

for backward_component in backward_components:
output_bit_size = backward_component.output_bit_size
input_ids, output_ids = backward_component._get_input_output_variables()

if include_all_components:
# for multiple input components such as the XOR, ensures compatibility occurs on the correct branch
inputs_to_be_kept = []
for index, input_id in enumerate(["_".join(i.split("_")[:-1]) for i in set(backward_component.input_id_links)]):
if f'{INPUT_KEY}' not in input_id and [link+MILP_BACKWARD_SUFFIX for link in self._cipher.get_component_from_id(input_id).input_id_links] == [backward_component.id]:
inputs_to_be_kept.extend([_ for _ in input_ids if input_id in _])
backward_vars = [x_class[id] for id in (inputs_to_be_kept or input_ids) if INPUT_KEY not in id]
else:
backward_vars = [x_class[id] for id in output_ids]
forward_vars = [x_class["_".join(id.split("_")[:-2] + [id.split("_")[-1]])] for id in output_ids]
inconsistent_vars = [x[f"{backward_component.id}_inconsistent_{_}"] for _ in range(output_bit_size)]
incompatibility_constraints, inconsistent_vars = milp_utils.generate_incompatiblity_constraints_for_component(self, MILP_BITWISE_IMPOSSIBLE_AUTO, x, x_class, backward_component, include_all_components)
all_inconsistent_vars += inconsistent_vars

for inconsistent_index in range(output_bit_size):
incompatibility_constraint = [forward_vars[inconsistent_index] + backward_vars[inconsistent_index] == 1]
constraints.extend(
milp_utils.milp_if_then(inconsistent_vars[inconsistent_index], incompatibility_constraint,
self._model.get_max(x_class) * 2))
constraints.extend(incompatibility_constraints)

constraints.extend([sum(all_inconsistent_vars) == 1])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,25 +314,10 @@ def add_constraints_to_build_fully_automatic_model_in_sage_milp_class(self, fixe
self._backward_cipher.get_component_from_id(key_flow_id) for key_flow_id in backward_key_flow)

for backward_component in backward_components:
output_size = backward_component.output_bit_size // self.word_size
input_ids, output_ids = backward_component._get_wordwise_input_output_linked_class(self)

if include_all_components:
# for multiple input components such as the XOR, ensures compatibility occurs on the correct branch
inputs_to_be_kept = []
for index, input_id in enumerate(["_".join(i.split("_")[:-1]) for i in set(backward_component.input_id_links)]):
if f'{INPUT_KEY}' not in input_id and [link+MILP_BACKWARD_SUFFIX for link in self._cipher.get_component_from_id(input_id).input_id_links] == [backward_component.id]:
inputs_to_be_kept.extend([_ for _ in input_ids if input_id in _])
backward_vars = [x_class[id] for id in (inputs_to_be_kept or input_ids) if INPUT_KEY not in id]
else:
backward_vars = [x_class[id] for id in output_ids]
forward_vars = [x_class["_".join(id.split("_")[:-4] + id.split("_")[-3:])] for id in output_ids]
inconsistent_vars = [x[f"{backward_component.id}_inconsistent_{_}"] for _ in range(output_size)]
incompatibility_constraints, inconsistent_vars = milp_utils.generate_incompatiblity_constraints_for_component(
self, MILP_WORDWISE_IMPOSSIBLE_AUTO, x, x_class, backward_component, include_all_components)
all_inconsistent_vars += inconsistent_vars

for inconsistent_index in range(output_size):
incompatibility_constraint = [forward_vars[inconsistent_index] + backward_vars[inconsistent_index] <= 2]
constraints.extend(milp_utils.milp_if_then(inconsistent_vars[inconsistent_index], incompatibility_constraint, self._model.get_max(x_class) * 2))
constraints.extend(incompatibility_constraints)

# decryption input is fixed and non-zero
constraints.extend(
Expand Down
47 changes: 47 additions & 0 deletions claasp/cipher_modules/models/milp/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
MILP_WORDWISE_DETERMINISTIC_TRUNCATED, MILP_BACKWARD_SUFFIX, MILP_TRUNCATED_XOR_DIFFERENTIAL_OBJECTIVE, \
MILP_XOR_DIFFERENTIAL_OBJECTIVE, MILP_BITWISE_IMPOSSIBLE, MILP_WORDWISE_IMPOSSIBLE, MILP_BITWISE_IMPOSSIBLE_AUTO, \
MILP_WORDWISE_IMPOSSIBLE_AUTO
from claasp.name_mappings import INPUT_KEY


### -------------------------External solver parsing methods------------------------- ###
Expand Down Expand Up @@ -683,6 +684,52 @@ def fix_variables_value_deterministic_truncated_xor_differential_constraints(mil

return constraints

def generate_incompatiblity_constraints_for_component(model, model_type, x, x_class, backward_component, include_all_components):

assert model_type in [MILP_BITWISE_IMPOSSIBLE_AUTO, MILP_WORDWISE_IMPOSSIBLE_AUTO]

incompatiblity_constraints = []

if model_type == MILP_BITWISE_IMPOSSIBLE_AUTO:
output_size = backward_component.output_bit_size
input_ids, output_ids = backward_component._get_input_output_variables()

else:
output_size = backward_component.output_bit_size // model.word_size
input_ids, output_ids = backward_component._get_wordwise_input_output_linked_class(model)


if include_all_components:
# for multiple input components such as the XOR, ensures compatibility occurs on the correct branch
inputs_to_be_kept = []
for index, input_id in enumerate(["_".join(i.split("_")[:-1]) for i in set(backward_component.input_id_links)]):
if f'{INPUT_KEY}' not in input_id and [link + MILP_BACKWARD_SUFFIX for link in
model._cipher.get_component_from_id(input_id).input_id_links] == [
backward_component.id]:
inputs_to_be_kept.extend([_ for _ in input_ids if input_id in _])
backward_vars = [x_class[id] for id in (inputs_to_be_kept or input_ids) if INPUT_KEY not in id]
else:
backward_vars = [x_class[id] for id in output_ids]

if model_type == MILP_BITWISE_IMPOSSIBLE_AUTO:
forward_vars = [x_class["_".join(id.split("_")[:-2] + [id.split("_")[-1]])] for id in output_ids]
else:
forward_vars = [x_class["_".join(id.split("_")[:-4] + id.split("_")[-3:])] for id in output_ids]

inconsistent_vars = [x[f"{backward_component.id}_inconsistent_{_}"] for _ in range(output_size)]

for inconsistent_index in range(output_size):
if model_type == MILP_BITWISE_IMPOSSIBLE_AUTO:
incompatibility_constraint = [forward_vars[inconsistent_index] + backward_vars[inconsistent_index] == 1]
else:
incompatibility_constraint = [forward_vars[inconsistent_index] + backward_vars[inconsistent_index] <= 2]
incompatiblity_constraints.extend(milp_if_then(inconsistent_vars[inconsistent_index], incompatibility_constraint,
model._model.get_max(x_class) * 2))


return incompatiblity_constraints, inconsistent_vars


### -------------------------Solution parser ------------------------- ###
def _get_component_values_for_impossible_models(model, objective_variables, components_variables):
components_values = {}
Expand Down
2 changes: 1 addition & 1 deletion claasp/cipher_modules/neural_network_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ def train_neural_distinguisher(cipher, data_generator, starting_round, neural_ne
bs = 5000
x, y = data_generator(samples=training_samples, nr=starting_round)
x_eval, y_eval = data_generator(samples=testing_samples, nr=starting_round)
h = neural_network.fit(x, y, epochs=num_epochs, batch_size=bs, validation_data=(x_eval, y_eval))
h = neural_network.fit(x, y, epochs=int(num_epochs), batch_size=bs, validation_data=(x_eval, y_eval))
acc = np.max(h.history["val_acc"])
print(f'Validation accuracy at {starting_round} rounds :{acc}')
return acc
Expand Down

0 comments on commit bf61f03

Please sign in to comment.