""" OCB 3 for lilliput ae i """ import lilliput_tbc as ltbc BLOCK_BITS = 128 KEY_BITS = 128 TWEAK_BITS = 192 TWEAKEY_BITS = KEY_BITS + TWEAK_BITS LANE_BITS = 64 LANES = int((TWEAKEY_BITS) / LANE_BITS) ROUNDS = 32 BLOCK_BYTES = int(BLOCK_BITS / 8) KEY_BYTES = int(KEY_BITS / 8) TWEAK_BYTES = int(TWEAK_BITS / 8) TWEAKEY_BYTES = int(TWEAKEY_BITS / 8) A_BITS = BLOCK_BITS M_BITS = BLOCK_BITS N_BITS = 120 N_BYTES = int(N_BITS / 8) def InitParameters(key_bits = 128, tweak_bits = 192, rounds = 32) : global KEY_BITS global KEY_BYTES global TWEAK_BITS global TWEAK_BYTES global TWEAKEY_BITS global TWEAKEY_BYTES global LANES global ROUNDS KEY_BITS = key_bits TWEAK_BITS = tweak_bits TWEAKEY_BITS = KEY_BITS + TWEAK_BITS LANES = int((TWEAKEY_BITS) / LANE_BITS) ROUNDS = rounds KEY_BYTES = int(KEY_BITS / 8) TWEAK_BYTES = int(TWEAK_BITS / 8) TWEAKEY_BYTES = int(TWEAKEY_BITS / 8) ############################################################################### def XorState(state1, state2) : state_output = [state1[byte] ^ state2[byte] for byte in range(0, len(state1))] return state_output def Padding10LSB(array, number_bits) : shifted = 0 for byte in range(0, len(array)) : shifted |= (array[byte] << (8 * byte)) shifted = (shifted << (BLOCK_BITS - number_bits)) & 0xffffffffffffffffffffffffffffffff padded = shifted | (0x1 << (BLOCK_BITS - number_bits - 1)) array_padded = [0 for byte in range(0, BLOCK_BYTES)] for byte in range(0, BLOCK_BYTES) : array_padded[byte] = (padded & (0xff << (8 * byte))) >> (8 * byte) return array_padded def LowPart(array, number_bits) : shifted = 0 for byte in range(0, len(array)) : shifted |= (array[byte] << (8 * byte)) mask = 0 for bit in range(0, number_bits) : mask |= (0x1 << bit) lower_part = shifted & mask will_padd = 0 if (number_bits % 8) != 0 : will_padd = 1 lower_part_byte = [0 for byte in range(0, int(number_bits / 8) + will_padd)] for byte in range(0, int(number_bits / 8) + will_padd) : lower_part_byte[byte] = lower_part & 0xff lower_part = lower_part >> 8 return lower_part_byte ############################################################################### def TweakAssociatedData(i, padded = 0) : tweak = [0 for byte in range(0, TWEAK_BYTES)] mask = 0xff for byte in range(0, TWEAK_BYTES - 1) : tweak[byte] = (i & mask) >> (byte * 8) mask = mask << 8 mask = (0xf << (8 * (TWEAK_BYTES - 1))) tweak[TWEAK_BYTES - 1] = (i & mask) >> ((TWEAK_BYTES - 1) * 8) if padded == 0 : tweak[TWEAK_BYTES - 1] |= 0x20 else : tweak[TWEAK_BYTES - 1] |= 0x60 return tweak def BuildAuth(A, key) : Auth = [0 for byte in range(0, BLOCK_BYTES)] l_a = int(A_BITS / BLOCK_BITS) if int(A_BITS % BLOCK_BITS) > 0 : will_padd = 1 else : will_padd = 0 for i in range(0, l_a) : tweak = TweakAssociatedData(i, padded = 0) enc = ltbc.LilliputTBCEnc(tweak, key, A[i]) Auth = XorState(Auth, enc) if (A_BITS % BLOCK_BITS) == 0 : return Auth tweak = TweakAssociatedData(l_a, padded = 1) ad_padded = Padding10LSB(A[l_a], (A_BITS % BLOCK_BITS)) enc = ltbc.LilliputTBCEnc(tweak, key, ad_padded) Auth = XorState(Auth, enc) return Auth ################################################################################ def TweakMessage(N, j, null = 0, padded = 0, final_padded = 0) : tweak = [0 for byte in range(0, TWEAK_BYTES)] for byte in range(N_BYTES - 1, -1, -1) : tweak[byte + (TWEAK_BYTES - N_BYTES)] |= (N[byte] & 0xf0) >> 4 tweak[byte + (TWEAK_BYTES - N_BYTES - 1)] |= (N[byte] & 0x0f) << 4 tweak[TWEAK_BYTES - N_BYTES - 1] |= ((j >> 64) & 0xf) for byte in range(TWEAK_BYTES - N_BYTES - 2, -1, -1) : tweak[byte] = (j >> (8 * byte)) & 0xff if null == 1 : tweak[TWEAK_BYTES - 1] |= 0x10 if padded == 1 : tweak[TWEAK_BYTES - 1] |= 0x40 if final_padded == 1 : tweak[TWEAK_BYTES - 1] |= 0x50 return tweak def TreatMessageEnc(M, N, key) : checksum = [0 for byte in range(0, BLOCK_BYTES)] l = int(M_BITS / BLOCK_BITS) if int(M_BITS % BLOCK_BITS) > 0 : will_padd = 1 else : will_padd = 0 C = [[0 for byte in range(0, BLOCK_BYTES)] for j in range(0, l + will_padd)] for j in range(0, l) : checksum = XorState(checksum, M[j]) tweak = TweakMessage(N, j, padded = 0) C[j] = ltbc.LilliputTBCEnc(tweak, key, M[j]) if will_padd == 0 : tweak = TweakMessage(N, l - 1, null = 1) Final = ltbc.LilliputTBCEnc(tweak, key, checksum) else : m_padded = Padding10LSB(M[l], M_BITS % BLOCK_BITS) checksum = XorState(checksum, m_padded) tweak = TweakMessage(N, l, padded = 1) pad = ltbc.LilliputTBCEnc(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) lower_part = LowPart(pad, M_BITS % BLOCK_BITS) C[l] = XorState(M[l], lower_part) tweak_final = TweakMessage(N, l, final_padded = 1) Final = ltbc.LilliputTBCEnc(tweak_final, key, checksum) return (Final, C) def TreatMessageDec(C, N, key) : checksum = [0 for byte in range(0, BLOCK_BYTES)] l = int(M_BITS / BLOCK_BITS) if int(M_BITS % BLOCK_BITS) > 0 : will_padd = 1 else : will_padd = 0 M = [[0 for byte in range(0, BLOCK_BYTES)] for j in range(0, l + will_padd)] for j in range(0, l) : tweak = TweakMessage(N, j, padded = 0) M[j] = ltbc.LilliputTBCDec(tweak, key, C[j]) checksum = XorState(checksum, M[j]) if will_padd == 0 : tweak = TweakMessage(N, l - 1, null = 1) Final = ltbc.LilliputTBCEnc(tweak, key, checksum) else : tweak = TweakMessage(N, l, padded = 1) pad = ltbc.LilliputTBCEnc(tweak, key, [0 for byte in range(0, BLOCK_BYTES)]) lower_part = LowPart(pad, M_BITS % BLOCK_BITS) M[l] = XorState(C[l], lower_part) m_padded = Padding10LSB(M[l], M_BITS % BLOCK_BITS) checksum = XorState(checksum, m_padded) tweak_final = TweakMessage(N, l, final_padded = 1) Final = ltbc.LilliputTBCEnc(tweak_final, key, checksum) return (Final, M) ################################################################################ def OCB3Enc(A, M, N, associated_data_length_bit, message_length_bit, key, key_bits, tweak_bits, rounds) : InitParameters(key_bits, tweak_bits, rounds) global A_BITS global M_BITS A_BITS = associated_data_length_bit M_BITS = message_length_bit ltbc.KEY_BITS = KEY_BITS ltbc.ROUNDS = ROUNDS ltbc.TWEAK_BITS = TWEAK_BITS ltbc.LANES = LANES ltbc.TWEAKEY_BITS = TWEAKEY_BITS ltbc.KEY_BYTES = KEY_BYTES ltbc.TWEAK_BYTES = TWEAK_BYTES ltbc.TWEAKEY_BYTES = TWEAKEY_BYTES ltbc.TKs = [[0 for byte in range(0, TWEAKEY_BYTES)] for round in range(0, ROUNDS)] ltbc.RTKs = [[0 for byte in range(0, 8)] for round in range(0, ROUNDS)] ltbc.States = [[0 for byte in range(0, BLOCK_BYTES)] for round in range(0, ROUNDS)] Auth = BuildAuth(A, key) (Final, C) = TreatMessageEnc(M, N, key) tag = XorState(Auth, Final) return (C, tag) def OCB3Dec(A, C, N, tag, associated_data_length_bit, message_length_bit, key, key_bits, tweak_bits, rounds) : InitParameters(key_bits, tweak_bits, rounds) global A_BITS global M_BITS A_BITS = associated_data_length_bit M_BITS = message_length_bit ltbc.KEY_BITS = KEY_BITS ltbc.ROUNDS = ROUNDS ltbc.TWEAK_BITS = TWEAK_BITS ltbc.LANES = LANES ltbc.TWEAKEY_BITS = TWEAKEY_BITS ltbc.KEY_BYTES = KEY_BYTES ltbc.TWEAK_BYTES = TWEAK_BYTES ltbc.TWEAKEY_BYTES = TWEAKEY_BYTES ltbc.TKs = [[0 for byte in range(0, TWEAKEY_BYTES)] for round in range(0, ROUNDS)] ltbc.RTKs = [[0 for byte in range(0, 8)] for round in range(0, ROUNDS)] ltbc.States = [[0 for byte in range(0, BLOCK_BYTES)] for round in range(0, ROUNDS)] Auth = BuildAuth(A, key) (Final, M) = TreatMessageDec(C, N, key) tag2 = XorState(Auth, Final) if(tag == tag2) : return M