Crypto++  8.2
Free C++ class library of cryptographic schemes
kalyna.cpp
1 // kalyna.cpp - written and placed in the public domain by Jeffrey Walton
2 // This code relied upon three sources. First was Oliynykov, Gorbenko, Kazymyrov, Ruzhentsev,
3 // Kuznetsov, Gorbenko, Dyrda, Dolgov, Pushkaryov, Mordvinov and Kaidalov's "A New Encryption
4 // Standard of Ukraine: The Kalyna Block Cipher" (http://eprint.iacr.org/2015/650.pdf). Second
5 // was Roman Oliynykov and Oleksandr Kazymyrov's GitHub with the reference implementation
6 // (http://github.com/Roman-Oliynykov/Kalyna-reference). The third and most utilized resource
7 // was Keru Kuro's public domain implementation of Kalyna in CppCrypto
8 // (http://sourceforge.net/projects/cppcrypto/). Kuro has an outstanding implementation that
9 // performed better than the reference implementation and our initial attempts. The only downside
10 // was the missing big endian port.
11 
12 #include "pch.h"
13 #include "config.h"
14 
15 #include "kalyna.h"
16 #include "argnames.h"
17 #include "misc.h"
18 #include "cpu.h"
19 
20 NAMESPACE_BEGIN(CryptoPP)
21 NAMESPACE_BEGIN(KalynaTab)
22 
23 // T can be shared between Kupyna and Kalyna; IT, S and IS are Kalyna specific
24 extern const word64 T[8][256]; // Columns
25 extern const word64 IT[8][256]; // Inverse
26 extern const byte S[4][256]; // Substitution
27 extern const byte IS[4][256]; // Inverse
28 
29 NAMESPACE_END
30 NAMESPACE_END
31 
32 ANONYMOUS_NAMESPACE_BEGIN
33 
34 // The typedef here is to sidestep problems with byte in the global namespace
35 typedef unsigned char byte;
36 
37 using CryptoPP::word64;
38 using CryptoPP::KalynaTab::T;
39 using CryptoPP::KalynaTab::S;
40 using CryptoPP::KalynaTab::IT;
41 using CryptoPP::KalynaTab::IS;
42 
43 template <unsigned int NB>
44 inline void MakeOddKey(const word64 evenkey[NB], word64 oddkey[NB])
45 {
46 #if (CRYPTOPP_BIG_ENDIAN)
47  if (NB == 2)
48  {
49  oddkey[0] = (evenkey[1] << 8) | (evenkey[0] >> 56);
50  oddkey[1] = (evenkey[0] << 8) | (evenkey[1] >> 56);
51  }
52  else if (NB == 4)
53  {
54  oddkey[0] = (evenkey[2] << 40) | (evenkey[1] >> 24);
55  oddkey[1] = (evenkey[3] << 40) | (evenkey[2] >> 24);
56  oddkey[2] = (evenkey[0] << 40) | (evenkey[3] >> 24);
57  oddkey[3] = (evenkey[1] << 40) | (evenkey[0] >> 24);
58  }
59  else if (NB == 8)
60  {
61  oddkey[0] = (evenkey[3] << 40) | (evenkey[2] >> 24);
62  oddkey[1] = (evenkey[4] << 40) | (evenkey[3] >> 24);
63  oddkey[2] = (evenkey[5] << 40) | (evenkey[4] >> 24);
64  oddkey[3] = (evenkey[6] << 40) | (evenkey[5] >> 24);
65 
66  oddkey[4] = (evenkey[7] << 40) | (evenkey[6] >> 24);
67  oddkey[5] = (evenkey[0] << 40) | (evenkey[7] >> 24);
68  oddkey[6] = (evenkey[1] << 40) | (evenkey[0] >> 24);
69  oddkey[7] = (evenkey[2] << 40) | (evenkey[1] >> 24);
70  }
71  else
72  {
73  CRYPTOPP_ASSERT(0);
74  }
75 #else
76  static const unsigned int U = (NB == 2) ? 16 : (NB == 4) ? 32 : (NB == 8) ? 64 : -1;
77  static const unsigned int V = (NB == 2) ? 7 : (NB == 4) ? 11 : (NB == 8) ? 19 : -1;
78 
79  const byte* even = reinterpret_cast<const byte*>(evenkey);
80  byte* odd = reinterpret_cast<byte*>(oddkey);
81 
82  memcpy(odd, even + V, U - V);
83  memcpy(odd + U - V, even, V);
84 #endif
85 }
86 
87 template <unsigned int NB>
88 inline void SwapBlocks(word64 k[NB])
89 {
90  const word64 t = k[0];
91  k[0] = k[1];
92 
93  if (NB > 2)
94  {
95  k[1] = k[2];
96  k[2] = k[3];
97  }
98 
99  if (NB > 4)
100  {
101  k[3] = k[4];
102  k[4] = k[5];
103  k[5] = k[6];
104  k[6] = k[7];
105  }
106 
107  k[NB - 1] = t;
108 }
109 
110 template <unsigned int NB>
111 inline void AddKey(const word64 x[NB], word64 y[NB], const word64 k[NB])
112 {
113  y[0] = x[0] + k[0];
114  y[1] = x[1] + k[1];
115 
116  if (NB > 2)
117  {
118  y[2] = x[2] + k[2];
119  y[3] = x[3] + k[3];
120  }
121 
122  if (NB > 4)
123  {
124  y[4] = x[4] + k[4];
125  y[5] = x[5] + k[5];
126  y[6] = x[6] + k[6];
127  y[7] = x[7] + k[7];
128  }
129 }
130 
131 template <unsigned int NB>
132 inline void SubKey(const word64 x[NB], word64 y[NB], const word64 k[NB])
133 {
134  y[0] = x[0] - k[0];
135  y[1] = x[1] - k[1];
136 
137  if (NB > 2)
138  {
139  y[2] = x[2] - k[2];
140  y[3] = x[3] - k[3];
141  }
142 
143  if (NB > 4)
144  {
145  y[4] = x[4] - k[4];
146  y[5] = x[5] - k[5];
147  y[6] = x[6] - k[6];
148  y[7] = x[7] - k[7];
149  }
150 }
151 
152 template <unsigned int NB>
153 static inline void AddConstant(word64 src[NB], word64 dst[NB], word64 constant)
154 {
155  dst[0] = src[0] + constant;
156  dst[1] = src[1] + constant;
157 
158  if (NB > 2)
159  {
160  dst[2] = src[2] + constant;
161  dst[3] = src[3] + constant;
162  }
163 
164  if (NB > 4)
165  {
166  dst[4] = src[4] + constant;
167  dst[5] = src[5] + constant;
168  dst[6] = src[6] + constant;
169  dst[7] = src[7] + constant;
170  }
171 }
172 
173 inline void G0128(const word64 x[2], word64 y[2])
174 {
175  y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
176  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
177  y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
178  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
179 }
180 
181 inline void G0256(const word64 x[4], word64 y[4])
182 {
183  y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
184  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
185  y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
186  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)];
187  y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
188  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)];
189  y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
190  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
191 }
192 
193 inline void G0512(const word64 x[8], word64 y[8])
194 {
195  y[0] = T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^
196  T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
197  y[1] = T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^
198  T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)];
199  y[2] = T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^
200  T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)];
201  y[3] = T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
202  T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)];
203  y[4] = T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
204  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)];
205  y[5] = T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
206  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)];
207  y[6] = T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
208  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)];
209  y[7] = T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^
210  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
211 }
212 
213 inline void GL128(const word64 x[2], word64 y[2], const word64 k[2])
214 {
215  y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
216  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]);
217  y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
218  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]);
219 }
220 
221 inline void GL256(const word64 x[4], word64 y[4], const word64 k[4])
222 {
223  y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
224  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)]);
225  y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
226  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)]);
227  y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
228  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)]);
229  y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
230  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)]);
231 }
232 
233 inline void GL512(const word64 x[8], word64 y[8], const word64 k[8])
234 {
235  y[0] = k[0] + (T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^
236  T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)]);
237  y[1] = k[1] + (T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^
238  T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)]);
239  y[2] = k[2] + (T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^
240  T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)]);
241  y[3] = k[3] + (T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
242  T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)]);
243  y[4] = k[4] + (T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
244  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)]);
245  y[5] = k[5] + (T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
246  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)]);
247  y[6] = k[6] + (T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
248  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)]);
249  y[7] = k[7] + (T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^
250  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)]);
251 }
252 
253 inline void IMC128(word64 x[2])
254 {
255  x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^
256  IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]];
257  x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^
258  IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]];
259 }
260 
261 inline void IMC256(word64 x[4])
262 {
263  x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^
264  IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]];
265  x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^
266  IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]];
267  x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^
268  IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]];
269  x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^
270  IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]];
271 }
272 
273 inline void IMC512(word64 x[8])
274 {
275  x[0] = IT[0][S[0][(byte)x[0]]] ^ IT[1][S[1][(byte)(x[0] >> 8)]] ^ IT[2][S[2][(byte)(x[0] >> 16)]] ^ IT[3][S[3][(byte)(x[0] >> 24)]] ^
276  IT[4][S[0][(byte)(x[0] >> 32)]] ^ IT[5][S[1][(byte)(x[0] >> 40)]] ^ IT[6][S[2][(byte)(x[0] >> 48)]] ^ IT[7][S[3][(byte)(x[0] >> 56)]];
277  x[1] = IT[0][S[0][(byte)x[1]]] ^ IT[1][S[1][(byte)(x[1] >> 8)]] ^ IT[2][S[2][(byte)(x[1] >> 16)]] ^ IT[3][S[3][(byte)(x[1] >> 24)]] ^
278  IT[4][S[0][(byte)(x[1] >> 32)]] ^ IT[5][S[1][(byte)(x[1] >> 40)]] ^ IT[6][S[2][(byte)(x[1] >> 48)]] ^ IT[7][S[3][(byte)(x[1] >> 56)]];
279  x[2] = IT[0][S[0][(byte)x[2]]] ^ IT[1][S[1][(byte)(x[2] >> 8)]] ^ IT[2][S[2][(byte)(x[2] >> 16)]] ^ IT[3][S[3][(byte)(x[2] >> 24)]] ^
280  IT[4][S[0][(byte)(x[2] >> 32)]] ^ IT[5][S[1][(byte)(x[2] >> 40)]] ^ IT[6][S[2][(byte)(x[2] >> 48)]] ^ IT[7][S[3][(byte)(x[2] >> 56)]];
281  x[3] = IT[0][S[0][(byte)x[3]]] ^ IT[1][S[1][(byte)(x[3] >> 8)]] ^ IT[2][S[2][(byte)(x[3] >> 16)]] ^ IT[3][S[3][(byte)(x[3] >> 24)]] ^
282  IT[4][S[0][(byte)(x[3] >> 32)]] ^ IT[5][S[1][(byte)(x[3] >> 40)]] ^ IT[6][S[2][(byte)(x[3] >> 48)]] ^ IT[7][S[3][(byte)(x[3] >> 56)]];
283  x[4] = IT[0][S[0][(byte)x[4]]] ^ IT[1][S[1][(byte)(x[4] >> 8)]] ^ IT[2][S[2][(byte)(x[4] >> 16)]] ^ IT[3][S[3][(byte)(x[4] >> 24)]] ^
284  IT[4][S[0][(byte)(x[4] >> 32)]] ^ IT[5][S[1][(byte)(x[4] >> 40)]] ^ IT[6][S[2][(byte)(x[4] >> 48)]] ^ IT[7][S[3][(byte)(x[4] >> 56)]];
285  x[5] = IT[0][S[0][(byte)x[5]]] ^ IT[1][S[1][(byte)(x[5] >> 8)]] ^ IT[2][S[2][(byte)(x[5] >> 16)]] ^ IT[3][S[3][(byte)(x[5] >> 24)]] ^
286  IT[4][S[0][(byte)(x[5] >> 32)]] ^ IT[5][S[1][(byte)(x[5] >> 40)]] ^ IT[6][S[2][(byte)(x[5] >> 48)]] ^ IT[7][S[3][(byte)(x[5] >> 56)]];
287  x[6] = IT[0][S[0][(byte)x[6]]] ^ IT[1][S[1][(byte)(x[6] >> 8)]] ^ IT[2][S[2][(byte)(x[6] >> 16)]] ^ IT[3][S[3][(byte)(x[6] >> 24)]] ^
288  IT[4][S[0][(byte)(x[6] >> 32)]] ^ IT[5][S[1][(byte)(x[6] >> 40)]] ^ IT[6][S[2][(byte)(x[6] >> 48)]] ^ IT[7][S[3][(byte)(x[6] >> 56)]];
289  x[7] = IT[0][S[0][(byte)x[7]]] ^ IT[1][S[1][(byte)(x[7] >> 8)]] ^ IT[2][S[2][(byte)(x[7] >> 16)]] ^ IT[3][S[3][(byte)(x[7] >> 24)]] ^
290  IT[4][S[0][(byte)(x[7] >> 32)]] ^ IT[5][S[1][(byte)(x[7] >> 40)]] ^ IT[6][S[2][(byte)(x[7] >> 48)]] ^ IT[7][S[3][(byte)(x[7] >> 56)]];
291 }
292 
293 inline void IG128(const word64 x[2], word64 y[2], const word64 k[2])
294 {
295  y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^
296  IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)];
297  y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^
298  IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)];
299 }
300 
301 inline void IG256(const word64 x[4], word64 y[4], const word64 k[4])
302 {
303  y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^
304  IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[3] >> 56)];
305  y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^
306  IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[0] >> 56)];
307  y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^
308  IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[1] >> 56)];
309  y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^
310  IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[2] >> 56)];
311 }
312 
313 inline void IG512(const word64 x[8], word64 y[8], const word64 k[8])
314 {
315  y[0] = k[0] ^ IT[0][(byte)x[0]] ^ IT[1][(byte)(x[1] >> 8)] ^ IT[2][(byte)(x[2] >> 16)] ^ IT[3][(byte)(x[3] >> 24)] ^
316  IT[4][(byte)(x[4] >> 32)] ^ IT[5][(byte)(x[5] >> 40)] ^ IT[6][(byte)(x[6] >> 48)] ^ IT[7][(byte)(x[7] >> 56)];
317  y[1] = k[1] ^ IT[0][(byte)x[1]] ^ IT[1][(byte)(x[2] >> 8)] ^ IT[2][(byte)(x[3] >> 16)] ^ IT[3][(byte)(x[4] >> 24)] ^
318  IT[4][(byte)(x[5] >> 32)] ^ IT[5][(byte)(x[6] >> 40)] ^ IT[6][(byte)(x[7] >> 48)] ^ IT[7][(byte)(x[0] >> 56)];
319  y[2] = k[2] ^ IT[0][(byte)x[2]] ^ IT[1][(byte)(x[3] >> 8)] ^ IT[2][(byte)(x[4] >> 16)] ^ IT[3][(byte)(x[5] >> 24)] ^
320  IT[4][(byte)(x[6] >> 32)] ^ IT[5][(byte)(x[7] >> 40)] ^ IT[6][(byte)(x[0] >> 48)] ^ IT[7][(byte)(x[1] >> 56)];
321  y[3] = k[3] ^ IT[0][(byte)x[3]] ^ IT[1][(byte)(x[4] >> 8)] ^ IT[2][(byte)(x[5] >> 16)] ^ IT[3][(byte)(x[6] >> 24)] ^
322  IT[4][(byte)(x[7] >> 32)] ^ IT[5][(byte)(x[0] >> 40)] ^ IT[6][(byte)(x[1] >> 48)] ^ IT[7][(byte)(x[2] >> 56)];
323  y[4] = k[4] ^ IT[0][(byte)x[4]] ^ IT[1][(byte)(x[5] >> 8)] ^ IT[2][(byte)(x[6] >> 16)] ^ IT[3][(byte)(x[7] >> 24)] ^
324  IT[4][(byte)(x[0] >> 32)] ^ IT[5][(byte)(x[1] >> 40)] ^ IT[6][(byte)(x[2] >> 48)] ^ IT[7][(byte)(x[3] >> 56)];
325  y[5] = k[5] ^ IT[0][(byte)x[5]] ^ IT[1][(byte)(x[6] >> 8)] ^ IT[2][(byte)(x[7] >> 16)] ^ IT[3][(byte)(x[0] >> 24)] ^
326  IT[4][(byte)(x[1] >> 32)] ^ IT[5][(byte)(x[2] >> 40)] ^ IT[6][(byte)(x[3] >> 48)] ^ IT[7][(byte)(x[4] >> 56)];
327  y[6] = k[6] ^ IT[0][(byte)x[6]] ^ IT[1][(byte)(x[7] >> 8)] ^ IT[2][(byte)(x[0] >> 16)] ^ IT[3][(byte)(x[1] >> 24)] ^
328  IT[4][(byte)(x[2] >> 32)] ^ IT[5][(byte)(x[3] >> 40)] ^ IT[6][(byte)(x[4] >> 48)] ^ IT[7][(byte)(x[5] >> 56)];
329  y[7] = k[7] ^ IT[0][(byte)x[7]] ^ IT[1][(byte)(x[0] >> 8)] ^ IT[2][(byte)(x[1] >> 16)] ^ IT[3][(byte)(x[2] >> 24)] ^
330  IT[4][(byte)(x[3] >> 32)] ^ IT[5][(byte)(x[4] >> 40)] ^ IT[6][(byte)(x[5] >> 48)] ^ IT[7][(byte)(x[6] >> 56)];
331 }
332 
333 inline void IGL128(const word64 x[2], word64 y[2], const word64 k[2])
334 {
335  y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^
336  word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[0];
337  y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^
338  word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1];
339 }
340 
341 inline void IGL256(const word64 x[4], word64 y[4], const word64 k[4])
342 {
343  y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^
344  word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[0];
345  y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^
346  word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1];
347  y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^
348  word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2];
349  y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^
350  word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3];
351 }
352 
353 inline void IGL512(const word64 x[8], word64 y[8], const word64 k[8])
354 {
355  y[0] = (word64(IS[0][(byte)x[0]]) ^ word64(IS[1][(byte)(x[1] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[2] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[3] >> 24)]) << 24 ^
356  word64(IS[0][(byte)(x[4] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[5] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[6] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[7] >> 56)]) << 56) - k[0];
357  y[1] = (word64(IS[0][(byte)x[1]]) ^ word64(IS[1][(byte)(x[2] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[3] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[4] >> 24)]) << 24 ^
358  word64(IS[0][(byte)(x[5] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[6] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[7] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[0] >> 56)]) << 56) - k[1];
359  y[2] = (word64(IS[0][(byte)x[2]]) ^ word64(IS[1][(byte)(x[3] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[4] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[5] >> 24)]) << 24 ^
360  word64(IS[0][(byte)(x[6] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[7] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[0] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[1] >> 56)]) << 56) - k[2];
361  y[3] = (word64(IS[0][(byte)x[3]]) ^ word64(IS[1][(byte)(x[4] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[5] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[6] >> 24)]) << 24 ^
362  word64(IS[0][(byte)(x[7] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[0] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[1] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[2] >> 56)]) << 56) - k[3];
363  y[4] = (word64(IS[0][(byte)x[4]]) ^ word64(IS[1][(byte)(x[5] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[6] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[7] >> 24)]) << 24 ^
364  word64(IS[0][(byte)(x[0] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[1] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[2] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[3] >> 56)]) << 56) - k[4];
365  y[5] = (word64(IS[0][(byte)x[5]]) ^ word64(IS[1][(byte)(x[6] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[7] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[0] >> 24)]) << 24 ^
366  word64(IS[0][(byte)(x[1] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[2] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[3] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[4] >> 56)]) << 56) - k[5];
367  y[6] = (word64(IS[0][(byte)x[6]]) ^ word64(IS[1][(byte)(x[7] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[0] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[1] >> 24)]) << 24 ^
368  word64(IS[0][(byte)(x[2] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[3] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[4] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[5] >> 56)]) << 56) - k[6];
369  y[7] = (word64(IS[0][(byte)x[7]]) ^ word64(IS[1][(byte)(x[0] >> 8)]) << 8 ^ word64(IS[2][(byte)(x[1] >> 16)]) << 16 ^ word64(IS[3][(byte)(x[2] >> 24)]) << 24 ^
370  word64(IS[0][(byte)(x[3] >> 32)]) << 32 ^ word64(IS[1][(byte)(x[4] >> 40)]) << 40 ^ word64(IS[2][(byte)(x[5] >> 48)]) << 48 ^ word64(IS[3][(byte)(x[6] >> 56)]) << 56) - k[7];
371 }
372 
373 inline void G128(const word64 x[2], word64 y[2], const word64 k[2])
374 {
375  y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
376  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
377  y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
378  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
379 }
380 
381 inline void G256(const word64 x[4], word64 y[4], const word64 k[4])
382 {
383  y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
384  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
385  y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
386  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[2] >> 56)];
387  y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
388  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[3] >> 56)];
389  y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
390  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
391 }
392 
393 inline void G512(const word64 x[8], word64 y[8], const word64 k[8])
394 {
395  y[0] = k[0] ^ T[0][(byte)x[0]] ^ T[1][(byte)(x[7] >> 8)] ^ T[2][(byte)(x[6] >> 16)] ^ T[3][(byte)(x[5] >> 24)] ^
396  T[4][(byte)(x[4] >> 32)] ^ T[5][(byte)(x[3] >> 40)] ^ T[6][(byte)(x[2] >> 48)] ^ T[7][(byte)(x[1] >> 56)];
397  y[1] = k[1] ^ T[0][(byte)x[1]] ^ T[1][(byte)(x[0] >> 8)] ^ T[2][(byte)(x[7] >> 16)] ^ T[3][(byte)(x[6] >> 24)] ^
398  T[4][(byte)(x[5] >> 32)] ^ T[5][(byte)(x[4] >> 40)] ^ T[6][(byte)(x[3] >> 48)] ^ T[7][(byte)(x[2] >> 56)];
399  y[2] = k[2] ^ T[0][(byte)x[2]] ^ T[1][(byte)(x[1] >> 8)] ^ T[2][(byte)(x[0] >> 16)] ^ T[3][(byte)(x[7] >> 24)] ^
400  T[4][(byte)(x[6] >> 32)] ^ T[5][(byte)(x[5] >> 40)] ^ T[6][(byte)(x[4] >> 48)] ^ T[7][(byte)(x[3] >> 56)];
401  y[3] = k[3] ^ T[0][(byte)x[3]] ^ T[1][(byte)(x[2] >> 8)] ^ T[2][(byte)(x[1] >> 16)] ^ T[3][(byte)(x[0] >> 24)] ^
402  T[4][(byte)(x[7] >> 32)] ^ T[5][(byte)(x[6] >> 40)] ^ T[6][(byte)(x[5] >> 48)] ^ T[7][(byte)(x[4] >> 56)];
403  y[4] = k[4] ^ T[0][(byte)x[4]] ^ T[1][(byte)(x[3] >> 8)] ^ T[2][(byte)(x[2] >> 16)] ^ T[3][(byte)(x[1] >> 24)] ^
404  T[4][(byte)(x[0] >> 32)] ^ T[5][(byte)(x[7] >> 40)] ^ T[6][(byte)(x[6] >> 48)] ^ T[7][(byte)(x[5] >> 56)];
405  y[5] = k[5] ^ T[0][(byte)x[5]] ^ T[1][(byte)(x[4] >> 8)] ^ T[2][(byte)(x[3] >> 16)] ^ T[3][(byte)(x[2] >> 24)] ^
406  T[4][(byte)(x[1] >> 32)] ^ T[5][(byte)(x[0] >> 40)] ^ T[6][(byte)(x[7] >> 48)] ^ T[7][(byte)(x[6] >> 56)];
407  y[6] = k[6] ^ T[0][(byte)x[6]] ^ T[1][(byte)(x[5] >> 8)] ^ T[2][(byte)(x[4] >> 16)] ^ T[3][(byte)(x[3] >> 24)] ^
408  T[4][(byte)(x[2] >> 32)] ^ T[5][(byte)(x[1] >> 40)] ^ T[6][(byte)(x[0] >> 48)] ^ T[7][(byte)(x[7] >> 56)];
409  y[7] = k[7] ^ T[0][(byte)x[7]] ^ T[1][(byte)(x[6] >> 8)] ^ T[2][(byte)(x[5] >> 16)] ^ T[3][(byte)(x[4] >> 24)] ^
410  T[4][(byte)(x[3] >> 32)] ^ T[5][(byte)(x[2] >> 40)] ^ T[6][(byte)(x[1] >> 48)] ^ T[7][(byte)(x[0] >> 56)];
411 }
412 
413 ANONYMOUS_NAMESPACE_END
414 
415 NAMESPACE_BEGIN(CryptoPP)
416 
417 // *********************** UncheckedSetKey specializations *********************** //
418 
419 void Kalyna128::Base::SetKey_22(const word64 key[2])
420 {
421  word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4;
422  word64 *t2 = m_wspace+6, *k = m_wspace+8, *kswapped = m_wspace+10;
423 
424  memset(t1, 0, 2*8);
425  t1[0] = (128 + 128 + 64) / 64;
426 
427  AddKey<2>(t1, t2, key);
428  G128(t2, t1, key);
429  GL128(t1, t2, key);
430  G0128(t2, ks);
431 
432  word64 constant = W64LIT(0x0001000100010001);
433 
434  // round 0
435  memcpy(k, key, 16);
436  kswapped[1] = k[0];
437  kswapped[0] = k[1];
438 
439  AddConstant<2>(ks, ksc, constant);
440  AddKey<2>(k, t2, ksc);
441  G128(t2, t1, ksc);
442  GL128(t1, &m_rkeys[0], ksc);
443  MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]);
444 
445  // round 2
446  constant <<= 1;
447  AddConstant<2>(ks, ksc, constant);
448  AddKey<2>(kswapped, t2, ksc);
449  G128(t2, t1, ksc);
450  GL128(t1, &m_rkeys[4], ksc);
451  MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]);
452 
453  // round 4
454  constant <<= 1;
455  AddConstant<2>(ks, ksc, constant);
456  AddKey<2>(k, t2, ksc);
457  G128(t2, t1, ksc);
458  GL128(t1, &m_rkeys[8], ksc);
459  MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]);
460 
461  // round 6
462  constant <<= 1;
463  AddConstant<2>(ks, ksc, constant);
464  AddKey<2>(kswapped, t2, ksc);
465  G128(t2, t1, ksc);
466  GL128(t1, &m_rkeys[12], ksc);
467  MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]);
468 
469  // round 8
470  constant <<= 1;
471  AddConstant<2>(ks, ksc, constant);
472  AddKey<2>(k, t2, ksc);
473  G128(t2, t1, ksc);
474  GL128(t1, &m_rkeys[16], ksc);
475  MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]);
476 
477  // round 10
478  constant <<= 1;
479  AddConstant<2>(ks, ksc, constant);
480  AddKey<2>(kswapped, t2, ksc);
481  G128(t2, t1, ksc);
482  GL128(t1, &m_rkeys[20], ksc);
483 
484  if (!IsForwardTransformation())
485  {
486  IMC128(&m_rkeys[18]); IMC128(&m_rkeys[16]);
487  IMC128(&m_rkeys[14]); IMC128(&m_rkeys[12]);
488  IMC128(&m_rkeys[10]); IMC128(&m_rkeys[ 8]);
489  IMC128(&m_rkeys[ 6]); IMC128(&m_rkeys[ 4]);
490  IMC128(&m_rkeys[ 2]);
491  }
492 }
493 
494 void Kalyna128::Base::SetKey_24(const word64 key[4])
495 {
496  word64 *ks = m_wspace+0, *ksc = m_wspace+2, *t1 = m_wspace+4, *t2 = m_wspace+6;
497  word64 *k = m_wspace+8, *ka = m_wspace+12, *ko = m_wspace+14;
498 
499  memset(t1, 0, 2*8);
500  t1[0] = (128 + 256 + 64) / 64;
501  memcpy(ka, key, 16);
502  memcpy(ko, key + 2, 16);
503 
504  AddKey<2>(t1, t2, ka);
505  G128(t2, t1, ko);
506  GL128(t1, t2, ka);
507  G0128(t2, ks);
508 
509  word64 constant = W64LIT(0x0001000100010001);
510 
511  // round 0
512  memcpy(k, key, 256 / 8);
513  AddConstant<2>(ks, ksc, constant);
514  AddKey<2>(k, t2, ksc);
515  G128(t2, t1, ksc);
516  GL128(t1, &m_rkeys[0], ksc);
517  MakeOddKey<2>(&m_rkeys[0], &m_rkeys[2]);
518 
519  // round 2
520  constant <<= 1;
521  AddConstant<2>(ks, ksc, constant);
522  AddKey<2>(k + 2, t2, ksc);
523  G128(t2, t1, ksc);
524  GL128(t1, &m_rkeys[4], ksc);
525  MakeOddKey<2>(&m_rkeys[4], &m_rkeys[6]);
526 
527  // round 4
528  SwapBlocks<4>(k);
529  constant <<= 1;
530  AddConstant<2>(ks, ksc, constant);
531  AddKey<2>(k, t2, ksc);
532  G128(t2, t1, ksc);
533  GL128(t1, &m_rkeys[8], ksc);
534  MakeOddKey<2>(&m_rkeys[8], &m_rkeys[10]);
535 
536  // round 6
537  constant <<= 1;
538  AddConstant<2>(ks, ksc, constant);
539  AddKey<2>(k + 2, t2, ksc);
540  G128(t2, t1, ksc);
541  GL128(t1, &m_rkeys[12], ksc);
542  MakeOddKey<2>(&m_rkeys[12], &m_rkeys[14]);
543 
544  // round 8
545  SwapBlocks<4>(k);
546  constant <<= 1;
547  AddConstant<2>(ks, ksc, constant);
548  AddKey<2>(k, t2, ksc);
549  G128(t2, t1, ksc);
550  GL128(t1, &m_rkeys[16], ksc);
551  MakeOddKey<2>(&m_rkeys[16], &m_rkeys[18]);
552 
553  // round 10
554  constant <<= 1;
555  AddConstant<2>(ks, ksc, constant);
556  AddKey<2>(k + 2, t2, ksc);
557  G128(t2, t1, ksc);
558  GL128(t1, &m_rkeys[20], ksc);
559  MakeOddKey<2>(&m_rkeys[20], &m_rkeys[22]);
560 
561  // round 12
562  SwapBlocks<4>(k);
563  constant <<= 1;
564  AddConstant<2>(ks, ksc, constant);
565  AddKey<2>(k, t2, ksc);
566  G128(t2, t1, ksc);
567  GL128(t1, &m_rkeys[24], ksc);
568  MakeOddKey<2>(&m_rkeys[24], &m_rkeys[26]);
569 
570  // round 14
571  constant <<= 1;
572  AddConstant<2>(ks, ksc, constant);
573  AddKey<2>(k + 2, t2, ksc);
574  G128(t2, t1, ksc);
575  GL128(t1, &m_rkeys[28], ksc);
576 
577  if (!IsForwardTransformation())
578  {
579  IMC128(&m_rkeys[26]);
580  IMC128(&m_rkeys[24]);
581  IMC128(&m_rkeys[22]);
582  IMC128(&m_rkeys[20]);
583  IMC128(&m_rkeys[18]);
584  IMC128(&m_rkeys[16]);
585  IMC128(&m_rkeys[14]);
586  IMC128(&m_rkeys[12]);
587  IMC128(&m_rkeys[10]);
588  IMC128(&m_rkeys[8]);
589  IMC128(&m_rkeys[6]);
590  IMC128(&m_rkeys[4]);
591  IMC128(&m_rkeys[2]);
592  }
593 }
594 
595 void Kalyna256::Base::SetKey_44(const word64 key[4])
596 {
597  word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8;
598  word64 *t2 = m_wspace+12, *k = m_wspace+16;
599 
600  memset(t1, 0, 32);
601  t1[0] = (256 + 256 + 64) / 64;
602 
603  AddKey<4>(t1, t2, key);
604  G256(t2, t1, key);
605  GL256(t1, t2, key);
606  G0256(t2, ks);
607 
608  word64 constant = W64LIT(0x0001000100010001);
609 
610  // round 0
611  memcpy(k, key, 32);
612  AddConstant<4>(ks, ksc, constant);
613  AddKey<4>(k, t2, ksc);
614  G256(t2, t1, ksc);
615  GL256(t1, &m_rkeys[0], ksc);
616  MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]);
617 
618  // round 2
619  SwapBlocks<4>(k);
620  constant <<= 1;
621  AddConstant<4>(ks, ksc, constant);
622  AddKey<4>(k, t2, ksc);
623  G256(t2, t1, ksc);
624  GL256(t1, &m_rkeys[8], ksc);
625  MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]);
626 
627  // round 4
628  SwapBlocks<4>(k);
629  constant <<= 1;
630  AddConstant<4>(ks, ksc, constant);
631  AddKey<4>(k, t2, ksc);
632  G256(t2, t1, ksc);
633  GL256(t1, &m_rkeys[16], ksc);
634  MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]);
635 
636  // round 6
637  SwapBlocks<4>(k);
638  constant <<= 1;
639  AddConstant<4>(ks, ksc, constant);
640  AddKey<4>(k, t2, ksc);
641  G256(t2, t1, ksc);
642  GL256(t1, &m_rkeys[24], ksc);
643  MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]);
644 
645  // round 8
646  SwapBlocks<4>(k);
647  constant <<= 1;
648  AddConstant<4>(ks, ksc, constant);
649  AddKey<4>(k, t2, ksc);
650  G256(t2, t1, ksc);
651  GL256(t1, &m_rkeys[32], ksc);
652  MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]);
653 
654  // round 10
655  SwapBlocks<4>(k);
656  constant <<= 1;
657  AddConstant<4>(ks, ksc, constant);
658  AddKey<4>(k, t2, ksc);
659  G256(t2, t1, ksc);
660  GL256(t1, &m_rkeys[40], ksc);
661  MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]);
662 
663  // round 12
664  SwapBlocks<4>(k);
665  constant <<= 1;
666  AddConstant<4>(ks, ksc, constant);
667  AddKey<4>(k, t2, ksc);
668  G256(t2, t1, ksc);
669  GL256(t1, &m_rkeys[48], ksc);
670  MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]);
671 
672  // round 14
673  SwapBlocks<4>(k);
674  constant <<= 1;
675  AddConstant<4>(ks, ksc, constant);
676  AddKey<4>(k, t2, ksc);
677  G256(t2, t1, ksc);
678  GL256(t1, &m_rkeys[56], ksc);
679 
680  if (!IsForwardTransformation())
681  {
682  IMC256(&m_rkeys[52]);
683  IMC256(&m_rkeys[48]);
684  IMC256(&m_rkeys[44]);
685  IMC256(&m_rkeys[40]);
686  IMC256(&m_rkeys[36]);
687  IMC256(&m_rkeys[32]);
688  IMC256(&m_rkeys[28]);
689  IMC256(&m_rkeys[24]);
690  IMC256(&m_rkeys[20]);
691  IMC256(&m_rkeys[16]);
692  IMC256(&m_rkeys[12]);
693  IMC256(&m_rkeys[8]);
694  IMC256(&m_rkeys[4]);
695  }
696 }
697 
698 void Kalyna256::Base::SetKey_48(const word64 key[8])
699 {
700  word64 *ks = m_wspace+0, *ksc = m_wspace+4, *t1 = m_wspace+8, *t2 = m_wspace+12;
701  word64 *k = m_wspace+16, *ka = m_wspace+24, *ko = m_wspace+28;
702 
703  memset(t1, 0, 4*8);
704  t1[0] = (512 + 256 + 64) / 64;
705  memcpy(ka, key, 32);
706  memcpy(ko, key+4, 32);
707 
708  AddKey<4>(t1, t2, ka);
709  G256(t2, t1, ko);
710  GL256(t1, t2, ka);
711  G0256(t2, ks);
712 
713  word64 constant = W64LIT(0x0001000100010001);
714 
715  // round 0
716  memcpy(k, key, 512 / 8);
717  AddConstant<4>(ks, ksc, constant);
718  AddKey<4>(k, t2, ksc);
719  G256(t2, t1, ksc);
720  GL256(t1, &m_rkeys[0], ksc);
721  MakeOddKey<4>(&m_rkeys[0], &m_rkeys[4]);
722 
723  // round 2
724  constant <<= 1;
725  AddConstant<4>(ks, ksc, constant);
726  AddKey<4>(k+4, t2, ksc);
727  G256(t2, t1, ksc);
728  GL256(t1, &m_rkeys[8], ksc);
729  MakeOddKey<4>(&m_rkeys[8], &m_rkeys[12]);
730 
731  // round 4
732  SwapBlocks<8>(k);
733  constant <<= 1;
734  AddConstant<4>(ks, ksc, constant);
735  AddKey<4>(k, t2, ksc);
736  G256(t2, t1, ksc);
737  GL256(t1, &m_rkeys[16], ksc);
738  MakeOddKey<4>(&m_rkeys[16], &m_rkeys[20]);
739 
740  // round 6
741  constant <<= 1;
742  AddConstant<4>(ks, ksc, constant);
743  AddKey<4>(k+4, t2, ksc);
744  G256(t2, t1, ksc);
745  GL256(t1, &m_rkeys[24], ksc);
746  MakeOddKey<4>(&m_rkeys[24], &m_rkeys[28]);
747 
748  // round 8
749  SwapBlocks<8>(k);
750  constant <<= 1;
751  AddConstant<4>(ks, ksc, constant);
752  AddKey<4>(k, t2, ksc);
753  G256(t2, t1, ksc);
754  GL256(t1, &m_rkeys[32], ksc);
755  MakeOddKey<4>(&m_rkeys[32], &m_rkeys[36]);
756 
757  // round 10
758  constant <<= 1;
759  AddConstant<4>(ks, ksc, constant);
760  AddKey<4>(k+4, t2, ksc);
761  G256(t2, t1, ksc);
762  GL256(t1, &m_rkeys[40], ksc);
763  MakeOddKey<4>(&m_rkeys[40], &m_rkeys[44]);
764 
765  // round 12
766  SwapBlocks<8>(k);
767  constant <<= 1;
768  AddConstant<4>(ks, ksc, constant);
769  AddKey<4>(k, t2, ksc);
770  G256(t2, t1, ksc);
771  GL256(t1, &m_rkeys[48], ksc);
772  MakeOddKey<4>(&m_rkeys[48], &m_rkeys[52]);
773 
774  // round 14
775  constant <<= 1;
776  AddConstant<4>(ks, ksc, constant);
777  AddKey<4>(k+4, t2, ksc);
778  G256(t2, t1, ksc);
779  GL256(t1, &m_rkeys[56], ksc);
780  MakeOddKey<4>(&m_rkeys[56], &m_rkeys[60]);
781 
782  // round 16
783  SwapBlocks<8>(k);
784  constant <<= 1;
785  AddConstant<4>(ks, ksc, constant);
786  AddKey<4>(k, t2, ksc);
787  G256(t2, t1, ksc);
788  GL256(t1, &m_rkeys[64], ksc);
789  MakeOddKey<4>(&m_rkeys[64], &m_rkeys[68]);
790 
791  // round 18
792  constant <<= 1;
793  AddConstant<4>(ks, ksc, constant);
794  AddKey<4>(k+4, t2, ksc);
795  G256(t2, t1, ksc);
796  GL256(t1, &m_rkeys[72], ksc);
797 
798  if (!IsForwardTransformation())
799  {
800  IMC256(&m_rkeys[68]);
801  IMC256(&m_rkeys[64]);
802  IMC256(&m_rkeys[60]);
803  IMC256(&m_rkeys[56]);
804  IMC256(&m_rkeys[52]);
805  IMC256(&m_rkeys[48]);
806  IMC256(&m_rkeys[44]);
807  IMC256(&m_rkeys[40]);
808  IMC256(&m_rkeys[36]);
809  IMC256(&m_rkeys[32]);
810  IMC256(&m_rkeys[28]);
811  IMC256(&m_rkeys[24]);
812  IMC256(&m_rkeys[20]);
813  IMC256(&m_rkeys[16]);
814  IMC256(&m_rkeys[12]);
815  IMC256(&m_rkeys[8]);
816  IMC256(&m_rkeys[4]);
817  }
818 }
819 
820 void Kalyna512::Base::SetKey_88(const word64 key[8])
821 {
822  word64 *ks = m_wspace+0, *ksc = m_wspace+8, *t1 = m_wspace+16;
823  word64 *t2 = m_wspace+24, *k = m_wspace+32;
824 
825  memset(t1, 0, 8*8);
826  t1[0] = (512 + 512 + 64) / 64;
827 
828  AddKey<8>(t1, t2, key);
829  G512(t2, t1, key);
830  GL512(t1, t2, key);
831  G0512(t2, ks);
832 
833  word64 constant = W64LIT(0x0001000100010001);
834 
835  // round 0
836  memcpy(k, key, 512 / 8);
837  AddConstant<8>(ks, ksc, constant);
838  AddKey<8>(k, t2, ksc);
839  G512(t2, t1, ksc);
840  GL512(t1, &m_rkeys[0], ksc);
841  MakeOddKey<8>(&m_rkeys[0], &m_rkeys[8]);
842 
843  // round 2
844  SwapBlocks<8>(k);
845  constant <<= 1;
846  AddConstant<8>(ks, ksc, constant);
847  AddKey<8>(k, t2, ksc);
848  G512(t2, t1, ksc);
849  GL512(t1, &m_rkeys[16], ksc);
850  MakeOddKey<8>(&m_rkeys[16], &m_rkeys[24]);
851 
852  // round 4
853  SwapBlocks<8>(k);
854  constant <<= 1;
855  AddConstant<8>(ks, ksc, constant);
856  AddKey<8>(k, t2, ksc);
857  G512(t2, t1, ksc);
858  GL512(t1, &m_rkeys[32], ksc);
859  MakeOddKey<8>(&m_rkeys[32], &m_rkeys[40]);
860 
861  // round 6
862  SwapBlocks<8>(k);
863  constant <<= 1;
864  AddConstant<8>(ks, ksc, constant);
865  AddKey<8>(k, t2, ksc);
866  G512(t2, t1, ksc);
867  GL512(t1, &m_rkeys[48], ksc);
868  MakeOddKey<8>(&m_rkeys[48], &m_rkeys[56]);
869 
870  // round 8
871  SwapBlocks<8>(k);
872  constant <<= 1;
873  AddConstant<8>(ks, ksc, constant);
874  AddKey<8>(k, t2, ksc);
875  G512(t2, t1, ksc);
876  GL512(t1, &m_rkeys[64], ksc);
877  MakeOddKey<8>(&m_rkeys[64], &m_rkeys[72]);
878 
879  // round 10
880  SwapBlocks<8>(k);
881  constant <<= 1;
882  AddConstant<8>(ks, ksc, constant);
883  AddKey<8>(k, t2, ksc);
884  G512(t2, t1, ksc);
885  GL512(t1, &m_rkeys[80], ksc);
886  MakeOddKey<8>(&m_rkeys[80], &m_rkeys[88]);
887 
888  // round 12
889  SwapBlocks<8>(k);
890  constant <<= 1;
891  AddConstant<8>(ks, ksc, constant);
892  AddKey<8>(k, t2, ksc);
893  G512(t2, t1, ksc);
894  GL512(t1, &m_rkeys[96], ksc);
895  MakeOddKey<8>(&m_rkeys[96], &m_rkeys[104]);
896 
897  // round 14
898  SwapBlocks<8>(k);
899  constant <<= 1;
900  AddConstant<8>(ks, ksc, constant);
901  AddKey<8>(k, t2, ksc);
902  G512(t2, t1, ksc);
903  GL512(t1, &m_rkeys[112], ksc);
904  MakeOddKey<8>(&m_rkeys[112], &m_rkeys[120]);
905 
906  // round 16
907  SwapBlocks<8>(k);
908  constant <<= 1;
909  AddConstant<8>(ks, ksc, constant);
910  AddKey<8>(k, t2, ksc);
911  G512(t2, t1, ksc);
912  GL512(t1, &m_rkeys[128], ksc);
913  MakeOddKey<8>(&m_rkeys[128], &m_rkeys[136]);
914 
915  // round 18
916  SwapBlocks<8>(k);
917  constant <<= 1;
918  AddConstant<8>(ks, ksc, constant);
919  AddKey<8>(k, t2, ksc);
920  G512(t2, t1, ksc);
921  GL512(t1, &m_rkeys[144], ksc);
922 
923  if (!IsForwardTransformation())
924  {
925  IMC512(&m_rkeys[136]); IMC512(&m_rkeys[128]); IMC512(&m_rkeys[120]); IMC512(&m_rkeys[112]);
926  IMC512(&m_rkeys[104]); IMC512(&m_rkeys[ 96]); IMC512(&m_rkeys[ 88]); IMC512(&m_rkeys[ 80]);
927  IMC512(&m_rkeys[ 72]); IMC512(&m_rkeys[ 64]); IMC512(&m_rkeys[ 56]); IMC512(&m_rkeys[ 48]);
928  IMC512(&m_rkeys[ 40]); IMC512(&m_rkeys[ 32]); IMC512(&m_rkeys[ 24]); IMC512(&m_rkeys[ 16]);
929  IMC512(&m_rkeys[ 8]);
930  }
931 }
932 
933 // *********************** ProcessAndXorBlock specializations *********************** //
934 
935 void Kalyna128::Base::ProcessBlock_22(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
936 {
937  word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;
938 
939  // Reverse bytes on BigEndian; Align pointer on LittleEndian
941  InBlock iblk(inBlock);
942  iblk(msg[0])(msg[1]);
943 
944  inBlock = msg;
945  if (IsForwardTransformation())
946  {
947  AddKey<2>(inBlock, t1, m_rkeys);
948  G128(t1, t2, &m_rkeys[2]); // 1
949  G128(t2, t1, &m_rkeys[4]); // 2
950  G128(t1, t2, &m_rkeys[6]); // 3
951  G128(t2, t1, &m_rkeys[8]); // 4
952  G128(t1, t2, &m_rkeys[10]); // 5
953  G128(t2, t1, &m_rkeys[12]); // 6
954  G128(t1, t2, &m_rkeys[14]); // 7
955  G128(t2, t1, &m_rkeys[16]); // 8
956  G128(t1, t2, &m_rkeys[18]); // 9
957  GL128(t2, t1, &m_rkeys[20]); // 10
958  }
959  else
960  {
961  SubKey<2>(inBlock, t1, &m_rkeys[20]);
962  IMC128(t1);
963  IG128(t1, t2, &m_rkeys[18]);
964  IG128(t2, t1, &m_rkeys[16]);
965  IG128(t1, t2, &m_rkeys[14]);
966  IG128(t2, t1, &m_rkeys[12]);
967  IG128(t1, t2, &m_rkeys[10]);
968  IG128(t2, t1, &m_rkeys[8]);
969  IG128(t1, t2, &m_rkeys[6]);
970  IG128(t2, t1, &m_rkeys[4]);
971  IG128(t1, t2, &m_rkeys[2]);
972  IGL128(t2, t1, &m_rkeys[0]);
973  }
974 
975  // Reverse bytes on BigEndian; Align pointer on LittleEndian
976  typedef PutBlock<word64, LittleEndian, false> OutBlock;
977  OutBlock oblk(xorBlock, outBlock);
978  oblk(t1[0])(t1[1]);
979 }
980 
981 void Kalyna128::Base::ProcessBlock_24(const word64 inBlock[2], const word64 xorBlock[2], word64 outBlock[2]) const
982 {
983  word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;
984 
985  // Reverse bytes on BigEndian; Align pointer on LittleEndian
987  InBlock iblk(inBlock);
988  iblk(msg[0])(msg[1]);
989 
990  inBlock = msg;
991  if (IsForwardTransformation())
992  {
993  AddKey<2>(inBlock, t1, m_rkeys);
994  G128(t1, t2, &m_rkeys[ 2]); // 1
995  G128(t2, t1, &m_rkeys[ 4]); // 2
996  G128(t1, t2, &m_rkeys[ 6]); // 3
997  G128(t2, t1, &m_rkeys[ 8]); // 4
998  G128(t1, t2, &m_rkeys[10]); // 5
999  G128(t2, t1, &m_rkeys[12]); // 6
1000  G128(t1, t2, &m_rkeys[14]); // 7
1001  G128(t2, t1, &m_rkeys[16]); // 8
1002  G128(t1, t2, &m_rkeys[18]); // 9
1003  G128(t2, t1, &m_rkeys[20]); // 10
1004  G128(t1, t2, &m_rkeys[22]); // 11
1005  G128(t2, t1, &m_rkeys[24]); // 12
1006  G128(t1, t2, &m_rkeys[26]); // 13
1007  GL128(t2, t1, &m_rkeys[28]); // 14
1008  }
1009  else
1010  {
1011  SubKey<2>(inBlock, t1, &m_rkeys[28]);
1012  IMC128(t1);
1013  IG128(t1, t2, &m_rkeys[26]);
1014  IG128(t2, t1, &m_rkeys[24]);
1015  IG128(t1, t2, &m_rkeys[22]);
1016  IG128(t2, t1, &m_rkeys[20]);
1017  IG128(t1, t2, &m_rkeys[18]);
1018  IG128(t2, t1, &m_rkeys[16]);
1019  IG128(t1, t2, &m_rkeys[14]);
1020  IG128(t2, t1, &m_rkeys[12]);
1021  IG128(t1, t2, &m_rkeys[10]);
1022  IG128(t2, t1, &m_rkeys[8]);
1023  IG128(t1, t2, &m_rkeys[6]);
1024  IG128(t2, t1, &m_rkeys[4]);
1025  IG128(t1, t2, &m_rkeys[2]);
1026  IGL128(t2, t1, &m_rkeys[0]);
1027  }
1028 
1029  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1030  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1031  OutBlock oblk(xorBlock, outBlock);
1032  oblk(t1[0])(t1[1]);
1033 }
1034 
1035 void Kalyna256::Base::ProcessBlock_44(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
1036 {
1037  word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
1038 
1039  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1040  typedef GetBlock<word64, LittleEndian, false> InBlock;
1041  InBlock iblk(inBlock);
1042  iblk(msg[0])(msg[1])(msg[2])(msg[3]);
1043 
1044  inBlock = msg;
1045  if (IsForwardTransformation())
1046  {
1047  AddKey<4>(inBlock, t1, m_rkeys);
1048  G256(t1, t2, &m_rkeys[4]); // 1
1049  G256(t2, t1, &m_rkeys[8]); // 2
1050  G256(t1, t2, &m_rkeys[12]); // 3
1051  G256(t2, t1, &m_rkeys[16]); // 4
1052  G256(t1, t2, &m_rkeys[20]); // 5
1053  G256(t2, t1, &m_rkeys[24]); // 6
1054  G256(t1, t2, &m_rkeys[28]); // 7
1055  G256(t2, t1, &m_rkeys[32]); // 8
1056  G256(t1, t2, &m_rkeys[36]); // 9
1057  G256(t2, t1, &m_rkeys[40]); // 10
1058  G256(t1, t2, &m_rkeys[44]); // 11
1059  G256(t2, t1, &m_rkeys[48]); // 12
1060  G256(t1, t2, &m_rkeys[52]); // 13
1061  GL256(t2, t1, &m_rkeys[56]); // 14
1062  }
1063  else
1064  {
1065  SubKey<4>(inBlock, t1, &m_rkeys[56]);
1066  IMC256(t1);
1067  IG256(t1, t2, &m_rkeys[52]);
1068  IG256(t2, t1, &m_rkeys[48]);
1069  IG256(t1, t2, &m_rkeys[44]);
1070  IG256(t2, t1, &m_rkeys[40]);
1071  IG256(t1, t2, &m_rkeys[36]);
1072  IG256(t2, t1, &m_rkeys[32]);
1073  IG256(t1, t2, &m_rkeys[28]);
1074  IG256(t2, t1, &m_rkeys[24]);
1075  IG256(t1, t2, &m_rkeys[20]);
1076  IG256(t2, t1, &m_rkeys[16]);
1077  IG256(t1, t2, &m_rkeys[12]);
1078  IG256(t2, t1, &m_rkeys[8]);
1079  IG256(t1, t2, &m_rkeys[4]);
1080  IGL256(t2, t1, &m_rkeys[0]);
1081  }
1082 
1083  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1084  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1085  OutBlock oblk(xorBlock, outBlock);
1086  oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1087 }
1088 
1089 void Kalyna256::Base::ProcessBlock_48(const word64 inBlock[4], const word64 xorBlock[4], word64 outBlock[4]) const
1090 {
1091  word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
1092 
1093  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1094  typedef GetBlock<word64, LittleEndian, false> InBlock;
1095  InBlock iblk(inBlock);
1096  iblk(msg[0])(msg[1])(msg[2])(msg[3]);
1097 
1098  inBlock = msg;
1099  if (IsForwardTransformation())
1100  {
1101  AddKey<4>(inBlock, t1, m_rkeys);
1102  G256(t1, t2, &m_rkeys[4]); // 1
1103  G256(t2, t1, &m_rkeys[8]); // 2
1104  G256(t1, t2, &m_rkeys[12]); // 3
1105  G256(t2, t1, &m_rkeys[16]); // 4
1106  G256(t1, t2, &m_rkeys[20]); // 5
1107  G256(t2, t1, &m_rkeys[24]); // 6
1108  G256(t1, t2, &m_rkeys[28]); // 7
1109  G256(t2, t1, &m_rkeys[32]); // 8
1110  G256(t1, t2, &m_rkeys[36]); // 9
1111  G256(t2, t1, &m_rkeys[40]); // 10
1112  G256(t1, t2, &m_rkeys[44]); // 11
1113  G256(t2, t1, &m_rkeys[48]); // 12
1114  G256(t1, t2, &m_rkeys[52]); // 13
1115  G256(t2, t1, &m_rkeys[56]); // 14
1116  G256(t1, t2, &m_rkeys[60]); // 15
1117  G256(t2, t1, &m_rkeys[64]); // 16
1118  G256(t1, t2, &m_rkeys[68]); // 17
1119  GL256(t2, t1, &m_rkeys[72]); // 18
1120  }
1121  else
1122  {
1123  SubKey<4>(inBlock, t1, &m_rkeys[72]);
1124  IMC256(t1);
1125  IG256(t1, t2, &m_rkeys[68]);
1126  IG256(t2, t1, &m_rkeys[64]);
1127  IG256(t1, t2, &m_rkeys[60]);
1128  IG256(t2, t1, &m_rkeys[56]);
1129  IG256(t1, t2, &m_rkeys[52]);
1130  IG256(t2, t1, &m_rkeys[48]);
1131  IG256(t1, t2, &m_rkeys[44]);
1132  IG256(t2, t1, &m_rkeys[40]);
1133  IG256(t1, t2, &m_rkeys[36]);
1134  IG256(t2, t1, &m_rkeys[32]);
1135  IG256(t1, t2, &m_rkeys[28]);
1136  IG256(t2, t1, &m_rkeys[24]);
1137  IG256(t1, t2, &m_rkeys[20]);
1138  IG256(t2, t1, &m_rkeys[16]);
1139  IG256(t1, t2, &m_rkeys[12]);
1140  IG256(t2, t1, &m_rkeys[8]);
1141  IG256(t1, t2, &m_rkeys[4]);
1142  IGL256(t2, t1, &m_rkeys[0]);
1143  }
1144 
1145  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1146  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1147  OutBlock oblk(xorBlock, outBlock);
1148  oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1149 }
1150 
1151 void Kalyna512::Base::ProcessBlock_88(const word64 inBlock[8], const word64 xorBlock[8], word64 outBlock[8]) const
1152 {
1153  word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16;
1154 
1155  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1156  typedef GetBlock<word64, LittleEndian, false> InBlock;
1157  InBlock iblk(inBlock);
1158  iblk(msg[0])(msg[1])(msg[2])(msg[3])(msg[4])(msg[5])(msg[6])(msg[7]);
1159 
1160  inBlock = msg;
1161  if (IsForwardTransformation())
1162  {
1163  AddKey<8>(inBlock, t1, m_rkeys);
1164  G512(t1, t2, &m_rkeys[8]); // 1
1165  G512(t2, t1, &m_rkeys[16]); // 2
1166  G512(t1, t2, &m_rkeys[24]); // 3
1167  G512(t2, t1, &m_rkeys[32]); // 4
1168  G512(t1, t2, &m_rkeys[40]); // 5
1169  G512(t2, t1, &m_rkeys[48]); // 6
1170  G512(t1, t2, &m_rkeys[56]); // 7
1171  G512(t2, t1, &m_rkeys[64]); // 8
1172  G512(t1, t2, &m_rkeys[72]); // 9
1173  G512(t2, t1, &m_rkeys[80]); // 10
1174  G512(t1, t2, &m_rkeys[88]); // 11
1175  G512(t2, t1, &m_rkeys[96]); // 12
1176  G512(t1, t2, &m_rkeys[104]); // 13
1177  G512(t2, t1, &m_rkeys[112]); // 14
1178  G512(t1, t2, &m_rkeys[120]); // 15
1179  G512(t2, t1, &m_rkeys[128]); // 16
1180  G512(t1, t2, &m_rkeys[136]); // 17
1181  GL512(t2, t1, &m_rkeys[144]); // 18
1182  }
1183  else
1184  {
1185  SubKey<8>(inBlock, t1, &m_rkeys[144]);
1186  IMC512(t1);
1187  IG512(t1, t2, &m_rkeys[136]);
1188  IG512(t2, t1, &m_rkeys[128]);
1189  IG512(t1, t2, &m_rkeys[120]);
1190  IG512(t2, t1, &m_rkeys[112]);
1191  IG512(t1, t2, &m_rkeys[104]);
1192  IG512(t2, t1, &m_rkeys[96]);
1193  IG512(t1, t2, &m_rkeys[88]);
1194  IG512(t2, t1, &m_rkeys[80]);
1195  IG512(t1, t2, &m_rkeys[72]);
1196  IG512(t2, t1, &m_rkeys[64]);
1197  IG512(t1, t2, &m_rkeys[56]);
1198  IG512(t2, t1, &m_rkeys[48]);
1199  IG512(t1, t2, &m_rkeys[40]);
1200  IG512(t2, t1, &m_rkeys[32]);
1201  IG512(t1, t2, &m_rkeys[24]);
1202  IG512(t2, t1, &m_rkeys[16]);
1203  IG512(t1, t2, &m_rkeys[8]);
1204  IGL512(t2, t1, &m_rkeys[0]);
1205  }
1206 
1207  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1208  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1209  OutBlock oblk(xorBlock, outBlock);
1210  oblk(t1[0])(t1[1])(t1[2])(t1[3])(t1[4])(t1[5])(t1[6])(t1[7]);
1211 }
1212 
1213 // *********************** Library routines *********************** //
1214 
1215 void Kalyna128::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1216 {
1217  CRYPTOPP_UNUSED(params);
1218  m_nb = static_cast<unsigned int>(16U / sizeof(word64));
1219  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1220 
1221  switch (keylen)
1222  {
1223  case 16: // 128
1224  m_kl = 16;
1225  m_mkey.New(2);
1226  m_rkeys.New(11*2);
1227  m_wspace.New(2*6);
1228 
1229  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16);
1230  SetKey_22(m_mkey.begin());
1231  break;
1232  case 32: // 256
1233  m_kl = 32;
1234  m_mkey.New(4);
1235  m_rkeys.New(15*2);
1236  m_wspace.New(6*2+4);
1237 
1238  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
1239  SetKey_24(m_mkey.begin());
1240  break;
1241  default:
1242  CRYPTOPP_ASSERT(0);
1243  }
1244 }
1245 
1246 void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1247 {
1248  // Timing attack countermeasure. see comments in Rijndael for more details
1249  const int cacheLineSize = GetCacheLineSize();
1250  volatile word64 _u = 0;
1251  word64 u = _u;
1252 
1253  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1254  for (unsigned int i=0; i<256; i+=cacheLineSize)
1255  u ^= *reinterpret_cast<const word64*>(p+i);
1256  m_wspace[0] = u;
1257 
1258  switch ((m_nb << 8) | m_nk)
1259  {
1260  case (2 << 8) | 2:
1261  ProcessBlock_22(reinterpret_cast<const word64*>(inBlock),
1262  reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
1263  break;
1264  case (2 << 8) | 4:
1265  ProcessBlock_24(reinterpret_cast<const word64*>(inBlock),
1266  reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
1267  break;
1268  default:
1269  CRYPTOPP_ASSERT(0);
1270  }
1271 }
1272 
1273 void Kalyna256::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1274 {
1275  CRYPTOPP_UNUSED(params);
1276  m_nb = static_cast<unsigned int>(32U / sizeof(word64));
1277  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1278 
1279  switch (keylen)
1280  {
1281  case 32: // 256
1282  m_kl = 32;
1283  m_mkey.New(4);
1284  m_rkeys.New(15*4);
1285  m_wspace.New(5*4);
1286 
1287  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
1288  SetKey_44(m_mkey.begin());
1289  break;
1290  case 64: // 512
1291  m_kl = 64;
1292  m_mkey.New(8);
1293  m_rkeys.New(19*4);
1294  m_wspace.New(6*4+8);
1295 
1296  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
1297  SetKey_48(m_mkey.begin());
1298  break;
1299  default:
1300  CRYPTOPP_ASSERT(0);
1301  }
1302 }
1303 
1304 void Kalyna256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1305 {
1306  // Timing attack countermeasure. see comments in Rijndael for more details
1307  const int cacheLineSize = GetCacheLineSize();
1308  volatile word64 _u = 0;
1309  word64 u = _u;
1310 
1311  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1312  for (unsigned int i=0; i<256; i+=cacheLineSize)
1313  u ^= *reinterpret_cast<const word64*>(p+i);
1314  m_wspace[0] = u;
1315 
1316  switch ((m_nb << 8) | m_nk)
1317  {
1318  case (4 << 8) | 4:
1319  ProcessBlock_44(reinterpret_cast<const word64*>(inBlock),
1320  reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
1321  break;
1322  case (4 << 8) | 8:
1323  ProcessBlock_48(reinterpret_cast<const word64*>(inBlock),
1324  reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
1325  break;
1326  default:
1327  CRYPTOPP_ASSERT(0);
1328  }
1329 }
1330 
1331 void Kalyna512::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1332 {
1333  CRYPTOPP_UNUSED(params);
1334  m_nb = static_cast<unsigned int>(64U / sizeof(word64));
1335  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1336 
1337  switch (keylen)
1338  {
1339  case 64: // 512
1340  m_kl = 64;
1341  m_nb = static_cast<unsigned int>(64U / sizeof(word64));
1342  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1343 
1344  m_mkey.New(8);
1345  m_rkeys.New(19*8);
1346  m_wspace.New(5*8);
1347 
1348  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
1349  SetKey_88(m_mkey.begin());
1350  break;
1351  default:
1352  CRYPTOPP_ASSERT(0);
1353  }
1354 }
1355 
1356 void Kalyna512::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1357 {
1358  // Timing attack countermeasure. see comments in Rijndael for more details
1359  const int cacheLineSize = GetCacheLineSize();
1360  volatile word64 _u = 0;
1361  word64 u = _u;
1362 
1363  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1364  for (unsigned int i=0; i<256; i+=cacheLineSize)
1365  u ^= *reinterpret_cast<const word64*>(p+i);
1366  m_wspace[0] = u;
1367 
1368  ProcessBlock_88(reinterpret_cast<const word64*>(inBlock),
1369  reinterpret_cast<const word64*>(xorBlock), reinterpret_cast<word64*>(outBlock));
1370 }
1371 
1372 NAMESPACE_END
Standard names for retrieving values by name when working with NameValuePairs.
Utility functions for the Crypto++ library.
Library configuration file.
int GetCacheLineSize()
Provides the cache line size.
Definition: cpu.h:328
byte order is little-endian
Definition: cryptlib.h:145
Precompiled header file.
Classes for the Kalyna block cipher.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
Functions for CPU features and intrinsics.
Access a block of memory.
Definition: misc.h:2454
Access a block of memory.
Definition: misc.h:2495
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:293