Skip to content
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
3 changes: 1 addition & 2 deletions claasp/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
from __future__ import annotations

import ast
from functools import lru_cache
import importlib
import json
import re
import shutil
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path


ABSTRACT_COMPONENT_CLASS_NAMES = frozenset({"MultiInputNonlinearLogicalOperator", "Modular"})
IO_COMPONENT_CLASS_NAMES = frozenset({"CipherOutput", "IntermediateOutput"})
ARX_COMPONENTS = frozenset({"constant", "modadd", "rotate", "xor"})
Expand Down
8 changes: 3 additions & 5 deletions claasp/cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@

import claasp
from claasp import editor
from claasp.cipher_modules import code_generator
from claasp.cipher_modules import tester, evaluator
from claasp.cipher_modules import code_generator, evaluator, tester
from claasp.cipher_modules.inverse_cipher import *
from claasp.cipher_modules.inverse_cipher import _prune_components_outside_round_range
from claasp.cipher_modules.models.algebraic.algebraic_model import AlgebraicModel
from claasp.components.cipher_output_component import CipherOutput
from claasp.compound_xor_differential_cipher import convert_to_compound_xor_cipher
from claasp.rounds import Rounds
from claasp.name_mappings import CIPHER_INVERSE_SUFFIX

from claasp.rounds import Rounds

tii_path = inspect.getfile(claasp)
tii_dir_path = os.path.dirname(tii_path)
Expand Down Expand Up @@ -1523,8 +1521,8 @@ def find_impossible_property(self, type, technique="sat", solver="kissat", scena
- ``solver`` -- **string**; the name of the solver to use for the search
"""
from claasp.cipher_modules.models.utils import (
set_fixed_variables,
integer_to_bit_list,
set_fixed_variables,
)

model = self.get_model(technique, f"xor_{type}")
Expand Down
2 changes: 1 addition & 1 deletion claasp/cipher_modules/algebraic_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def algebraic_tests(self, timeout_in_seconds=60):
nmonomials_up_to_round.append(Fseq.nmonomials())
max_deg_of_equations_up_to_round.append(Fseq.maximal_degree())

from cysignals.alarm import alarm, cancel_alarm, AlarmInterrupt
from cysignals.alarm import AlarmInterrupt, alarm, cancel_alarm
try:
alarm(timeout_in_seconds)
Fseq.groebner_basis()
Expand Down
24 changes: 11 additions & 13 deletions claasp/cipher_modules/avalanche_tests.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@

# ****************************************************************************
# Copyright 2023 Technology Innovation Institute
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# ****************************************************************************


import sys
import math
import numpy as np
from math import log
from claasp.cipher_modules import evaluator
from claasp.name_mappings import INTERMEDIATE_OUTPUT, CIPHER_OUTPUT

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

from claasp.cipher_modules import evaluator
from claasp.name_mappings import CIPHER_OUTPUT, INTERMEDIATE_OUTPUT


class AvalancheTests:
def __init__(self, cipher):
self._cipher = cipher
Expand Down Expand Up @@ -433,8 +434,8 @@ def compute_criterion_from_avalanche_probability_vectors(self, all_avalanche_pro


def _set_vector_entropy(self, criterion, input_diff, input_tag, number_of_occurrence, output_tag, vector):
vector_entropy = [round((-proba * log(proba, 2)) - (1 - proba) *
log(1 - proba, 2), 5) if proba not in [0, 1] else 0 for proba in vector]
vector_entropy = [round((-proba * math.log(proba, 2)) - (1 - proba) *
math.log(1 - proba, 2), 5) if proba not in [0, 1] else 0 for proba in vector]
criterion[input_tag][output_tag][input_diff][number_of_occurrence][
"avalanche_entropy_vectors"] = vector_entropy

Expand Down Expand Up @@ -544,6 +545,3 @@ def generate_3D_plot(self, number_of_samples=100, criterion="avalanche_weight_ve
# plt.show()
print("graph can be plot with the build-in method plot.show()")
return plt



70 changes: 16 additions & 54 deletions claasp/cipher_modules/code_generator.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@

# ****************************************************************************
# Copyright 2023 Technology Innovation Institute
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# ****************************************************************************
Expand All @@ -24,9 +24,19 @@
import claasp
from claasp.cipher_modules.generic_functions_vectorized_byte import get_number_of_bytes_needed_for_bit_size
from claasp.component import free_input
from claasp.name_mappings import (SBOX, LINEAR_LAYER, MIX_COLUMN, WORD_OPERATION, CONSTANT,
PADDING, INTERMEDIATE_OUTPUT, CIPHER_OUTPUT,
FSR, CIPHER_INVERSE_SUFFIX, PERMUTATION_COMPONENT)
from claasp.name_mappings import (
CIPHER_INVERSE_SUFFIX,
CIPHER_OUTPUT,
CONSTANT,
FSR,
INTERMEDIATE_OUTPUT,
LINEAR_LAYER,
MIX_COLUMN,
PADDING,
PERMUTATION_COMPONENT,
SBOX,
WORD_OPERATION,
)

tii_path = inspect.getfile(claasp)
tii_dir_path = os.path.dirname(tii_path)
Expand Down Expand Up @@ -218,54 +228,6 @@ def get_word_operation_component_bit_based_c_code(component, verbosity):

return word_operation_code

def generate_bit_based_vectorized_python_code_string(cipher, store_intermediate_outputs=False,
verbosity=False, convert_output_to_bytes=False):
"""
Return string python code needed to evaluate a cipher using a vectorized implementation bit based oriented.

INPUT:

- ``cipher`` -- **Cipher object**; a cipher instance
- ``store_intermediate_outputs`` -- **boolean** (default: `False`); set this flag to True in order to return a list
with each round output
- ``verbosity`` -- **boolean** (default: `False`); set to True to make the Python code print the input/output of
each component
- ``convert_output_to_bytes`` -- **boolean** (default: `False`)

EXAMPLES::

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: from claasp.cipher_modules import code_generator
sage: speck = SpeckBlockCipher()
sage: string_python_code = code_generator.generate_bit_based_vectorized_python_code_string(speck)
sage: string_python_code.split("\n")[0]
'from claasp.cipher_modules.generic_functions_vectorized_bit import *'
"""
code = ['from claasp.cipher_modules.generic_functions_vectorized_bit import *\n',
'def evaluate(input, store_intermediate_outputs):', ' intermediateOutputs={}']

code.extend([f' {cipher.inputs[i]}=input[{i}]' for i in range(len(cipher.inputs))])
for component in cipher.get_all_components():
params = prepare_input_bit_based_vectorized_python_code_string(component)
component_types_allowed = ['constant', 'linear_layer', 'mix_column', 'permutation',
'sbox', 'cipher_output', 'intermediate_output', 'fsr']
component_descriptions_allowed = ['ROTATE', 'SHIFT', 'SHIFT_BY_VARIABLE_AMOUNT', 'NOT', 'XOR',
'MODADD', 'MODMUL', 'MODSUB', 'OR', 'AND']
if component.type in component_types_allowed or (component.type == 'word_operation' and
component.description[0] in component_descriptions_allowed):
code.extend(component.get_bit_based_vectorized_python_code(params, convert_output_to_bytes))
name = component.id
if True and component.type != 'constant':
code.append(f' bit_vector_print_as_hex_values("{name}_output", {name})')
if store_intermediate_outputs:
code.append(' return intermediateOutputs')
elif CIPHER_INVERSE_SUFFIX in cipher.id:
code.append(' return intermediateOutputs["plaintext"]')
else:
code.append(' return intermediateOutputs["cipher_output"]')

return '\n'.join(code)


def generate_bit_based_vectorized_python_code_string(cipher, store_intermediate_outputs=False,
verbosity=False, convert_output_to_bytes=False):
Expand Down
25 changes: 12 additions & 13 deletions claasp/cipher_modules/component_analysis_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,24 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# ****************************************************************************

import re
import shutil
import subprocess
import tempfile
from itertools import combinations, product
from math import log2, pi
from pathlib import Path

import matplotlib.pyplot as plt
from sage.crypto.sbox import SBox
from sage.matrix.constructor import Matrix, matrix
from sage.matrix.special import identity_matrix
from sage.matrix.constructor import matrix, Matrix
from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing

from claasp.cipher_modules.generic_functions import ROTATE, SHIFT, mix_column_generalized
from claasp.component import linear_layer_to_binary_matrix
from claasp.cipher_modules.generic_functions import SHIFT, ROTATE, mix_column_generalized
from claasp.name_mappings import (
CIPHER_OUTPUT,
CONSTANT,
Expand All @@ -34,16 +43,6 @@
WORD_OPERATION,
)

import matplotlib.pyplot as plt
from math import pi, log2
from itertools import combinations, product
import re
import shutil
import subprocess
import tempfile
from pathlib import Path


BRANCH_NUMBER_NON_EMPTY_MATRIX_MSG = "Branch number requires a non-empty matrix"


Expand Down
16 changes: 12 additions & 4 deletions claasp/cipher_modules/continuous_diffusion_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,18 @@
import numpy as np

from claasp.cipher_modules import evaluator
from claasp.cipher_modules.generic_functions_continuous_diffusion_analysis import (get_sbox_precomputations,
get_mix_column_precomputations)
from claasp.utils.utils import (merging_list_of_lists, aggregate_list_of_dictionary, generate_sample_from_gf_2_n,
group_list_by_key, point_pair, signed_distance)
from claasp.cipher_modules.generic_functions_continuous_diffusion_analysis import (
get_mix_column_precomputations,
get_sbox_precomputations,
)
from claasp.utils.utils import (
aggregate_list_of_dictionary,
generate_sample_from_gf_2_n,
group_list_by_key,
merging_list_of_lists,
point_pair,
signed_distance,
)


class ContinuousDiffusionAnalysis:
Expand Down Expand Up @@ -259,7 +267,7 @@

@staticmethod
def _get_graph_representation_components_by_type(graph_representation, type_name):
cipher_rounds = sum(graph_representation["cipher_rounds"], [])

Check failure on line 270 in claasp/cipher_modules/continuous_diffusion_analysis.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use "itertools.chain.from_iterable()" instead of "sum()" to flatten or concatenate lists.

See more on https://sonarcloud.io/project/issues?id=Crypto-TII_claasp&issues=AZ5E8iWPzymZYXV_TkV-&open=AZ5E8iWPzymZYXV_TkV-&pullRequest=461
components_by_type = list(filter(lambda d: d['type'] in [type_name], cipher_rounds))
return components_by_type

Expand Down
7 changes: 1 addition & 6 deletions claasp/cipher_modules/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,10 @@
# ****************************************************************************


import numpy as np
from subprocess import PIPE, Popen
from types import ModuleType
from subprocess import Popen, PIPE

from claasp.cipher_modules import code_generator
from claasp.cipher_modules.generic_functions_vectorized_byte import (
cipher_inputs_to_evaluate_vectorized_inputs,
evaluate_vectorized_outputs_to_integers,
)


def evaluate(cipher, cipher_input, intermediate_output=False, verbosity=False):
Expand Down
12 changes: 6 additions & 6 deletions claasp/cipher_modules/generic_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@


# using bitstring module to manage bits
from math import log
from copy import copy
from bitstring import BitArray # pip3 install bitstring
from math import log

from bitstring import BitArray # pip3 install bitstring
from sage.crypto.sbox import SBox
from sage.rings.quotient_ring import QuotientRing
from sage.matrix.constructor import matrix, Matrix
from sage.matrix.constructor import Matrix, matrix
from sage.modules.free_module_element import vector
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.quotient_ring import QuotientRing

from claasp.utils.utils import int_to_poly, poly_to_int
from claasp.cipher_modules.models.algebraic.boolean_polynomial_ring import BooleanPolynomialRing
from claasp.utils.utils import int_to_poly, poly_to_int

number_of_inputs_expression = " #in = {}"
input_expression = " in = {}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@

import copy
import math
from decimal import MAX_EMAX, Decimal, getcontext

import numpy as np
from numpy.linalg import multi_dot
from decimal import Decimal, getcontext, MAX_EMAX

from sage.crypto.sbox import SBox
from sage.rings.quotient_ring import QuotientRing
from sage.rings.finite_rings.finite_field_constructor import FiniteField
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.quotient_ring import QuotientRing

from claasp.utils.utils import int_to_poly, poly_to_int

Expand Down
5 changes: 3 additions & 2 deletions claasp/cipher_modules/generic_functions_vectorized_byte.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
# ****************************************************************************


import numpy as np
from functools import reduce
import math
from functools import reduce

import numpy as np

NB = 8 # Number of bits of the representation

Expand Down
2 changes: 1 addition & 1 deletion claasp/cipher_modules/inverse_cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from claasp.cipher_modules.component_analysis_tests import (
binary_matrix_of_linear_component,
get_inverse_matrix_in_integer_representation,
int_to_poly,
)
from claasp.cipher_modules.graph_generator import create_networkx_graph_from_input_ids
from claasp.component import Component
Expand All @@ -17,7 +18,6 @@
modsub_component,
)
from claasp.input import Input
from claasp.cipher_modules.component_analysis_tests import int_to_poly
from claasp.name_mappings import (
CIPHER_INPUT,
CIPHER_OUTPUT,
Expand Down
2 changes: 1 addition & 1 deletion claasp/cipher_modules/models/algebraic/algebraic_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
# ****************************************************************************


from sage.structure.sequence import Sequence
from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing
from sage.structure.sequence import Sequence


class AlgebraicModel:
Expand Down
1 change: 0 additions & 1 deletion claasp/cipher_modules/models/cp/minizinc_utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os


def filter_out_strings_containing_substring(strings_list, substring):
Expand Down
Loading
Loading