diff options
Diffstat (limited to 'src/add_python')
| -rw-r--r-- | src/add_python/lilliput/lilliput_ae_1.py | 52 | ||||
| -rw-r--r-- | src/add_python/lilliput/tbc.py | 105 |
2 files changed, 95 insertions, 62 deletions
diff --git a/src/add_python/lilliput/lilliput_ae_1.py b/src/add_python/lilliput/lilliput_ae_1.py index 0da2a95..1429002 100644 --- a/src/add_python/lilliput/lilliput_ae_1.py +++ b/src/add_python/lilliput/lilliput_ae_1.py @@ -1,5 +1,21 @@ -""" - OCB 3 for lilliput ae i +# Implementation of the Lilliput-AE tweakable block cipher. +# +# Authors, hereby denoted as "the implementer": +# Kévin Le Gouguec, +# Léo Reynaud +# 2019. +# +# For more information, feedback or questions, refer to our website: +# https://paclido.fr/lilliput-ae +# +# To the extent possible under law, the implementer has waived all copyright +# and related or neighboring rights to the source code in this file. +# http://creativecommons.org/publicdomain/zero/1.0/ + +"""Lilliput-I Authenticated Encryption mode. + +This module provides the functions for authenticated encryption and decryption +using Lilliput-AE's nonce-misuse-resistant mode based on ΘCB3. """ from enum import Enum @@ -20,7 +36,7 @@ TWEAK_BITS = 192 TWEAK_BYTES = TWEAK_BITS//8 -def LowPart(array, number_bits): +def _LowPart(array, number_bits): shifted = 0 for byte in range(0, len(array)): shifted |= (array[byte] << (8 * byte)) @@ -51,7 +67,7 @@ class _MessageTweak(Enum): FINAL = 0b0101 -def TweakMessage(N, j, padding): +def _TweakMessage(N, j, padding): tweak = [0 for byte in range(0, TWEAK_BYTES)] for byte in range(NONCE_BYTES-1, -1, -1): tweak[byte + (TWEAK_BYTES-NONCE_BYTES)] |= (N[byte] & 0xf0) >> 4 @@ -66,7 +82,7 @@ def TweakMessage(N, j, padding): return tweak -def TreatMessageEnc(M, N, key): +def _TreatMessageEnc(M, N, key): checksum = [0 for byte in range(0, BLOCK_BYTES)] l = len(M)//BLOCK_BYTES @@ -77,28 +93,28 @@ def TreatMessageEnc(M, N, key): for j in range(0, l): checksum = XorState(checksum, M[j]) - tweak = TweakMessage(N, j, _MessageTweak.BLOCK) + tweak = _TweakMessage(N, j, _MessageTweak.BLOCK) C.append(tbc.encrypt(tweak, key, M[j])) if padding_bytes == 0: - tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING) + tweak = _TweakMessage(N, l, _MessageTweak.NO_PADDING) Final = tbc.encrypt(tweak, key, checksum) else: m_padded = Padding10LSB(M[l]) checksum = XorState(checksum, m_padded) - tweak = TweakMessage(N, l, _MessageTweak.PAD) + tweak = _TweakMessage(N, l, _MessageTweak.PAD) pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) - lower_part = LowPart(pad, padding_bytes*8) + lower_part = _LowPart(pad, padding_bytes*8) C.append(XorState(M[l], lower_part)) - tweak_final = TweakMessage(N, l+1, _MessageTweak.FINAL) + tweak_final = _TweakMessage(N, l+1, _MessageTweak.FINAL) Final = tbc.encrypt(tweak_final, key, checksum) return (Final, C) -def TreatMessageDec(C, N, key): +def _TreatMessageDec(C, N, key): checksum = [0 for byte in range(0, BLOCK_BYTES)] l = len(C)//BLOCK_BYTES @@ -108,23 +124,23 @@ def TreatMessageDec(C, N, key): M = [] for j in range(0, l): - tweak = TweakMessage(N, j, _MessageTweak.BLOCK) + tweak = _TweakMessage(N, j, _MessageTweak.BLOCK) M.append(tbc.decrypt(tweak, key, C[j])) checksum = XorState(checksum, M[j]) if padding_bytes == 0: - tweak = TweakMessage(N, l, _MessageTweak.NO_PADDING) + tweak = _TweakMessage(N, l, _MessageTweak.NO_PADDING) Final = tbc.encrypt(tweak, key, checksum) else: - tweak = TweakMessage(N, l, _MessageTweak.PAD) + tweak = _TweakMessage(N, l, _MessageTweak.PAD) pad = tbc.encrypt(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) - lower_part = LowPart(pad, padding_bytes*8) + 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) + tweak_final = _TweakMessage(N, l+1, _MessageTweak.FINAL) Final = tbc.encrypt(tweak_final, key, checksum) return (Final, M) @@ -135,7 +151,7 @@ def encrypt(A, M, N, key): K = list(key) Auth = BuildAuth(TWEAK_BITS, A, K) - (Final, C) = TreatMessageEnc(M, N, K) + (Final, C) = _TreatMessageEnc(M, N, K) tag = XorState(Auth, Final) return BlockbytesMatrixToBytes(C), bytes(tag) @@ -146,7 +162,7 @@ def decrypt(A, C, N, tag, key): tag = list(tag) Auth = BuildAuth(TWEAK_BITS, A, K) - (Final, M) = TreatMessageDec(C, N, K) + (Final, M) = _TreatMessageDec(C, N, K) tag2 = XorState(Auth, Final) if tag != tag2: diff --git a/src/add_python/lilliput/tbc.py b/src/add_python/lilliput/tbc.py index 5291994..50f9e2f 100644 --- a/src/add_python/lilliput/tbc.py +++ b/src/add_python/lilliput/tbc.py @@ -1,34 +1,51 @@ +# Implementation of the Lilliput-AE tweakable block cipher. +# +# Authors, hereby denoted as "the implementer": +# Kévin Le Gouguec, +# Léo Reynaud +# 2019. +# +# For more information, feedback or questions, refer to our website: +# https://paclido.fr/lilliput-ae +# +# To the extent possible under law, the implementer has waived all copyright +# and related or neighboring rights to the source code in this file. +# http://creativecommons.org/publicdomain/zero/1.0/ + +"""Lilliput-TBC tweakable block cipher. + +This module provides functions to encrypt and decrypt blocks of 128 bits. """ - 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] +_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): +def _BuildTweakey(tweak, key): return tweak+key ############################# -def _lane(TK, j): +def _Lane(TK, j): return TK[j*8:(j+1)*8] -def RoundTweakeySchedule(tweakey): + +def _RoundTweakeySchedule(tweakey): p = len(tweakey)//8 multiplied_lanes = ( - ALPHAS[j](_lane(tweakey, j)) for j in range(p) + 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): +def _SubTweakeyExtract(tweakey, Ci): RTKi = [0]*8 for j, byte in enumerate(tweakey): @@ -39,22 +56,22 @@ def SubTweakeyExtract(tweakey, Ci): return RTKi -def TweakeyScheduleWhole(tweakey, r): - # store main tweakey in TKs[0] - # and corresponding round tweakey in RTKs[0] +def _TweakeyScheduleWhole(tweakey, r): + # Store the initial tweakey in TKs[0], and the corresponding round tweakey + # in RTKs[0]. TKs = [tweakey] - RTKs = [SubTweakeyExtract(TKs[0], 0)] + RTKs = [_SubTweakeyExtract(TKs[0], 0)] for i in range(1, r): - TKs.append(RoundTweakeySchedule(TKs[i-1])) - RTKs.append(SubTweakeyExtract(TKs[i], i)) + TKs.append(_RoundTweakeySchedule(TKs[i-1])) + RTKs.append(_SubTweakeyExtract(TKs[i], i)) return RTKs ################################################################################ -def NonLinearLayer(state, subtweakey): +def _NonLinearLayer(state, subtweakey): variables_xored = [0 for byte in range(0, 8)] for byte in range(0,8): @@ -73,7 +90,7 @@ def NonLinearLayer(state, subtweakey): return state_output -def LinearLayer(state): +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] @@ -87,44 +104,44 @@ def LinearLayer(state): return state_output -def PermutationLayerEnc(state): +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]] + state_output[byte] = state[_permutation[byte]] return state_output -def PermutationLayerDec(state): +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]] + 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) +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) +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) +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): +def _Rounds(key_bytes): rounds = { 128: 32, 192: 36, @@ -134,45 +151,45 @@ def _rounds(key_bytes): ################################################################################ -# Lilliput TBC + def encrypt(tweak, key, message): - r = _rounds(len(key)) + r = _Rounds(len(key)) - tweakey = BuildTweakey(tweak, key) - RTKs = TweakeyScheduleWhole(tweakey, r) + 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]) + 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]) + state_output = _LastRoundEGFN(state, RTKs[r-1]) return state_output def decrypt(tweak, key, cipher): - r = _rounds(len(key)) + r = _Rounds(len(key)) - tweakey = BuildTweakey(tweak, key) - RTKs = TweakeyScheduleWhole(tweakey, r) + 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]) + 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]) + state_output = _LastRoundEGFN(state, RTKs[0]) return state_output |
