From 33c615feaaf148c099ee4299ad2c8a6f7e1778cf Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Sun, 24 Mar 2019 15:19:15 +0100 Subject: [implem-python] Réécriture de certains range() dans tbc.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IME, itérer sur un range() est rarement la façon la plus expressive de faire les choses ; les alternatives imposent une structure qui rendent l'intention plus claire. E.g. quand on voit une compréhension, on comprend que l'auteur cherche à filtrer et/ou transformer ce sur quoi il itère. Réutilisation de xor_state(), renommé xor() puisqu'il sert dans plusieurs situations. Séparation de ce xor() et des fonctions communes aux modes authentifiés pour éviter un import circulaire. --- src/add_python/lilliput/tbc.py | 98 ++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 66 deletions(-) (limited to 'src/add_python/lilliput/tbc.py') diff --git a/src/add_python/lilliput/tbc.py b/src/add_python/lilliput/tbc.py index c607e45..0772853 100644 --- a/src/add_python/lilliput/tbc.py +++ b/src/add_python/lilliput/tbc.py @@ -18,6 +18,7 @@ This module provides functions to encrypt and decrypt blocks of 128 bits. """ from .constants import BLOCK_BYTES, SBOX +from .helpers import xor from .multiplications import ALPHAS @@ -25,6 +26,13 @@ _PERMUTATION = [14, 11, 12, 10, 8, 9, 13, 15, 3, 1, 4, 5, 6, 0, 2, 7] _PERMUTATION_INV = [13, 9, 14, 8, 10, 11, 12, 15, 4, 5, 3, 1, 2, 6 ,0 ,7] +_ROUNDS = { + 128: 32, + 192: 36, + 256: 42 +} + + def _build_tweakey(tweak, key): return tweak+key @@ -55,8 +63,6 @@ def _subtweakey_extract(tweakey, Ci): def _tweakey_schedule_whole(tweakey, r): - # Store the initial tweakey in TKs[0], and the corresponding round tweakey - # in RTKs[0]. TKs = [tweakey] RTKs = [_subtweakey_extract(TKs[0], 0)] @@ -68,28 +74,21 @@ def _tweakey_schedule_whole(tweakey, r): def _non_linear_layer(state, subtweakey): + variables_xored = xor(state, subtweakey) - variables_xored = [0 for byte in range(0, 8)] - for byte in range(0,8): - variables_xored[byte] = state[byte] ^ subtweakey[byte] - - variables_sboxed = [0 for byte in range(0, 8)] - for byte in range(0, 8): - variables_sboxed[byte] = SBOX[variables_xored[byte]] + variables_sboxed = [ + SBOX[variables_xored[i]] for i in range(8) + ] - state_output = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0,BLOCK_BYTES): - state_output[byte] = state[byte] - for byte in range(0, 8): - state_output[15 - byte] ^= variables_sboxed[byte] + state_output = state + for i in range(8): + state_output[15-i] ^= variables_sboxed[i] return state_output def _linear_layer(state): - state_output = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state_output[byte] = state[byte] + state_output = state for byte in range(1, 8): state_output[15] ^= state[byte] @@ -100,26 +99,16 @@ def _linear_layer(state): return state_output -def _permutation_layer_enc(state): - state_output = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state_output[byte] = state[_PERMUTATION[byte]] - - return state_output - - -def _permutation_layer_dec(state): - state_output = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state_output[byte] = state[_PERMUTATION_INV[byte]] - - return state_output +def _permutation_layer(state, p): + return [ + state[p[i]] for i in range(BLOCK_BYTES) + ] def _one_round_egfn_enc(state, subtweakey): state_non_linear = _non_linear_layer(state, subtweakey) state_linear = _linear_layer(state_non_linear) - state_permutation = _permutation_layer_enc(state_linear) + state_permutation = _permutation_layer(state_linear, _PERMUTATION) return state_permutation @@ -134,57 +123,34 @@ def _last_round_egfn(state, subtweakey): def _one_round_egfn_dec(state, subtweakey): state_non_linear = _non_linear_layer(state, subtweakey) state_linear = _linear_layer(state_non_linear) - state_permutation = _permutation_layer_dec(state_linear) + state_permutation = _permutation_layer(state_linear, _PERMUTATION_INV) return state_permutation -def _rounds(key_bytes): - rounds = { - 128: 32, - 192: 36, - 256: 42 - } - return rounds[key_bytes*8] - - def encrypt(tweak, key, message): - r = _rounds(len(key)) + r = _ROUNDS[8*len(key)] tweakey = _build_tweakey(tweak, key) RTKs = _tweakey_schedule_whole(tweakey, r) - state = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state[byte] = message[byte] - - for i in range(0, r-1): - state_output = _one_round_egfn_enc(state, RTKs[i]) - - for byte in range(0, BLOCK_BYTES): - state[byte] = state_output[byte] + state = message - state_output = _last_round_egfn(state, RTKs[r-1]) + for i in range(r-1): + state = _one_round_egfn_enc(state, RTKs[i]) - return state_output + return _last_round_egfn(state, RTKs[r-1]) def decrypt(tweak, key, cipher): - r = _rounds(len(key)) + r = _ROUNDS[8*len(key)] tweakey = _build_tweakey(tweak, key) RTKs = _tweakey_schedule_whole(tweakey, r) - state = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state[byte] = cipher[byte] - - for i in range(0, r-1): - state_output = _one_round_egfn_dec(state, RTKs[r-i-1]) + state = cipher - for byte in range(0, BLOCK_BYTES): - state[byte] = state_output[byte] + for i in range(r-1): + state = _one_round_egfn_dec(state, RTKs[r-i-1]) - state_output = _last_round_egfn(state, RTKs[0]) - - return state_output + return _last_round_egfn(state, RTKs[0]) -- cgit v1.2.3