diff options
| author | Kévin Le Gouguec <kevin.legouguec@gmail.com> | 2019-03-24 15:19:15 +0100 |
|---|---|---|
| committer | Kévin Le Gouguec <kevin.legouguec@gmail.com> | 2019-03-24 16:10:51 +0100 |
| commit | 33c615feaaf148c099ee4299ad2c8a6f7e1778cf (patch) | |
| tree | 4db814ee709a9ab2800e56bdac9b12cbc0cf2f26 /src/add_python/lilliput/tbc.py | |
| parent | 1b6e1eb38927633292e934ac314b10e7acc28e3d (diff) | |
| download | lilliput-ae-implem-33c615feaaf148c099ee4299ad2c8a6f7e1778cf.tar.xz | |
[implem-python] Réécriture de certains range() dans tbc.py
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.
Diffstat (limited to 'src/add_python/lilliput/tbc.py')
| -rw-r--r-- | src/add_python/lilliput/tbc.py | 98 |
1 files changed, 32 insertions, 66 deletions
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]) |
