Skip to content

Commit

Permalink
Merge pull request #241 from Crypto-TII/feat/doctest-workflow
Browse files Browse the repository at this point in the history
Feat/doctest workflow
  • Loading branch information
peacker authored Jun 12, 2024
2 parents 93b0286 + fc27593 commit 24abf97
Show file tree
Hide file tree
Showing 49 changed files with 755 additions and 568 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/run-doctest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Run doctest

on:
push:
branches:
- '**'
pull_request:
types: [opened, synchronize, reopened, edited]
branches:
- develop
- main

concurrency:
group: run-doctest_${{ github.ref }}
cancel-in-progress: true

jobs:
run-doctest:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: 0

- name: Fix Directory Structure
run: |
mkdir /home/runner/_work/claasp_backup
mv -f /home/runner/_work/claasp/claasp/* /home/runner/_work/claasp_backup
rm -rf /home/runner/_work/claasp/
mkdir /home/runner/_work/claasp
mv -f /home/runner/_work/claasp_backup/* /home/runner/_work/claasp
chmod g+w /home/runner/_work/claasp/ -R
rm -rf /home/runner/_work/claasp_backup
- name: Run test
run: |
cd /home/runner/_work/claasp
make test
86 changes: 16 additions & 70 deletions claasp/cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,15 @@ def cipher_inverse(self):
sage: from claasp.ciphers.block_ciphers.present_block_cipher import PresentBlockCipher
sage: key = 0x98edeafc899338c45fad
sage: plaintext = 0x42c20fd3b586879e
sage: cipher = PresentBlockCipher(number_of_rounds=2)
sage: cipher = PresentBlockCipher(number_of_rounds=1)
sage: ciphertext = cipher.evaluate([plaintext, key])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
True
sage: from claasp.ciphers.permutations.ascon_sbox_sigma_permutation import AsconSboxSigmaPermutation
sage: plaintext = 0
sage: cipher = AsconSboxSigmaPermutation(number_of_rounds=2)
sage: cipher = AsconSboxSigmaPermutation(number_of_rounds=1)
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
Expand Down Expand Up @@ -433,15 +433,15 @@ def cipher_inverse(self):
sage: from claasp.ciphers.permutations.sparkle_permutation import SparklePermutation
sage: plaintext = 0x1234
sage: cipher = SparklePermutation(number_of_steps=2)
sage: cipher = SparklePermutation(number_of_steps=1)
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
True
sage: from claasp.ciphers.permutations.xoodoo_invertible_permutation import XoodooInvertiblePermutation
sage: plaintext = 0x1234
sage: cipher = XoodooInvertiblePermutation(number_of_rounds=2)
sage: cipher = XoodooInvertiblePermutation(number_of_rounds=1)
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
Expand Down Expand Up @@ -484,15 +484,15 @@ def cipher_inverse(self):
True
sage: from claasp.ciphers.permutations.salsa_permutation import SalsaPermutation
sage: cipher = SalsaPermutation(number_of_rounds=5)
sage: cipher = SalsaPermutation(number_of_rounds=2)
sage: plaintext = 0xffff
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
True
sage: from claasp.ciphers.block_ciphers.bea1_block_cipher import BEA1BlockCipher
sage: cipher = BEA1BlockCipher(number_of_rounds=2)
sage: cipher = BEA1BlockCipher(number_of_rounds=1)
sage: key = 0x8cdd0f3459fb721e798655298d5c1
sage: plaintext = 0x47a57eff5d6475a68916
sage: ciphertext = cipher.evaluate([key, plaintext])
Expand All @@ -509,59 +509,13 @@ def cipher_inverse(self):
True
sage: from claasp.ciphers.permutations.chacha_permutation import ChachaPermutation
sage: cipher = ChachaPermutation(number_of_rounds=5)
sage: cipher = ChachaPermutation(number_of_rounds=2)
sage: plaintext = 0xffff
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
True
sage: from claasp.ciphers.permutations.gimli_sbox_permutation import GimliSboxPermutation
sage: cipher = GimliSboxPermutation(number_of_rounds=2, word_size=32)
sage: plaintext = 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
sage: ciphertext = cipher.evaluate([plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext]) == plaintext
False # loop 356
sage: from claasp.ciphers.block_ciphers.sparx_block_cipher import SparxBlockCipher
sage: plaintext = 0x0123456789abcdef
sage: key = 0x00112233445566778899aabbccddeeff
sage: cipher = SparxBlockCipher(number_of_rounds=2)
sage: ciphertext = cipher.evaluate([plaintext, key])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
False # loop 66
sage: from claasp.ciphers.block_ciphers.threefish_block_cipher import ThreefishBlockCipher
sage: cipher = ThreefishBlockCipher(number_of_rounds=2)
sage: plaintext = 0xF8F9FAFBFCFDFEFFF0F1F2F3F4F5F6F7E8E9EAEBECEDEEEFE0E1E2E3E4E5E6E7
sage: key = 0x17161514131211101F1E1D1C1B1A191827262524232221202F2E2D2C2B2A2928
sage: tweak = 0x07060504030201000F0E0D0C0B0A0908
sage: ciphertext = cipher.evaluate([plaintext, key, tweak])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key, tweak]) == plaintext
False # loop 29
sage: from claasp.ciphers.permutations.tinyjambu_permutation import TinyJambuPermutation
sage: cipher = TinyJambuPermutation(number_of_rounds=2)
sage: plaintext = 0xffff
sage: key = 0x1234
sage: ciphertext = cipher.evaluate([key, plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
False # loop 8
sage: from claasp.ciphers.block_ciphers.lowmc_block_cipher import LowMCBlockCipher
sage: cipher = LowMCBlockCipher(block_bit_size=192, key_bit_size=192, number_of_rounds=4)
sage: key = 0x800000000000000000000000000000000000000000000000
sage: plaintext = 0xABFF00000000000000000000000000000000000000000000
sage: ciphertext = cipher.evaluate([key, plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
False # loop 274
sage: from claasp.ciphers.block_ciphers.twofish_block_cipher import TwofishBlockCipher
sage: cipher = TwofishBlockCipher(key_length=256, number_of_rounds=2)
sage: key = 0xD43BB7556EA32E46F2A282B7D45B4E0D57FF739D4DC92C1BD7FC01700CC8216F
Expand All @@ -570,16 +524,6 @@ def cipher_inverse(self):
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
True
sage: from claasp.ciphers.block_ciphers.kasumi_block_cipher import KasumiBlockCipher
sage: cipher = KasumiBlockCipher(number_of_rounds=2)
sage: key = 0x9900aabbccddeeff1122334455667788
sage: plaintext = 0xfedcba0987654321
sage: ciphertext = cipher.evaluate([key, plaintext])
sage: cipher_inv = cipher.cipher_inverse()
sage: cipher_inv.evaluate([ciphertext, key]) == plaintext
False # loop 96
"""
inverted_cipher = Cipher(f"{self.id}{CIPHER_INVERSE_SUFFIX}", f"{self.type}", [], [], self.output_bit_size)

Expand Down Expand Up @@ -727,8 +671,9 @@ def cipher_partial_inverse(self, start_round=None, end_round=None, keep_key_sche
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)
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
"""

Expand Down Expand Up @@ -1406,9 +1351,10 @@ def polynomial_system(self):
EXAMPLES::
sage: from claasp.ciphers.block_ciphers.identity_block_cipher import IdentityBlockCipher
sage: IdentityBlockCipher().polynomial_system()
Polynomial Sequence with 128 Polynomials in 256 Variables
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
"""
algebraic_model = AlgebraicModel(self)
return algebraic_model.polynomial_system()
Expand All @@ -1423,9 +1369,9 @@ def polynomial_system_at_round(self, r):
EXAMPLES::
sage: from claasp.ciphers.block_ciphers.fancy_block_cipher import FancyBlockCipher
sage: FancyBlockCipher(number_of_rounds=1).polynomial_system_at_round(0)
Polynomial Sequence with 252 Polynomials in 288 Variables
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
"""
algebraic_model = AlgebraicModel(self)
return algebraic_model.polynomial_system_at_round(r)
Expand Down
16 changes: 8 additions & 8 deletions claasp/cipher_modules/algebraic_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class AlgebraicTests:
sage: alg_test = AlgebraicTests(toyspn)
sage: alg_test.algebraic_tests(timeout_in_seconds=10)
{'input_parameters': {'cipher': toyspn1_p6_k6_o6_r2,
'timeout_in_seconds': 10,
'test_name': 'algebraic_tests'},
'test_results': {'number_of_variables': [24, 42],
'test_name': 'algebraic_tests',
'timeout_in_seconds': 10},
'test_results': {'max_degree_of_equations': [2, 2],
'number_of_equations': [34, 74],
'number_of_monomials': [54, 102],
'max_degree_of_equations': [2, 2],
'number_of_variables': [24, 42],
'test_passed': [False, False]}}
sage: from claasp.cipher_modules.algebraic_tests import AlgebraicTests
Expand All @@ -46,12 +46,12 @@ class AlgebraicTests:
sage: alg_test = AlgebraicTests(speck)
sage: alg_test.algebraic_tests(timeout_in_seconds=30)
{'input_parameters': {'cipher': speck_p32_k64_o32_r1,
'timeout_in_seconds': 30,
'test_name': 'algebraic_tests'},
'test_results': {'number_of_variables': [112],
'test_name': 'algebraic_tests',
'timeout_in_seconds': 30},
'test_results': {'max_degree_of_equations': [2],
'number_of_equations': [64],
'number_of_monomials': [157],
'max_degree_of_equations': [2],
'number_of_variables': [112],
'test_passed': [True]}}
"""
Expand Down
2 changes: 2 additions & 0 deletions claasp/cipher_modules/avalanche_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,15 @@ def generate_3D_plot(self, number_of_samples=100, criterion="avalanche_weight_ve
sage: cipher = SpeckBlockCipher(block_bit_size=16, key_bit_size=32, number_of_rounds=5)
sage: from claasp.cipher_modules.avalanche_tests import AvalancheTests
sage: plot = AvalancheTests(cipher).generate_3D_plot(number_of_samples=100)
graph can be plot with the build-in method plot.show()
sage: type(plot)
<class 'module'>
sage: from claasp.ciphers.permutations.chacha_permutation import ChachaPermutation
sage: cipher = ChachaPermutation(number_of_rounds=5)
sage: from claasp.cipher_modules.avalanche_tests import AvalancheTests
sage: plot = AvalancheTests(cipher).generate_3D_plot(number_of_samples=100)
graph can be plot with the build-in method plot.show()
sage: type(plot)
<class 'module'>
Expand Down
14 changes: 7 additions & 7 deletions claasp/cipher_modules/component_analysis_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def component_analysis_tests(self):
sage: from claasp.cipher_modules.component_analysis_tests import CipherComponentsAnalysis
sage: fancy = FancyBlockCipher(number_of_rounds=3)
sage: components_analysis = CipherComponentsAnalysis(fancy).component_analysis_tests()
sage: len(components_analysis)
sage: len(components_analysis['test_results'])
9
"""
Expand Down Expand Up @@ -798,7 +798,7 @@ def _fsr_properties(self, operation):
sage: from claasp.ciphers.stream_ciphers.bluetooth_stream_cipher_e0 import BluetoothStreamCipherE0
sage: from claasp.cipher_modules.component_analysis_tests import CipherComponentsAnalysis
sage: e0 = BluetoothStreamCipherE0(keystream_bit_len=2)
sage: dictionary = CipherComponentsAnalysis(e0).component_analysis_tests()
sage: dictionary = CipherComponentsAnalysis(e0).component_analysis_tests()['test_results']
sage: assert dictionary[8]["number_of_registers"] == 4
sage: dictionary[8]["lfsr_connection_polynomials"][0] == 'x^25 + x^20 + x^12 + x^8 + 1' # first lfsr
True
Expand All @@ -807,7 +807,7 @@ def _fsr_properties(self, operation):
sage: from claasp.ciphers.stream_ciphers.trivium_stream_cipher import TriviumStreamCipher
sage: triv = TriviumStreamCipher(keystream_bit_len=1)
sage: dictionary = CipherComponentsAnalysis(triv).component_analysis_tests()
sage: dictionary = CipherComponentsAnalysis(triv).component_analysis_tests()['test_results']
sage: dictionary[0]["type_of_registers"] == ['non-linear', 'non-linear', 'non-linear']
True
Expand Down Expand Up @@ -1030,7 +1030,7 @@ def get_inverse_matrix_in_integer_representation(component):
sage: mix_column_component = midori.get_component_from_id('mix_column_0_20')
sage: m = get_inverse_matrix_in_integer_representation(mix_column_component)
sage: m.dimensions()
(16,16)
(16, 16)
"""
if component.type != MIX_COLUMN:
Expand Down Expand Up @@ -1149,15 +1149,15 @@ def instantiate_matrix_over_correct_field(matrix, polynomial_as_int, word_size,
sage: mix_column_component = midori.get_component_from_id('mix_column_0_20')
sage: description = mix_column_component.description
sage: mc_matrix, _ = instantiate_matrix_over_correct_field(description[0], int(description[1]), int(description[2]),
mix_column_component.input_bit_size, mix_column_component.output_bit_size)
....: mix_column_component.input_bit_size, mix_column_component.output_bit_size)
sage: from claasp.ciphers.block_ciphers.midori_block_cipher import MidoriBlockCipher
sage: from claasp.cipher_modules.component_analysis_tests import instantiate_matrix_over_correct_field
sage: midori = MidoriBlockCipher(number_of_rounds=2)
sage: mix_column_component = midori.get_component_from_id('mix_column_0_21')
sage: description = mix_column_component.description
sage: mc_matrix, _ = instantiate_matrix_over_correct_field(description[0], int(description[1]), int(description[2]),
mix_column_component.input_bit_size, mix_column_component.output_bit_size)
....: mix_column_component.input_bit_size, mix_column_component.output_bit_size)
"""
G = PolynomialRing(GF(2), 'x')
Expand Down Expand Up @@ -1195,7 +1195,7 @@ def field_element_matrix_to_integer_matrix(matrix):
sage: mix_column_component = aes.get_component_from_id('mix_column_1_20')
sage: description = mix_column_component.description
sage: mc_matrix, _ = instantiate_matrix_over_correct_field(description[0], int(description[1]), int(description[2]),
mix_column_component.input_bit_size, mix_column_component.output_bit_size)
....: mix_column_component.input_bit_size, mix_column_component.output_bit_size)
sage: mc_matrix
[ a a + 1 1 1]
[ 1 a a + 1 1]
Expand Down
12 changes: 6 additions & 6 deletions claasp/cipher_modules/continuous_diffusion_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ def continuous_diffusion_factor(self, beta_number_of_samples, gf_number_samples)
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: from claasp.cipher_modules.continuous_diffusion_analysis import ContinuousDiffusionAnalysis
sage: speck_cipher = speck(number_of_rounds=2) # long time
sage: cda = ContinuousDiffusionAnalysis(speck_cipher)
sage: output = cda.continuous_diffusion_factor(5, 20) # long time
sage: output['plaintext']['cipher_output']['diffusion_factor']['values'][0] > 0 # long time
sage: cda = ContinuousDiffusionAnalysis(speck_cipher) # doctest: +SKIP
sage: output = cda.continuous_diffusion_factor(5, 20) # long time # doctest: +SKIP
sage: output['plaintext']['cipher_output']['diffusion_factor']['values'][0] > 0 # long time # doctest: +SKIP
True
"""
output_tags = list(ContinuousDiffusionAnalysis._get_graph_representation_tag_output_sizes(
Expand Down Expand Up @@ -433,9 +433,9 @@ def continuous_diffusion_tests(self,
sage: from claasp.ciphers.block_ciphers.speck_block_cipher import SpeckBlockCipher as speck
sage: from claasp.cipher_modules.continuous_diffusion_analysis import ContinuousDiffusionAnalysis
sage: speck_cipher = speck(number_of_rounds=1) # long time
sage: cda = ContinuousDiffusionAnalysis(speck_cipher)
sage: output = cda.continuous_diffusion_tests() # long time
sage: output["test_results"]['plaintext']['round_key_output']['continuous_neutrality_measure'][0]['values'][0] == 0.0 # long time
sage: cda = ContinuousDiffusionAnalysis(speck_cipher) # doctest: +SKIP
sage: output = cda.continuous_diffusion_tests() # long time # doctest: +SKIP
sage: output["test_results"]['plaintext']['round_key_output']['continuous_neutrality_measure'][0]['values'][0] == 0.0 # long time # doctest: +SKIP
True
"""
continuous_diffusion_tests = {"input_parameters": {
Expand Down
2 changes: 1 addition & 1 deletion claasp/cipher_modules/generic_functions_vectorized_byte.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def get_number_of_consecutive_bits(l):
sage: from claasp.cipher_modules.generic_functions_vectorized_byte import get_number_of_consecutive_bits
sage: L=[4, 3, 5, 7, 2]
sage: get_number_of_consecutive_bits(L) == 2
sage: get_number_of_consecutive_bits(L) == 1
True
"""

Expand Down
Loading

0 comments on commit 24abf97

Please sign in to comment.