summaryrefslogtreecommitdiff
path: root/src/add_python/lilliput/tbc.py
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@gmail.com>2019-03-24 15:19:15 +0100
committerKévin Le Gouguec <kevin.legouguec@gmail.com>2019-03-24 16:10:51 +0100
commit33c615feaaf148c099ee4299ad2c8a6f7e1778cf (patch)
tree4db814ee709a9ab2800e56bdac9b12cbc0cf2f26 /src/add_python/lilliput/tbc.py
parent1b6e1eb38927633292e934ac314b10e7acc28e3d (diff)
downloadlilliput-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.py98
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])