multiplications.py (5368B)
1 # Implementation of the Lilliput-AE tweakable block cipher. 2 # 3 # Authors, hereby denoted as "the implementer": 4 # Kévin Le Gouguec, 5 # Léo Reynaud 6 # 2019. 7 # 8 # For more information, feedback or questions, refer to our website: 9 # https://paclido.fr/lilliput-ae 10 # 11 # To the extent possible under law, the implementer has waived all copyright 12 # and related or neighboring rights to the source code in this file. 13 # http://creativecommons.org/publicdomain/zero/1.0/ 14 15 """Multiplications for Lilliput-TBC's tweakey schedule. 16 17 This module provides a list of functions implementing lane multiplications, 18 from ALPHAS[0] = α₀ = I to ALPHAS[6] = α₆ = M_R³. 19 """ 20 21 22 from functools import reduce 23 from operator import xor 24 25 26 def _shl(xi, n): 27 return (xi << n) & 0xff 28 29 def _Sl(n): 30 return lambda xi: _shl(xi, n) 31 32 def _Sr(n): 33 return lambda xi: xi>>n 34 35 def _Id(xi): 36 return xi 37 38 def _0(xi): 39 return 0 40 41 def _M1(xi): 42 return _shl(xi, 3) ^ xi>>3 43 44 def _M2(xi): 45 return _shl(xi, 6) ^ xi&0b11111000 ^ xi>>6 46 47 def _M3(xi): 48 return _shl(xi>>3, 6) ^ xi>>6<<3 49 50 def _M4(xi): 51 return _shl(xi, 2) >> 3 52 53 def _M5(xi): 54 return _shl(xi, 5) ^ xi>>3<<2 55 56 def _M6(xi): 57 return xi & 0b00011111 58 59 def _M7(xi): 60 return _shl(xi, 2) >> 3 61 62 63 M = ( 64 ( _0, _Id, _0, _0, _0, _0, _0, _0), 65 ( _0, _0, _Id, _0, _0, _0, _0, _0), 66 ( _0, _0, _Sl(3), _Id, _0, _0, _0, _0), 67 ( _0, _0, _0, _Sr(3), _Id, _0, _0, _0), 68 ( _0, _0, _0, _0, _0, _Id, _0, _0), 69 ( _0, _Sl(2), _0, _0, _0, _0, _Id, _0), 70 ( _0, _0, _0, _0, _0, _0, _0, _Id), 71 (_Id, _0, _0, _0, _0, _0, _0, _0), 72 ) 73 74 M2 = ( 75 ( _0, _0, _Id, _0, _0, _0, _0, _0), 76 ( _0, _0, _Sl(3), _Id, _0, _0, _0, _0), 77 ( _0, _0, _Sl(6), _M1, _Id, _0, _0, _0), 78 ( _0, _0, _0, _Sr(6), _Sr(3), _Id, _0, _0), 79 ( _0, _Sl(2), _0, _0, _0, _0, _Id, _0), 80 ( _0, _0, _Sl(2), _0, _0, _0, _0, _Id), 81 (_Id, _0, _0, _0, _0, _0, _0, _0), 82 ( _0, _Id, _0, _0, _0, _0, _0, _0), 83 ) 84 85 M3 = ( 86 ( _0, _0, _Sl(3), _Id, _0, _0, _0, _0), 87 ( _0, _0, _Sl(6), _M1, _Id, _0, _0, _0), 88 ( _0, _0, _0, _M2, _M1, _Id, _0, _0), 89 ( _0, _Sl(2), _0, _0, _Sr(6), _Sr(3), _Id, _0), 90 ( _0, _0, _Sl(2), _0, _0, _0, _0, _Id), 91 (_Id, _0, _Sl(5), _Sl(2), _0, _0, _0, _0), 92 ( _0, _Id, _0, _0, _0, _0, _0, _0), 93 ( _0, _0, _Id, _0, _0, _0, _0, _0), 94 ) 95 96 M4 = ( 97 ( _0, _0, _Sl(6), _M1, _Id, _0, _0, _0), 98 ( _0, _0, _0, _M2, _M1, _Id, _0, _0), 99 ( _0, _Sl(2), _0, _M3, _M2, _M1, _Id, _0), 100 ( _0, _M4, _Sl(2), _0, _0, _Sr(6), _Sr(3), _Id), 101 (_Id, _0, _Sl(5), _Sl(2), _0, _0, _0, _0), 102 ( _0, _Id, _0, _M5, _Sl(2), _0, _0, _0), 103 ( _0, _0, _Id, _0, _0, _0, _0, _0), 104 ( _0, _0, _Sl(3), _Id, _0, _0, _0, _0), 105 ) 106 107 # NB: shift directions are reversed with respect to the specification 108 # for powers of M_R, since the specification reverses the byte order 109 # for those matrices. 110 111 MR = ( 112 ( _0, _Id, _0, _0, _0, _0, _0, _0), 113 ( _0, _0, _Id, _0, _0, _0, _0, _0), 114 ( _0, _0, _0, _Id, _Sr(3), _0, _0, _0), 115 ( _0, _0, _0, _0, _Id, _0, _0, _0), 116 ( _0, _0, _0, _0, _0, _Id, _Sl(3), _0), 117 ( _0, _0, _0, _Sl(2), _0, _0, _Id, _0), 118 ( _0, _0, _0, _0, _0, _0, _0, _Id), 119 (_Id, _0, _0, _0, _0, _0, _0, _0), 120 ) 121 122 MR2 = ( 123 ( _0, _0, _Id, _0, _0, _0, _0, _0), 124 ( _0, _0, _0, _Id, _Sr(3), _0, _0, _0), 125 ( _0, _0, _0, _0, _Id, _Sr(3), _M6, _0), 126 ( _0, _0, _0, _0, _0, _Id, _Sl(3), _0), 127 ( _0, _0, _0, _Sl(2), _0, _0, _Id, _Sl(3)), 128 ( _0, _0, _0, _0, _Sl(2), _0, _0, _Id), 129 (_Id, _0, _0, _0, _0, _0, _0, _0), 130 ( _0, _Id, _0, _0, _0, _0, _0, _0), 131 ) 132 133 MR3 = ( 134 ( _0, _0, _0, _Id, _Sr(3), _0, _0, _0), 135 ( _0, _0, _0, _0, _Id, _Sr(3), _M6, _0), 136 ( _0, _0, _0, _M7, _0, _Id, _M1, _M6), 137 ( _0, _0, _0, _Sl(2), _0, _0, _Id, _Sl(3)), 138 (_Sl(3), _0, _0, _0, _Sl(2), _0, _0, _Id), 139 ( _Id, _0, _0, _0, _0, _Sl(2), _Sl(5), _0), 140 ( _0, _Id, _0, _0, _0, _0, _0, _0), 141 ( _0, _0, _Id, _0, _0, _0, _0, _0), 142 ) 143 144 145 def _multiplication(m, reverse=True): 146 def ordered(l): 147 if reverse: 148 return list(reversed(list(l))) 149 return l 150 151 def _multiply(x): 152 return ordered( 153 reduce(xor, (mj[i](xi) for i, xi in enumerate(ordered(x)))) 154 for mj in m 155 ) 156 157 return _multiply 158 159 160 ALPHAS = ( 161 _multiplication(M), 162 _multiplication(M2), 163 _multiplication(M3), 164 _multiplication(M4), 165 _multiplication(MR, reverse=False), 166 _multiplication(MR2, reverse=False), 167 _multiplication(MR3, reverse=False) 168 )