From dd934c63386c8fa22a5b0944e0256c435d55938c Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Fri, 22 Mar 2019 10:34:02 +0100 Subject: [implem-python] Renommage du module TBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quand le tout sera packagé sous le namespace "lilliput", le préfixe alourdira plus qu'autre chose. --- python/helpers.py | 6 +- python/lilliput_ae_1.py | 18 ++--- python/lilliput_ae_2.py | 12 ++-- python/lilliput_tbc.py | 178 ------------------------------------------------ python/tbc.py | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 196 deletions(-) delete mode 100644 python/lilliput_tbc.py create mode 100644 python/tbc.py diff --git a/python/helpers.py b/python/helpers.py index be4b406..321b096 100644 --- a/python/helpers.py +++ b/python/helpers.py @@ -1,5 +1,5 @@ from constants import BLOCK_BITS, BLOCK_BYTES -from lilliput_tbc import LilliputTBCEnc +import tbc def ArrayToBlockbytesMatrix(array): @@ -65,7 +65,7 @@ def BuildAuth(t, A, key): for i in range(0, l_a): tweak = _tweakAssociatedData(t, i, padded=False) - enc = LilliputTBCEnc(tweak, key, A[i]) + enc = tbc.encrypt(tweak, key, A[i]) Auth = XorState(Auth, enc) if not need_padding: @@ -73,7 +73,7 @@ def BuildAuth(t, A, key): tweak = _tweakAssociatedData(t, l_a, padded=True) ad_padded = Padding10LSB(A[l_a]) - enc = LilliputTBCEnc(tweak, key, ad_padded) + enc = tbc.encrypt(tweak, key, ad_padded) Auth = XorState(Auth, enc) return Auth diff --git a/python/lilliput_ae_1.py b/python/lilliput_ae_1.py index 5cc263b..8064871 100644 --- a/python/lilliput_ae_1.py +++ b/python/lilliput_ae_1.py @@ -4,7 +4,6 @@ from enum import Enum -import lilliput_tbc as ltbc from constants import BLOCK_BYTES, NONCE_BYTES from helpers import ( ArrayToBlockbytesMatrix, @@ -14,6 +13,7 @@ from helpers import ( TagValidationError, XorState ) +import tbc TWEAK_BITS = 192 @@ -78,22 +78,22 @@ def TreatMessageEnc(M, N, key): for j in range(0, l): checksum = XorState(checksum, M[j]) tweak = TweakMessage(N, j, _MessageTweak.BLOCK) - C.append(ltbc.LilliputTBCEnc(tweak, key, M[j])) + C.append(tbc.encrypt(tweak, key, M[j])) if padding_bytes == 0: tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING) - Final = ltbc.LilliputTBCEnc(tweak, key, checksum) + Final = tbc.encrypt(tweak, key, checksum) else: m_padded = Padding10LSB(M[l]) checksum = XorState(checksum, m_padded) tweak = TweakMessage(N, l, _MessageTweak.PAD) - pad = ltbc.LilliputTBCEnc(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) + pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) lower_part = LowPart(pad, padding_bytes*8) C.append(XorState(M[l], lower_part)) tweak_final = TweakMessage(N, l+1, _MessageTweak.FINAL) - Final = ltbc.LilliputTBCEnc(tweak_final, key, checksum) + Final = tbc.encrypt(tweak_final, key, checksum) return (Final, C) @@ -109,23 +109,23 @@ def TreatMessageDec(C, N, key): for j in range(0, l): tweak = TweakMessage(N, j, _MessageTweak.BLOCK) - M.append(ltbc.LilliputTBCDec(tweak, key, C[j])) + M.append(tbc.decrypt(tweak, key, C[j])) checksum = XorState(checksum, M[j]) if padding_bytes == 0: tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING) - Final = ltbc.LilliputTBCEnc(tweak, key, checksum) + Final = tbc.encrypt(tweak, key, checksum) else: tweak = TweakMessage(N, l, _MessageTweak.PAD) - pad = ltbc.LilliputTBCEnc(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) + pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) lower_part = LowPart(pad, padding_bytes*8) M.append(XorState(C[l], lower_part)) m_padded = Padding10LSB(M[l]) checksum = XorState(checksum, m_padded) tweak_final = TweakMessage(N, l+1, _MessageTweak.FINAL) - Final = ltbc.LilliputTBCEnc(tweak_final, key, checksum) + Final = tbc.encrypt(tweak_final, key, checksum) return (Final, M) diff --git a/python/lilliput_ae_2.py b/python/lilliput_ae_2.py index 2e7843b..3c0aa2a 100644 --- a/python/lilliput_ae_2.py +++ b/python/lilliput_ae_2.py @@ -2,7 +2,6 @@ SCT 2 for lilliput ae 2 """ -import lilliput_tbc as ltbc from constants import BLOCK_BYTES from helpers import ( ArrayToBlockbytesMatrix, @@ -12,6 +11,7 @@ from helpers import ( TagValidationError, XorState ) +import tbc TWEAK_BITS = 128 @@ -62,17 +62,17 @@ def MesssageAuthTag(M, N, Auth, key): for j in range(0, l): tweak = TweakTag(j, False) - encryption = ltbc.LilliputTBCEnc(tweak, key, M[j]) + encryption = tbc.encrypt(tweak, key, M[j]) tag = XorState(tag, encryption) if need_padding: tweak = TweakTag(l, True) m_padded = Padding10LSB(M[l]) - encryption = ltbc.LilliputTBCEnc(tweak, key, m_padded) + encryption = tbc.encrypt(tweak, key, m_padded) tag = XorState(tag, encryption) tweak = TweakTagEnd(N) - encryption = ltbc.LilliputTBCEnc(tweak, key, tag) + encryption = tbc.encrypt(tweak, key, tag) tag = encryption return tag @@ -88,13 +88,13 @@ def MessageEncryption(M, N, tag, key): for j in range(0, l): tweak = AddTagJ(tag, j) padded_nonce = list(N) + [0x00] - encryption = ltbc.LilliputTBCEnc(tweak, key, padded_nonce) + encryption = tbc.encrypt(tweak, key, padded_nonce) C.append(XorState(M[j], encryption)) if need_padding: tweak = AddTagJ(tag, l) padded_nonce = list(N) + [0x00] - encryption = ltbc.LilliputTBCEnc(tweak, key, padded_nonce) + encryption = tbc.encrypt(tweak, key, padded_nonce) C.append(XorState(M[l], encryption)) return C diff --git a/python/lilliput_tbc.py b/python/lilliput_tbc.py deleted file mode 100644 index 9dc7df2..0000000 --- a/python/lilliput_tbc.py +++ /dev/null @@ -1,178 +0,0 @@ -""" - Lilliput TBC -""" -from constants import BLOCK_BYTES, Sbox -from multiplications import ALPHAS - - -permutation = [14, 11, 12, 10, 8, 9, 13, 15, 3, 1, 4, 5, 6, 0, 2, 7] -permutationInv = [13, 9, 14, 8, 10, 11, 12, 15, 4, 5, 3, 1, 2, 6 ,0 ,7] - -################################################################################ - -def BuildTweakey(tweak, key): - return tweak+key - -############################# - -def _lane(TK, j): - return TK[j*8:(j+1)*8] - -def RoundTweakeySchedule(tweakey): - p = len(tweakey)//8 - - multiplied_lanes = ( - ALPHAS[j](_lane(tweakey, j)) for j in range(p) - ) - - return [byte for lane in multiplied_lanes for byte in lane] - - -def SubTweakeyExtract(tweakey, Ci): - RTKi = [0]*8 - - for j, byte in enumerate(tweakey): - RTKi[j%8] ^= byte - - RTKi[0] ^= Ci - - return RTKi - - -def TweakeyScheduleWhole(tweakey, r): - # store main tweakey in TKs[0] - # and corresponding round tweakey in RTKs[0] - TKs = [tweakey] - RTKs = [SubTweakeyExtract(TKs[0], 0)] - - for i in range(1, r): - TKs.append(RoundTweakeySchedule(TKs[i-1])) - RTKs.append(SubTweakeyExtract(TKs[i], i)) - - return RTKs - - -################################################################################ - -def NonLinearLayer(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]] - - 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] - - return state_output - - -def LinearLayer(state): - 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(1, 8): - state_output[15] ^= state[byte] - - for byte in range(9, 15): - state_output[byte] ^= state[7] - - return state_output - - -def PermutationLayerEnc(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 PermutationLayerDec(state): - state_output = [0 for byte in range(0, BLOCK_BYTES)] - for byte in range(0, BLOCK_BYTES): - state_output[byte] = state[permutationInv[byte]] - - return state_output - - -def OneRoundEGFNEnc(state, subtweakey): - state_non_linear = NonLinearLayer(state, subtweakey) - state_linear = LinearLayer(state_non_linear) - state_permutation = PermutationLayerEnc(state_linear) - - return state_permutation - -def LastRoundEGFN(state, subtweakey): - state_non_linear = NonLinearLayer(state, subtweakey) - state_linear = LinearLayer(state_non_linear) - - return state_linear - - -def OneRoundEGFNDec(state, subtweakey): - state_non_linear = NonLinearLayer(state, subtweakey) - state_linear = LinearLayer(state_non_linear) - state_permutation = PermutationLayerDec(state_linear) - - return state_permutation - - -def _rounds(key_bytes): - rounds = { - 128: 32, - 192: 36, - 256: 42 - } - return rounds[key_bytes*8] - - -################################################################################ -# Lilliput TBC - -def LilliputTBCEnc(tweak, key, message): - r = _rounds(len(key)) - - tweakey = BuildTweakey(tweak, key) - RTKs = TweakeyScheduleWhole(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 = OneRoundEGFNEnc(state, RTKs[i]) - - for byte in range(0, BLOCK_BYTES): - state[byte] = state_output[byte] - - state_output = LastRoundEGFN(state, RTKs[r-1]) - - return state_output - - -def LilliputTBCDec(tweak, key, cipher): - r = _rounds(len(key)) - - tweakey = BuildTweakey(tweak, key) - RTKs = TweakeyScheduleWhole(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 = OneRoundEGFNDec(state, RTKs[r-i-1]) - - for byte in range(0, BLOCK_BYTES): - state[byte] = state_output[byte] - - state_output = LastRoundEGFN(state, RTKs[0]) - - return state_output diff --git a/python/tbc.py b/python/tbc.py new file mode 100644 index 0000000..ca51649 --- /dev/null +++ b/python/tbc.py @@ -0,0 +1,178 @@ +""" + Lilliput TBC +""" +from constants import BLOCK_BYTES, Sbox +from multiplications import ALPHAS + + +permutation = [14, 11, 12, 10, 8, 9, 13, 15, 3, 1, 4, 5, 6, 0, 2, 7] +permutationInv = [13, 9, 14, 8, 10, 11, 12, 15, 4, 5, 3, 1, 2, 6 ,0 ,7] + +################################################################################ + +def BuildTweakey(tweak, key): + return tweak+key + +############################# + +def _lane(TK, j): + return TK[j*8:(j+1)*8] + +def RoundTweakeySchedule(tweakey): + p = len(tweakey)//8 + + multiplied_lanes = ( + ALPHAS[j](_lane(tweakey, j)) for j in range(p) + ) + + return [byte for lane in multiplied_lanes for byte in lane] + + +def SubTweakeyExtract(tweakey, Ci): + RTKi = [0]*8 + + for j, byte in enumerate(tweakey): + RTKi[j%8] ^= byte + + RTKi[0] ^= Ci + + return RTKi + + +def TweakeyScheduleWhole(tweakey, r): + # store main tweakey in TKs[0] + # and corresponding round tweakey in RTKs[0] + TKs = [tweakey] + RTKs = [SubTweakeyExtract(TKs[0], 0)] + + for i in range(1, r): + TKs.append(RoundTweakeySchedule(TKs[i-1])) + RTKs.append(SubTweakeyExtract(TKs[i], i)) + + return RTKs + + +################################################################################ + +def NonLinearLayer(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]] + + 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] + + return state_output + + +def LinearLayer(state): + 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(1, 8): + state_output[15] ^= state[byte] + + for byte in range(9, 15): + state_output[byte] ^= state[7] + + return state_output + + +def PermutationLayerEnc(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 PermutationLayerDec(state): + state_output = [0 for byte in range(0, BLOCK_BYTES)] + for byte in range(0, BLOCK_BYTES): + state_output[byte] = state[permutationInv[byte]] + + return state_output + + +def OneRoundEGFNEnc(state, subtweakey): + state_non_linear = NonLinearLayer(state, subtweakey) + state_linear = LinearLayer(state_non_linear) + state_permutation = PermutationLayerEnc(state_linear) + + return state_permutation + +def LastRoundEGFN(state, subtweakey): + state_non_linear = NonLinearLayer(state, subtweakey) + state_linear = LinearLayer(state_non_linear) + + return state_linear + + +def OneRoundEGFNDec(state, subtweakey): + state_non_linear = NonLinearLayer(state, subtweakey) + state_linear = LinearLayer(state_non_linear) + state_permutation = PermutationLayerDec(state_linear) + + return state_permutation + + +def _rounds(key_bytes): + rounds = { + 128: 32, + 192: 36, + 256: 42 + } + return rounds[key_bytes*8] + + +################################################################################ +# Lilliput TBC + +def encrypt(tweak, key, message): + r = _rounds(len(key)) + + tweakey = BuildTweakey(tweak, key) + RTKs = TweakeyScheduleWhole(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 = OneRoundEGFNEnc(state, RTKs[i]) + + for byte in range(0, BLOCK_BYTES): + state[byte] = state_output[byte] + + state_output = LastRoundEGFN(state, RTKs[r-1]) + + return state_output + + +def decrypt(tweak, key, cipher): + r = _rounds(len(key)) + + tweakey = BuildTweakey(tweak, key) + RTKs = TweakeyScheduleWhole(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 = OneRoundEGFNDec(state, RTKs[r-i-1]) + + for byte in range(0, BLOCK_BYTES): + state[byte] = state_output[byte] + + state_output = LastRoundEGFN(state, RTKs[0]) + + return state_output -- cgit v1.2.3