Twofish block cipher

class TwofishBlockCipher(key_length=128, number_of_rounds=16)

Bases: Cipher

Construct an instance of the TwofishBlockCipher class.

INPUT:

  • key_lengthinteger (default: 128); length of the cipher master key. Must be an integer between 1 and 256 included

  • number_of_roundsinteger (default: 16); number of rounds of the cipher. Must be less or equal than 16

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.twofish_block_cipher import TwofishBlockCipher
sage: cipher = TwofishBlockCipher()
sage: cipher.print_cipher_structure_as_python_dictionary_to_file(  # doctest: +SKIP
....: "claasp/graph_representations/block_ciphers/twofish_key256_r16.py") # doctest: +SKIP

sage: from claasp.ciphers.block_ciphers.twofish_block_cipher import TwofishBlockCipher
sage: cipher = TwofishBlockCipher(key_length=256, number_of_rounds=16)
sage: key = 0xD43BB7556EA32E46F2A282B7D45B4E0D57FF739D4DC92C1BD7FC01700CC8216F
sage: plaintext = 0x90AFE91BB288544F2C32DC239B2635E6
sage: ciphertext = 0x6CB4561C40BF0A9705931CB6D408E7FA
sage: cipher.evaluate([key, plaintext]) == ciphertext
True
add_AND_component(input_id_links, input_bit_positions, output_bit_size)
add_FSR_component(input_id_links, input_bit_positions, output_bit_size, description)
add_MODADD_component(input_id_links, input_bit_positions, output_bit_size, modulus=None)
add_MODSUB_component(input_id_links, input_bit_positions, output_bit_size, modulus=None)
add_NOT_component(input_id_links, input_bit_positions, output_bit_size)
add_OR_component(input_id_links, input_bit_positions, output_bit_size)
add_SBOX_component(input_id_links, input_bit_positions, output_bit_size, description)
add_SHIFT_component(input_id_links, input_bit_positions, output_bit_size, parameter)
add_XOR_component(input_id_links, input_bit_positions, output_bit_size)
add_cipher_output_component(input_id_links, input_bit_positions, output_bit_size)
add_concatenate_component(input_id_links, input_bit_positions, output_bit_size)
add_constant_component(output_bit_size, value)
add_intermediate_output_component(input_id_links, input_bit_positions, output_bit_size, output_tag)
add_linear_layer_component(input_id_links, input_bit_positions, output_bit_size, description)
add_mix_column_component(input_id_links, input_bit_positions, output_bit_size, mix_column_description)
add_permutation_component(input_id_links, input_bit_positions, output_bit_size, permutation_description)
add_reverse_component(input_id_links, input_bit_positions, output_bit_size)
add_rotate_component(input_id_links, input_bit_positions, output_bit_size, parameter)
add_round()
add_round_key_output_component(input_id_links, input_bit_positions, output_bit_size)
add_round_output_component(input_id_links, input_bit_positions, output_bit_size)
add_shift_rows_component(input_id_links, input_bit_positions, output_bit_size, parameter)
add_sigma_component(input_id_links, input_bit_positions, output_bit_size, rotation_amounts_parameter)
add_suffix_to_components(suffix, component_id_list=None)
add_theta_gaston_component(input_id_links, input_bit_positions, output_bit_size, rotation_amounts_parameter)
add_theta_keccak_component(input_id_links, input_bit_positions, output_bit_size)
add_theta_xoodoo_component(input_id_links, input_bit_positions, output_bit_size)
add_variable_rotate_component(input_id_links, input_bit_positions, output_bit_size, parameter)
add_variable_shift_component(input_id_links, input_bit_positions, output_bit_size, parameter)
add_word_permutation_component(input_id_links, input_bit_positions, output_bit_size, permutation_description, word_size)
as_python_dictionary()
cipher_inverse()

Return the graph representation of the inverse of the cipher under analysis

EXAMPLE:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: key = 0xabcdef01abcdef01
sage: plaintext = 0x01234567
sage: cipher = SpeckBlockCipher(number_of_rounds=2)
sage: ciphertext = cipher.evaluate([plaintext, key])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
True
cipher_partial_inverse(start_round=None, end_round=None, keep_key_schedule=False)

Returns the inverted portion of a cipher.

INPUT:

  • start_roundinteger; initial round number of the partial cipher

  • end_roundinteger; final round number of the partial cipher

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: key = 0xabcdef01abcdef01
sage: plaintext = 0x01234567
sage: speck = SpeckBlockCipher(number_of_rounds=3)
sage: result = speck.evaluate([plaintext, key], intermediate_output=True)
sage: partial_speck = speck.cipher_partial_inverse(1, 2, keep_key_schedule=True)
sage: partial_speck.evaluate([result[0], key]) == result[2]['intermediate_output_0_6'][0]
True
component_from(round_number, index)
convert_to_compound_xor_cipher()
create_networx_graph_from_input_ids()
create_top_and_bottom_subgraphs_from_components_graph(e0_bottom_ids, e1_top_ids)
property current_round
property current_round_number
property current_round_number_of_components
delete_generated_evaluate_c_shared_library()

Delete the file named <id_cipher>_evaluate.c and the corresponding executable.

INPUT:

  • None

EXAMPLES:

ds sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher as fancy

sage: fancy().delete_generated_evaluate_c_shared_library() # doctest: +SKIP

evaluate(cipher_input, intermediate_output=False, verbosity=False)

Return the output of the cipher.

INPUT:

  • cipher_inputlist; block cipher inputs

  • intermediate_outputboolean (default: False); set this flag to True to return a dictionary with each intermediate output

  • verbosityboolean (default: False); set this flag to True to print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.toys.identity_block_cipher import IdentityBlockCipher as identity
sage: identity().evaluate([0x01234567,0x89ABCDEF])
19088743
evaluate_using_c(inputs, intermediate_output=False, verbosity=False)

Return the output of the cipher.

INPUT:

  • inputs

  • intermediate_outputboolean (default: False); Set this flag to True in order to return a dictionary with each intermediate output

  • verbosityboolean (default: False); Set this flag to True in order to print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher as fancy
sage: fancy(number_of_rounds=2).evaluate_using_c([0x012345,0x89ABCD], True) # random
{'round_key_output': [3502917, 73728],
 'round_output': [9834215],
 'cipher_output': [7457252]}
evaluate_vectorized(cipher_input, intermediate_output=False, verbosity=False, evaluate_api=False, bit_based=False)

Return the output of the cipher for multiple inputs.

The inputs are given as a list cipher_input,such that cipher_inputs[0] contains the first input, and cipher_inputs[1] the second. Each of the inputs is given as a numpy ndarray of np.uint8, of shape n*m, where n is the size (in bytes) of the input, and m is the number of samples.

The return is a list of m*n ndarrays (format transposed compared to the input format), where the list is of size 1 if intermediate_output is False, and NUMBER_OF_ROUNDS otherwise.

This function determines automatically if a bit-based evaluation is required, and does the transformation transparently. The inputs and outputs are similar to evaluate_vectorized_byte.

INPUT:

  • cipher_inputlist; block cipher inputs (ndarray of uint8 representing one byte each, n rows, m columns, with m the number of inputs to evaluate)

  • intermediate_outputboolean (default: False)

  • verbosityboolean (default: False); set this flag to True in order to print the input/output of each component

  • evaluate_apiboolean (default: False); if set to True, takes integer inputs (as the evaluate function)

and returns integer inputs; it is expected that cipher.evaluate(x) == cipher.evaluate_vectorized(x, evaluate_api = True) is True. EXAMPLES:

sage: import numpy as np
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: speck = speck(block_bit_size=32, key_bit_size=64, number_of_rounds=22)
sage: K=np.random.randint(256, size=(8,2), dtype=np.uint8)
sage: X=np.random.randint(256, size=(4,2), dtype=np.uint8)
sage: result=speck.evaluate_vectorized([X, K])
sage: K0Lib=int.from_bytes(K[:,0].tobytes(), byteorder='big')
sage: K1Lib=int.from_bytes(K[:,1].tobytes(), byteorder='big')
sage: X0Lib=int.from_bytes(X[:,0].tobytes(), byteorder='big')
sage: X1Lib=int.from_bytes(X[:,1].tobytes(), byteorder='big')
sage: C0Lib=speck.evaluate([X0Lib, K0Lib])
sage: C1Lib=speck.evaluate([X1Lib, K1Lib])
sage: int.from_bytes(result[-1][0].tobytes(), byteorder='big') == C0Lib
True
sage: int.from_bytes(result[-1][1].tobytes(), byteorder='big') == C1Lib
True
evaluate_with_intermediate_outputs_continuous_diffusion_analysis(cipher_input, sbox_precomputations, sbox_precomputations_mix_columns, verbosity=False)

Return the output of the continuous generalized cipher.

INPUT:

  • cipher_inputlist of Decimal; block cipher input message

  • sbox_precomputations dictionary

  • sbox_precomputations_mix_columns dictionary

  • verbosityboolean (default: False); set this flag to True in order to print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: from decimal import *
sage: plaintext_input = [Decimal('1') for i in range(32)]
sage: plaintext_input[10] = Decimal('0.802999073954890452142763024312444031238555908203125')
sage: key_input = [Decimal('-1') for i in range(64)]
sage: cipher_inputs = [plaintext_input, key_input]
sage: output = speck(number_of_rounds=2).evaluate_with_intermediate_outputs_continuous_diffusion_analysis(
....:     cipher_inputs,
....:     {},
....:     {}
....: )
sage: output[0][0] == Decimal('-1.000000000')
True
property family_name
property file_name
find_impossible_property(type, technique='sat', solver='kissat', scenario='single-key')

From [SGLYTQH2017] : Finds impossible differentials or zero-correlation linear approximations (based on type) by fixing the input and output iteratively to all possible Hamming weight 1 value, and asking the solver to find a solution; if none is found, then the propagation is impossible. Return a list of impossible differentials or zero_correlation linear approximations if there are any; otherwise return an empty list INPUT:

  • typestring; {“differential”, “linear”}: the type of property to search for

  • techniquestring; {“sat”, “smt”, “milp”, “cp”}: the technique to use for the search

  • solverstring; the name of the solver to use for the search

generate_bit_based_c_code(intermediate_output=False, verbosity=False)

Return a string containing the C code that defines the self.evaluate() method.

INPUT:

  • intermediate_outputboolean (default: False); set this flag to True in order to return a dictionary with each intermediate output

  • verbosityboolean (default: False); set this flag to True in order to make the code print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher as fancy
sage: s = fancy().generate_bit_based_c_code()
sage: s[:8] == '#include'
True
generate_evaluate_c_code_shared_library(intermediate_output=False, verbosity=False)

Store the C code in a file named <id_cipher>_evaluate.c, and build the corresponding executable.

INPUT:

  • intermediate_outputboolean (default: False); set this flag to True in order to make the C code print a dictionary with each intermediate output

  • verbosityboolean (default: False); set this flag to True in order to make the C code print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher as fancy
sage: fancy().generate_evaluate_c_code_shared_library() # doctest: +SKIP
generate_word_based_c_code(word_size, intermediate_output=False, verbosity=False)

Return a string containing the optimized C code that defines the self.evaluate() method.

INPUT:

  • word_sizeinteger; the size of the word

  • intermediate_outputboolean (default: False); set this flag to True in order to return a dictionary with each intermediate output

  • verbosityboolean (default: False); set this flag to True in order to make the code print the input/output of each component

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: word_based_c_code = speck().generate_word_based_c_code(20)
sage: word_based_c_code[:8] == '#include'
True
get_all_components()
get_all_components_ids()
get_all_inputs_bit_positions()
get_component_from_id(component_id)

Return the component according to the id given as input.

INPUT:

  • id_componentstring; id of a component

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher
sage: fancy = FancyBlockCipher(number_of_rounds=2)
sage: component = fancy.get_component_from_id('sbox_0_0')
sage: component.description
[0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15]
get_components_in_round(round_number)
get_current_component_id()

Use this function to get the current component id.

INPUT:

  • None

EXAMPLES:

sage: from claasp.cipher import Cipher
sage: from claasp.name_mappings import PERMUTATION
sage: cipher = Cipher("cipher_name", PERMUTATION, ["input"], [4], 4)
sage: cipher.add_round()
sage: constant_0_0 = cipher.add_constant_component(4, 0xF)
sage: constant_0_1 = cipher.add_constant_component(4, 0xF)
sage: cipher.add_round()
sage: constant_1_0 = cipher.add_constant_component(4, 0xF)
sage: cipher.get_current_component_id()
'constant_1_0'
get_model(technique, problem)

Returns a model for a given technique and problem.

INPUT:

  • techniquestring ; sat, smt, milp or cp

  • problemstring ; xor_differential, xor_linear, cipher_model (more to be added as more model types are added to the library)

get_number_of_components_in_round(round_number)
get_partial_cipher(start_round=None, end_round=None, keep_key_schedule=True)
get_round_from_component_id(component_id)

Return the round according to the round of the component id given as input.

INPUT:

  • id_componentstring; id of a component

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher
sage: fancy = FancyBlockCipher(number_of_rounds=2)
sage: fancy.get_round_from_component_id('xor_1_14')
1
get_sizes_of_components_by_type()
h_function(X, L, L_bits)
property id

Return a list of impossible differentials if there are any; otherwise return an empty list INPUT:

  • techniquestring; {“sat”, “smt”, “milp”, “cp”}: the technique to use for the search

  • solverstring; the name of the solver to use for the search

  • scenariostring; the type of impossible differentials to search, single-key or related-key

property inputs
property inputs_bit_size
inputs_size_to_dict()
is_algebraically_secure(timeout)

Return True if the cipher is resistant against algebraic attack.

INPUT:

  • timeoutinteger; the timeout for the Grobner basis computation in seconds

is_andrx()

Return True if the cipher is AndRX, False otherwise.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.midori_block_cipher import MidoriBlockCipher
sage: midori = MidoriBlockCipher(number_of_rounds=20)
sage: midori.is_andrx()
False
is_arx()

Return True if the cipher is ARX, False otherwise.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.midori_block_cipher import MidoriBlockCipher
sage: midori = MidoriBlockCipher(number_of_rounds=20)
sage: midori.is_arx()
False
is_power_of_2_word_based()

Return the word size if the cipher is word based (64, 32, 16 or 8 bits), False otherwise.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.xtea_block_cipher import XTeaBlockCipher
sage: XTeaBlockCipher(number_of_rounds=32).is_power_of_2_word_based()
32
sage: from claasp.ciphers.block_ciphers.midori_block_cipher import MidoriBlockCipher
sage: MidoriBlockCipher(number_of_rounds=16).is_power_of_2_word_based()
False
is_shift_arx()

Return True if the cipher is Shift-ARX, False otherwise.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.xtea_block_cipher import XTeaBlockCipher
sage: xtea = XTeaBlockCipher(number_of_rounds=32)
sage: xtea.is_shift_arx()
True
is_spn()

Return True if the cipher is SPN.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.aes_block_cipher import AESBlockCipher
sage: aes = AESBlockCipher(number_of_rounds=2)
sage: aes.is_spn()
True
make_cipher_id()
make_file_name()
property number_of_rounds
property output_bit_size
polynomial_system()

Return a polynomial system for the cipher.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: speck = SpeckBlockCipher(block_bit_size=32, key_bit_size=64, number_of_rounds=1)
sage: speck.polynomial_system()
Polynomial Sequence with 64 Polynomials in 112 Variables
polynomial_system_at_round(r)

Return a polynomial system for the cipher at round r.

INPUT:

  • rinteger; round index

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher
sage: SpeckBlockCipher(number_of_rounds=1).polynomial_system_at_round(0)
Polynomial Sequence with 64 Polynomials in 112 Variables
print()

Print the structure of the cipher into the sage terminal.

INPUT:

  • None

EXAMPLES:

sage: from claasp.cipher import Cipher
sage: from claasp.name_mappings import PERMUTATION
sage: cipher = Cipher("cipher_name", PERMUTATION, ["input"], [32], 32)
sage: cipher.add_round()
sage: constant_0_0 = cipher.add_constant_component(16, 0xAB01)
sage: constant_0_1 = cipher.add_constant_component(16, 0xAB01)
sage: cipher.print()
cipher_id = cipher_name_i32_o32_r1
cipher_type = permutation
cipher_inputs = ['input']
cipher_inputs_bit_size = [32]
cipher_output_bit_size = 32
cipher_number_of_rounds = 1

    # round = 0 - round component = 0
    id = constant_0_0
    type = constant
    input_bit_size = 0
    input_id_link = ['']
    input_bit_positions = [[]]
    output_bit_size = 16
    description = ['0xab01']

    # round = 0 - round component = 1
    id = constant_0_1
    type = constant
    input_bit_size = 0
    input_id_link = ['']
    input_bit_positions = [[]]
    output_bit_size = 16
    description = ['0xab01']
cipher_reference_code = None
print_as_python_dictionary()

Use this function to print the cipher as a python dictionary into the sage terminal.

INPUT:

  • None

EXAMPLES:

sage: from claasp.cipher import Cipher
sage: from claasp.name_mappings import BLOCK_CIPHER, INPUT_KEY, INPUT_PLAINTEXT
sage: cipher = Cipher("cipher_name", BLOCK_CIPHER, [INPUT_KEY, INPUT_PLAINTEXT], [32, 32], 32)
sage: cipher.add_round()
sage: constant_0_0 = cipher.add_constant_component(16, 0xAB01)
sage: constant_0_1 = cipher.add_constant_component(16, 0xAB01)
sage: cipher.print_as_python_dictionary()
cipher = {
'cipher_id': 'cipher_name_k32_p32_o32_r1',
'cipher_type': 'block_cipher',
'cipher_inputs': ['key', 'plaintext'],
'cipher_inputs_bit_size': [32, 32],
'cipher_output_bit_size': 32,
'cipher_number_of_rounds': 1,
'cipher_rounds' : [
  # round 0
  [
  {
    # round = 0 - round component = 0
    'id': 'constant_0_0',
    'type': 'constant',
    'input_bit_size': 0,
    'input_id_link': [''],
    'input_bit_positions': [[]],
    'output_bit_size': 16,
    'description': ['0xab01'],
  },
  {
    # round = 0 - round component = 1
    'id': 'constant_0_1',
    'type': 'constant',
    'input_bit_size': 0,
    'input_id_link': [''],
    'input_bit_positions': [[]],
    'output_bit_size': 16,
    'description': ['0xab01'],
  },
  ],
  ],
'cipher_reference_code': None,
}
print_as_python_dictionary_to_file(file_name='')

Use this function to print the cipher as a python dictionary to a file.

INPUT:

  • file_namestring; a python string representing a valid file name

EXAMPLES:

sage: from claasp.cipher import Cipher
sage: from claasp.name_mappings import BLOCK_CIPHER, INPUT_KEY, INPUT_PLAINTEXT
sage: cipher = Cipher("cipher_name", BLOCK_CIPHER, [INPUT_KEY, INPUT_PLAINTEXT], [32, 32], 32)
sage: cipher.print_as_python_dictionary_to_file("claasp/ciphers/dictionary_example.py")
sage: os.remove("claasp/ciphers/dictionary_example.py")
print_evaluation_python_code(verbosity=False)

Print the python code that implement the evaluation function of the cipher.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.toys.identity_block_cipher import IdentityBlockCipher as identity
sage: identity().print_evaluation_python_code() # random
from copy import copy
from bitstring import BitArray
from claasp.cipher_modules.generic_functions import *

def evaluate(input):
    plaintext_output = copy(BitArray(uint=input[0], length=32))
    key_output = copy(BitArray(uint=input[1], length=32))
    intermediate_output = {}
    intermediate_output['cipher_output'] = []
    intermediate_output['round_key_output'] = []
    components_io = {}
    component_input = BitArray(1)

    # round: 0, component: 0, component_id: concatenate_0_0
    component_input = select_bits(key_output, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
    output_bit_size = 32
    concatenate_0_0_output = component_input
    components_io['concatenate_0_0'] = [component_input.uint, concatenate_0_0_output.uint]

    # round: 0, component: 1, component_id: intermediate_output_0_1
    component_input = select_bits(concatenate_0_0_output, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
    output_bit_size = 32
    intermediate_output_0_1_output = component_input
    intermediate_output['round_key_output'].append(intermediate_output_0_1_output.uint)
    components_io['intermediate_output_0_1'] = [component_input.uint, intermediate_output_0_1_output.uint]

    # round: 0, component: 2, component_id: concatenate_0_2
    component_input = select_bits(plaintext_output, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
    output_bit_size = 32
    concatenate_0_2_output = component_input
    components_io['concatenate_0_2'] = [component_input.uint, concatenate_0_2_output.uint]

    # round: 0, component: 3, component_id: cipher_output_0_3
    component_input = select_bits(concatenate_0_2_output, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
    output_bit_size = 32
    cipher_output_0_3_output = component_input
    intermediate_output['cipher_output'].append(cipher_output_0_3_output.uint)
    cipher_output = cipher_output_0_3_output.uint
    components_io['cipher_output_0_3'] = [component_input.uint, cipher_output_0_3_output.uint]

    return cipher_output, intermediate_output, components_io
print_evaluation_python_code_to_file(file_name)

Use this function to print the python code to a file.

INPUT:

  • file_namestring; name of the output file

EXAMPLES:

sage: from claasp.ciphers.toys.identity_block_cipher import IdentityBlockCipher as identity
sage: identity = identity()
sage: identity.file_name
'identity_block_cipher_p32_k32_o32_r1.py'
sage: identity.print_evaluation_python_code_to_file(identity.id + 'evaluation.py') # doctest: +SKIP
print_input_information()

Print a list of the inputs with their corresponding bit size.

Possible cipher inputs are:
  • plaintext

  • key

  • tweak

  • initialization vector

  • nonce

  • constant

  • etc.

INPUT:

  • None

EXAMPLES:

sage: from claasp.ciphers.toys.fancy_block_cipher import FancyBlockCipher
sage: fancy = FancyBlockCipher()
sage: fancy.print_input_information()
plaintext of bit size 24
key of bit size 24
property reference_code
remove_key_schedule(keep_round_key_injection=True)
remove_round_component(round_id, component)
remove_round_component_from_id(round_id, component_id)
property rounds
property rounds_as_list
set_file_name(file_name)
set_id(cipher_id)
set_inputs(inputs_ids_list, inputs_bit_size_list)
sort_cipher()
test_against_reference_code(number_of_tests=5)

Test the graph representation against its reference implementation (if available) with random inputs.

INPUT:

  • number_of_testsinteger (default: 5); number of tests to execute

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.xtea_block_cipher import XTeaBlockCipher as xtea
sage: xtea(number_of_rounds=32).test_against_reference_code()
True
test_vector_check(list_of_test_vectors_input, list_of_test_vectors_output)

Testing the cipher with list of test vectors input and list of test vectors output.

INPUT:

  • list_of_test_vectors_inputlist; list of input testing vectors

  • list_of_test_vectors_outputlist; list of the expected output of the corresponding input testing vectors. That is, list_of_test_vectors_output[i] = cipher.evaluate(list_of_test_vectors_input[i])

OUTPUT:

  • test_result – output of the testing. True if all the cipher.evaluate(input)=output for every input

test vectors, and False, otherwise.

EXAMPLES:

sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: speck = speck(number_of_rounds=22)
sage: key1 = 0x1918111009080100
sage: plaintext1 = 0x6574694c
sage: ciphertext1 = 0xa86842f2
sage: key2 = 0x1918111009080100
sage: plaintext2 = 0x6574694d
sage: ciphertext2 = 0x2b5f25d6
sage: input_list=[[plaintext1, key1], [plaintext2, key2]]
sage: output_list=[ciphertext1, ciphertext2]
sage: speck.test_vector_check(input_list, output_list)
True
sage: input_list.append([0x11111111, 0x1111111111111111])
sage: output_list.append(0xFFFFFFFF)
sage: speck.test_vector_check(input_list, output_list)
Testing Failed
index: 2
input:  [286331153, 1229782938247303441]
output:  4294967295
False
property type

Return a list of zero_correlation linear approximations if there are any; otherwise return an empty list INPUT:

  • techniquestring; {“sat”, “smt”, “milp”, “cp”}: the technique to use for the search

  • solverstring; the name of the solver to use for the search