Sha2 hash function

This module has been coded following the original RFC 6234. Every variable name has been chosen to strictly adhere to the RFC.

The input is named key because the hash functions in the SHA-2 family can be seen like a symmetric cipher whose plaintext is the initial state and key is the input.

class SHA2HashFunction(output_bit_size=256, number_of_rounds=64)

Bases: Cipher

Returns a cipher object of SHA-224, SHA-256, SHA-384 or SHA-512.

Warning

This cipher handles just the Graph Representation of 1 block input.

INPUT:

  • output_bit_sizeinteger (default: 256); size of the cipher output, must be equal to 224, 256, 384, 512

  • number_of_roundsinteger (default: 64); the number of rounds

EXAMPLES:

sage: from claasp.ciphers.hash_functions.sha2_hash_function import SHA2HashFunction
sage: sha2 = SHA2HashFunction()
sage: sha2.print_cipher_structure_as_python_dictionary_to_file(  # doctest: +SKIP
....: "claasp/graph_representations/hash_functions/sha256")  # doctest: +SKIP

sage: from claasp.ciphers.hash_functions.sha2_hash_function import SHA2HashFunction
sage: sha2 = SHA2HashFunction()
sage: message = 0x43686961726180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030
sage: digest = 0x0d8d2647a12b0d544989a6b03603b8b3c27e2c4e0be08671745366d1a8bc4d95
sage: sha2.evaluate([message]) == digest
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_and_component_sha2(component_0, component_1)
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_modadd_component_sha2(component_0, component_1)
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_rotate_component_sha2(component, amount)
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_round_output_component_sha2(a, b, c, d, e, f, g, h)
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)
add_xor_component_sha2(component_0, component_1)
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)
compute_bsig0_bsig1(component_0, component_1)
compute_ch(x, y, z)
compute_maj(x, y, z)
compute_ssig0_ssig1(W, t)
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()
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)
round_function(a, b, c, d, e, f, g, h, Kt, W)
property rounds
property rounds_as_list
schedule(W, t)
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