""" SCT 2 for lilliput ae 2 """ from .constants import BLOCK_BYTES from .helpers import ( ArrayToBlockbytesMatrix, BlockbytesMatrixToBytes, BuildAuth, Padding10LSB, TagValidationError, XorState ) from . import tbc TWEAK_BITS = 128 TWEAK_BYTES = TWEAK_BITS//8 def TweakTag(j, padded): tweak = [0 for byte in range(0, TWEAK_BYTES)] tweak[TWEAK_BYTES - 1] |= ((j >> 120) & 0xf) for byte in range(TWEAK_BYTES - 2, -1, -1): tweak[byte] = (j >> (8 * byte)) & 0xff if padded: tweak[TWEAK_BYTES - 1] |= 0x40 return tweak def TweakTagEnd(N): tweak = [0 for byte in range(0, TWEAK_BYTES)] for byte in range(0, TWEAK_BYTES - 1): tweak[byte] = N[byte] tweak[TWEAK_BYTES - 1] = 0x10 return tweak def AddTagJ(tag, j): array_j = [0 for byte in range(0, TWEAK_BYTES)] for byte in range(0, TWEAK_BYTES): array_j[byte] = (j >> (byte * 8)) xorr = XorState(tag, array_j) xorr[TWEAK_BYTES - 1] |= 0x80 return xorr def MesssageAuthTag(M, N, Auth, key): l = len(M)//BLOCK_BYTES need_padding = len(M)%BLOCK_BYTES > 0 tag = list(Auth) M = ArrayToBlockbytesMatrix(M) for j in range(0, l): tweak = TweakTag(j, False) encryption = tbc.encrypt(tweak, key, M[j]) tag = XorState(tag, encryption) if need_padding: tweak = TweakTag(l, True) m_padded = Padding10LSB(M[l]) encryption = tbc.encrypt(tweak, key, m_padded) tag = XorState(tag, encryption) tweak = TweakTagEnd(N) encryption = tbc.encrypt(tweak, key, tag) tag = encryption return tag def MessageEncryption(M, N, tag, key): l = len(M)//BLOCK_BYTES need_padding = len(M)%BLOCK_BYTES > 0 M = ArrayToBlockbytesMatrix(M) C = [] for j in range(0, l): tweak = AddTagJ(tag, j) padded_nonce = list(N) + [0x00] 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 = tbc.encrypt(tweak, key, padded_nonce) C.append(XorState(M[l], encryption)) return C ################################################################################ def encrypt(A, M, N, key): K = list(key) Auth = BuildAuth(TWEAK_BITS, A, K) tag = MesssageAuthTag(M, N, Auth, K) C = MessageEncryption(M, N, tag, K) return BlockbytesMatrixToBytes(C), bytes(tag) def decrypt(A, C, N, tag, key): K = list(key) tag = list(tag) M = BlockbytesMatrixToBytes( MessageEncryption(C, N, tag, K) ) Auth = BuildAuth(TWEAK_BITS, A, K) tag2 = MesssageAuthTag(M, N, Auth, K) if tag != tag2: raise TagValidationError(tag, tag2) return M