# 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/ """Multiplications for Lilliput-TBC's tweakey schedule. This module provides a list of functions implementing lane multiplications, from ALPHAS[0] = α₀ = I to ALPHAS[6] = α₆ = M_R³. """ def _multiply_M(lane): multiplied_lane = [lane[(byte-1) % 8] for byte in range(0, 8)] multiplied_lane[2] ^= ((lane[6] << 2) & 0xff) multiplied_lane[4] ^= ((lane[4] >> 3) & 0xff) multiplied_lane[5] ^= ((lane[5] << 3) & 0xff) return multiplied_lane def _multiply_M2(lane): multiplied_lane = [lane[(byte-2) % 8] for byte in range(0, 8)] multiplied_lane[2] ^= ((lane[5] << 2) & 0xff) multiplied_lane[3] ^= ((lane[6] << 2) & 0xff) multiplied_lane[4] ^= ((lane[3] >> 3) & 0xff) ^ ((lane[4] >> 6) & 0xff) multiplied_lane[5] ^= ((lane[5] << 6) & 0xff) multiplied_lane[6] ^= ((lane[5] << 3) & 0xff) # binary matrix M1 multi_mat_l4_m1 = 0 l4 = lane[4] multi_mat_l4_m1 ^= ((l4 & 0x8) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x10) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x20) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x40) >> 3) ^ ((l4 & 0x1) << 3) multi_mat_l4_m1 ^= ((l4 & 0x80) >> 3) ^ ((l4 & 0x2) << 3) multi_mat_l4_m1 ^= ((l4 & 0x04) << 3) multi_mat_l4_m1 ^= ((l4 & 0x08) << 3) multi_mat_l4_m1 ^= ((l4 & 0x10) << 3) multiplied_lane[5] ^= multi_mat_l4_m1 return multiplied_lane def _multiply_M3(lane): multiplied_lane = [lane[(byte-3) % 8] for byte in range(0, 8)] multiplied_lane[2] ^= ((lane[4] << 2) & 0xff) ^ ((lane[5] << 5) & 0xff) multiplied_lane[3] ^= ((lane[5] << 2) & 0xff) multiplied_lane[4] ^= ((lane[2] >> 3) & 0xff) ^ ((lane[3] >> 6) & 0xff) ^ ((lane[6] << 2) & 0xff) multiplied_lane[6] ^= ((lane[5] << 6) & 0xff) multiplied_lane[7] ^= ((lane[5] << 3) & 0xff) # binary matrix M1 multi_mat_l3_m1 = 0 l3 = lane[3] multi_mat_l3_m1 ^= ((l3 & 0x8) >> 3) multi_mat_l3_m1 ^= ((l3 & 0x10) >> 3) multi_mat_l3_m1 ^= ((l3 & 0x20) >> 3) multi_mat_l3_m1 ^= ((l3 & 0x40) >> 3) ^ ((l3 & 0x1) << 3) multi_mat_l3_m1 ^= ((l3 & 0x80) >> 3) ^ ((l3 & 0x2) << 3) multi_mat_l3_m1 ^= ((l3 & 0x04) << 3) multi_mat_l3_m1 ^= ((l3 & 0x08) << 3) multi_mat_l3_m1 ^= ((l3 & 0x10) << 3) # binary matrix M1 multi_mat_l4_m1 = 0 l4 = lane[4] multi_mat_l4_m1 ^= ((l4 & 0x8) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x10) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x20) >> 3) multi_mat_l4_m1 ^= ((l4 & 0x40) >> 3) ^ ((l4 & 0x1) << 3) multi_mat_l4_m1 ^= ((l4 & 0x80) >> 3) ^ ((l4 & 0x2) << 3) multi_mat_l4_m1 ^= ((l4 & 0x04) << 3) multi_mat_l4_m1 ^= ((l4 & 0x08) << 3) multi_mat_l4_m1 ^= ((l4 & 0x10) << 3) # binary matrix M2 multi_mat_l4_m2 = 0 l4 = lane[4] multi_mat_l4_m2 ^= ((l4 & 0x40) >> 6) multi_mat_l4_m2 ^= ((l4 & 0x80) >> 6) multi_mat_l4_m2 ^= (l4 & 0x08) multi_mat_l4_m2 ^= (l4 & 0x10) multi_mat_l4_m2 ^= (l4 & 0x20) multi_mat_l4_m2 ^= (l4 & 0x40) ^ ((l4 & 0x1) << 6) multi_mat_l4_m2 ^= (l4 & 0x80) ^ ((l4 & 0x2) << 6) multiplied_lane[5] ^= multi_mat_l3_m1 ^ multi_mat_l4_m2 multiplied_lane[6] ^= multi_mat_l4_m1 return multiplied_lane def _multiply_MR(lane): multiplied_lane = [lane[(byte+1) % 8] for byte in range(0, 8)] multiplied_lane[2] ^= ((lane[4] >> 3) & 0xff) multiplied_lane[4] ^= ((lane[6] << 3) & 0xff) multiplied_lane[5] ^= ((lane[3] << 2) & 0xff) return multiplied_lane def _multiply_MR2(lane): multiplied_lane = [lane[(byte+2) % 8] for byte in range(0, 8)] multiplied_lane[1] ^= ((lane[4] >> 3) & 0xff) multiplied_lane[2] ^= ((lane[5] >> 3) & 0xff) multiplied_lane[3] ^= ((lane[6] << 3) & 0xff) multiplied_lane[4] ^= ((lane[3] << 2) & 0xff) ^ ((lane[7] << 3) & 0xff) multiplied_lane[5] ^= ((lane[4] << 2) & 0xff) # binary matrix m3 multi_mat_l6_m3 = 0 l6 = lane[6] multi_mat_l6_m3 ^= (l6 & 0x1) multi_mat_l6_m3 ^= (l6 & 0x2) multi_mat_l6_m3 ^= (l6 & 0x4) multi_mat_l6_m3 ^= (l6 & 0x8) multi_mat_l6_m3 ^= (l6 & 0x10) multiplied_lane[2] ^= multi_mat_l6_m3 return multiplied_lane def _multiply_MR3(lane): multiplied_lane = [lane[(byte+3) % 8] for byte in range(0, 8)] multiplied_lane[0] ^= ((lane[4] >> 3) & 0xff) multiplied_lane[1] ^= ((lane[5] >> 3) & 0xff) multiplied_lane[3] ^= ((lane[3] << 2) & 0xff) ^ ((lane[7] << 3) & 0xff) multiplied_lane[4] ^= ((lane[0] << 3) & 0xff) ^ ((lane[4] << 2) & 0xff) multiplied_lane[5] ^= ((lane[5] << 2) & 0xff) ^ ((lane[6] << 5) & 0xff) # binary matrix m3 multi_mat_l6_m3 = 0 l6 = lane[6] multi_mat_l6_m3 ^= (l6 & 0x1) multi_mat_l6_m3 ^= (l6 & 0x2) multi_mat_l6_m3 ^= (l6 & 0x4) multi_mat_l6_m3 ^= (l6 & 0x8) multi_mat_l6_m3 ^= (l6 & 0x10) # binary matrix m3 multi_mat_l7_m3 = 0 l7 = lane[7] multi_mat_l7_m3 ^= (l7 & 0x1) multi_mat_l7_m3 ^= (l7 & 0x2) multi_mat_l7_m3 ^= (l7 & 0x4) multi_mat_l7_m3 ^= (l7 & 0x8) multi_mat_l7_m3 ^= (l7 & 0x10) # binary matrix m4 multi_mat_l3_m4 = 0 l3 = lane[3] multi_mat_l3_m4 ^= ((l3 & 0x2) >> 1) multi_mat_l3_m4 ^= ((l3 & 0x4) >> 1) multi_mat_l3_m4 ^= ((l3 & 0x8) >> 1) multi_mat_l3_m4 ^= ((l3 & 0x10) >> 1) multi_mat_l3_m4 ^= ((l3 & 0x20) >> 1) # binary matrix m1 for MR multi_mat_l6_m1 = 0 l6 = lane[6] multi_mat_l6_m1 ^= ((l6 & 0x8) >> 3) multi_mat_l6_m1 ^= ((l6 & 0x10) >> 3) multi_mat_l6_m1 ^= ((l6 & 0x20) >> 3) multi_mat_l6_m1 ^= ((l6 & 0x40) >> 3) ^ ((l6 & 0x1) << 3) multi_mat_l6_m1 ^= ((l6 & 0x80) >> 3) ^ ((l6 & 0x2) << 3) multi_mat_l6_m1 ^= ((l6 & 0x4) << 3) multi_mat_l6_m1 ^= ((l6 & 0x8) << 3) multi_mat_l6_m1 ^= ((l6 & 0x10) << 3) multiplied_lane[1] ^= multi_mat_l6_m3 multiplied_lane[2] ^= multi_mat_l3_m4 ^ multi_mat_l6_m1 ^ multi_mat_l7_m3 return multiplied_lane ALPHAS = ( list, # Identity. _multiply_M, _multiply_M2, _multiply_M3, _multiply_MR, _multiply_MR2, _multiply_MR3 )