Crypto++  8.6
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 byte* inBlock, const byte* xorBlock, byte* outBlock) 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  if (IsForwardTransformation())
945  {
946  AddKey<2>(msg, t1, m_rkeys);
947  G128(t1, t2, &m_rkeys[2]); // 1
948  G128(t2, t1, &m_rkeys[4]); // 2
949  G128(t1, t2, &m_rkeys[6]); // 3
950  G128(t2, t1, &m_rkeys[8]); // 4
951  G128(t1, t2, &m_rkeys[10]); // 5
952  G128(t2, t1, &m_rkeys[12]); // 6
953  G128(t1, t2, &m_rkeys[14]); // 7
954  G128(t2, t1, &m_rkeys[16]); // 8
955  G128(t1, t2, &m_rkeys[18]); // 9
956  GL128(t2, t1, &m_rkeys[20]); // 10
957  }
958  else
959  {
960  SubKey<2>(msg, t1, &m_rkeys[20]);
961  IMC128(t1);
962  IG128(t1, t2, &m_rkeys[18]);
963  IG128(t2, t1, &m_rkeys[16]);
964  IG128(t1, t2, &m_rkeys[14]);
965  IG128(t2, t1, &m_rkeys[12]);
966  IG128(t1, t2, &m_rkeys[10]);
967  IG128(t2, t1, &m_rkeys[8]);
968  IG128(t1, t2, &m_rkeys[6]);
969  IG128(t2, t1, &m_rkeys[4]);
970  IG128(t1, t2, &m_rkeys[2]);
971  IGL128(t2, t1, &m_rkeys[0]);
972  }
973 
974  // Reverse bytes on BigEndian; Align pointer on LittleEndian
975  typedef PutBlock<word64, LittleEndian, false> OutBlock;
976  OutBlock oblk(xorBlock, outBlock);
977  oblk(t1[0])(t1[1]);
978 }
979 
980 void Kalyna128::Base::ProcessBlock_24(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
981 {
982  word64 *t1 = m_wspace+0, *t2 = m_wspace+2, *msg = m_wspace+4;
983 
984  // Reverse bytes on BigEndian; Align pointer on LittleEndian
986  InBlock iblk(inBlock);
987  iblk(msg[0])(msg[1]);
988 
989  if (IsForwardTransformation())
990  {
991  AddKey<2>(msg, t1, m_rkeys);
992  G128(t1, t2, &m_rkeys[ 2]); // 1
993  G128(t2, t1, &m_rkeys[ 4]); // 2
994  G128(t1, t2, &m_rkeys[ 6]); // 3
995  G128(t2, t1, &m_rkeys[ 8]); // 4
996  G128(t1, t2, &m_rkeys[10]); // 5
997  G128(t2, t1, &m_rkeys[12]); // 6
998  G128(t1, t2, &m_rkeys[14]); // 7
999  G128(t2, t1, &m_rkeys[16]); // 8
1000  G128(t1, t2, &m_rkeys[18]); // 9
1001  G128(t2, t1, &m_rkeys[20]); // 10
1002  G128(t1, t2, &m_rkeys[22]); // 11
1003  G128(t2, t1, &m_rkeys[24]); // 12
1004  G128(t1, t2, &m_rkeys[26]); // 13
1005  GL128(t2, t1, &m_rkeys[28]); // 14
1006  }
1007  else
1008  {
1009  SubKey<2>(msg, t1, &m_rkeys[28]);
1010  IMC128(t1);
1011  IG128(t1, t2, &m_rkeys[26]);
1012  IG128(t2, t1, &m_rkeys[24]);
1013  IG128(t1, t2, &m_rkeys[22]);
1014  IG128(t2, t1, &m_rkeys[20]);
1015  IG128(t1, t2, &m_rkeys[18]);
1016  IG128(t2, t1, &m_rkeys[16]);
1017  IG128(t1, t2, &m_rkeys[14]);
1018  IG128(t2, t1, &m_rkeys[12]);
1019  IG128(t1, t2, &m_rkeys[10]);
1020  IG128(t2, t1, &m_rkeys[8]);
1021  IG128(t1, t2, &m_rkeys[6]);
1022  IG128(t2, t1, &m_rkeys[4]);
1023  IG128(t1, t2, &m_rkeys[2]);
1024  IGL128(t2, t1, &m_rkeys[0]);
1025  }
1026 
1027  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1028  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1029  OutBlock oblk(xorBlock, outBlock);
1030  oblk(t1[0])(t1[1]);
1031 }
1032 
1033 void Kalyna256::Base::ProcessBlock_44(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1034 {
1035  word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
1036 
1037  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1038  typedef GetBlock<word64, LittleEndian, false> InBlock;
1039  InBlock iblk(inBlock);
1040  iblk(msg[0])(msg[1])(msg[2])(msg[3]);
1041 
1042  if (IsForwardTransformation())
1043  {
1044  AddKey<4>(msg, t1, m_rkeys);
1045  G256(t1, t2, &m_rkeys[4]); // 1
1046  G256(t2, t1, &m_rkeys[8]); // 2
1047  G256(t1, t2, &m_rkeys[12]); // 3
1048  G256(t2, t1, &m_rkeys[16]); // 4
1049  G256(t1, t2, &m_rkeys[20]); // 5
1050  G256(t2, t1, &m_rkeys[24]); // 6
1051  G256(t1, t2, &m_rkeys[28]); // 7
1052  G256(t2, t1, &m_rkeys[32]); // 8
1053  G256(t1, t2, &m_rkeys[36]); // 9
1054  G256(t2, t1, &m_rkeys[40]); // 10
1055  G256(t1, t2, &m_rkeys[44]); // 11
1056  G256(t2, t1, &m_rkeys[48]); // 12
1057  G256(t1, t2, &m_rkeys[52]); // 13
1058  GL256(t2, t1, &m_rkeys[56]); // 14
1059  }
1060  else
1061  {
1062  SubKey<4>(msg, t1, &m_rkeys[56]);
1063  IMC256(t1);
1064  IG256(t1, t2, &m_rkeys[52]);
1065  IG256(t2, t1, &m_rkeys[48]);
1066  IG256(t1, t2, &m_rkeys[44]);
1067  IG256(t2, t1, &m_rkeys[40]);
1068  IG256(t1, t2, &m_rkeys[36]);
1069  IG256(t2, t1, &m_rkeys[32]);
1070  IG256(t1, t2, &m_rkeys[28]);
1071  IG256(t2, t1, &m_rkeys[24]);
1072  IG256(t1, t2, &m_rkeys[20]);
1073  IG256(t2, t1, &m_rkeys[16]);
1074  IG256(t1, t2, &m_rkeys[12]);
1075  IG256(t2, t1, &m_rkeys[8]);
1076  IG256(t1, t2, &m_rkeys[4]);
1077  IGL256(t2, t1, &m_rkeys[0]);
1078  }
1079 
1080  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1081  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1082  OutBlock oblk(xorBlock, outBlock);
1083  oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1084 }
1085 
1086 void Kalyna256::Base::ProcessBlock_48(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1087 {
1088  word64 *t1 = m_wspace+0, *t2 = m_wspace+4, *msg = m_wspace+8;
1089 
1090  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1091  typedef GetBlock<word64, LittleEndian, false> InBlock;
1092  InBlock iblk(inBlock);
1093  iblk(msg[0])(msg[1])(msg[2])(msg[3]);
1094 
1095  if (IsForwardTransformation())
1096  {
1097  AddKey<4>(msg, t1, m_rkeys);
1098  G256(t1, t2, &m_rkeys[4]); // 1
1099  G256(t2, t1, &m_rkeys[8]); // 2
1100  G256(t1, t2, &m_rkeys[12]); // 3
1101  G256(t2, t1, &m_rkeys[16]); // 4
1102  G256(t1, t2, &m_rkeys[20]); // 5
1103  G256(t2, t1, &m_rkeys[24]); // 6
1104  G256(t1, t2, &m_rkeys[28]); // 7
1105  G256(t2, t1, &m_rkeys[32]); // 8
1106  G256(t1, t2, &m_rkeys[36]); // 9
1107  G256(t2, t1, &m_rkeys[40]); // 10
1108  G256(t1, t2, &m_rkeys[44]); // 11
1109  G256(t2, t1, &m_rkeys[48]); // 12
1110  G256(t1, t2, &m_rkeys[52]); // 13
1111  G256(t2, t1, &m_rkeys[56]); // 14
1112  G256(t1, t2, &m_rkeys[60]); // 15
1113  G256(t2, t1, &m_rkeys[64]); // 16
1114  G256(t1, t2, &m_rkeys[68]); // 17
1115  GL256(t2, t1, &m_rkeys[72]); // 18
1116  }
1117  else
1118  {
1119  SubKey<4>(msg, t1, &m_rkeys[72]);
1120  IMC256(t1);
1121  IG256(t1, t2, &m_rkeys[68]);
1122  IG256(t2, t1, &m_rkeys[64]);
1123  IG256(t1, t2, &m_rkeys[60]);
1124  IG256(t2, t1, &m_rkeys[56]);
1125  IG256(t1, t2, &m_rkeys[52]);
1126  IG256(t2, t1, &m_rkeys[48]);
1127  IG256(t1, t2, &m_rkeys[44]);
1128  IG256(t2, t1, &m_rkeys[40]);
1129  IG256(t1, t2, &m_rkeys[36]);
1130  IG256(t2, t1, &m_rkeys[32]);
1131  IG256(t1, t2, &m_rkeys[28]);
1132  IG256(t2, t1, &m_rkeys[24]);
1133  IG256(t1, t2, &m_rkeys[20]);
1134  IG256(t2, t1, &m_rkeys[16]);
1135  IG256(t1, t2, &m_rkeys[12]);
1136  IG256(t2, t1, &m_rkeys[8]);
1137  IG256(t1, t2, &m_rkeys[4]);
1138  IGL256(t2, t1, &m_rkeys[0]);
1139  }
1140 
1141  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1142  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1143  OutBlock oblk(xorBlock, outBlock);
1144  oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1145 }
1146 
1147 void Kalyna512::Base::ProcessBlock_88(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1148 {
1149  word64 *t1 = m_wspace+0, *t2 = m_wspace+8, *msg = m_wspace+16;
1150 
1151  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1152  typedef GetBlock<word64, LittleEndian, false> InBlock;
1153  InBlock iblk(inBlock);
1154  iblk(msg[0])(msg[1])(msg[2])(msg[3])(msg[4])(msg[5])(msg[6])(msg[7]);
1155 
1156  if (IsForwardTransformation())
1157  {
1158  AddKey<8>(msg, t1, m_rkeys);
1159  G512(t1, t2, &m_rkeys[8]); // 1
1160  G512(t2, t1, &m_rkeys[16]); // 2
1161  G512(t1, t2, &m_rkeys[24]); // 3
1162  G512(t2, t1, &m_rkeys[32]); // 4
1163  G512(t1, t2, &m_rkeys[40]); // 5
1164  G512(t2, t1, &m_rkeys[48]); // 6
1165  G512(t1, t2, &m_rkeys[56]); // 7
1166  G512(t2, t1, &m_rkeys[64]); // 8
1167  G512(t1, t2, &m_rkeys[72]); // 9
1168  G512(t2, t1, &m_rkeys[80]); // 10
1169  G512(t1, t2, &m_rkeys[88]); // 11
1170  G512(t2, t1, &m_rkeys[96]); // 12
1171  G512(t1, t2, &m_rkeys[104]); // 13
1172  G512(t2, t1, &m_rkeys[112]); // 14
1173  G512(t1, t2, &m_rkeys[120]); // 15
1174  G512(t2, t1, &m_rkeys[128]); // 16
1175  G512(t1, t2, &m_rkeys[136]); // 17
1176  GL512(t2, t1, &m_rkeys[144]); // 18
1177  }
1178  else
1179  {
1180  SubKey<8>(msg, t1, &m_rkeys[144]);
1181  IMC512(t1);
1182  IG512(t1, t2, &m_rkeys[136]);
1183  IG512(t2, t1, &m_rkeys[128]);
1184  IG512(t1, t2, &m_rkeys[120]);
1185  IG512(t2, t1, &m_rkeys[112]);
1186  IG512(t1, t2, &m_rkeys[104]);
1187  IG512(t2, t1, &m_rkeys[96]);
1188  IG512(t1, t2, &m_rkeys[88]);
1189  IG512(t2, t1, &m_rkeys[80]);
1190  IG512(t1, t2, &m_rkeys[72]);
1191  IG512(t2, t1, &m_rkeys[64]);
1192  IG512(t1, t2, &m_rkeys[56]);
1193  IG512(t2, t1, &m_rkeys[48]);
1194  IG512(t1, t2, &m_rkeys[40]);
1195  IG512(t2, t1, &m_rkeys[32]);
1196  IG512(t1, t2, &m_rkeys[24]);
1197  IG512(t2, t1, &m_rkeys[16]);
1198  IG512(t1, t2, &m_rkeys[8]);
1199  IGL512(t2, t1, &m_rkeys[0]);
1200  }
1201 
1202  // Reverse bytes on BigEndian; Align pointer on LittleEndian
1203  typedef PutBlock<word64, LittleEndian, false> OutBlock;
1204  OutBlock oblk(xorBlock, outBlock);
1205  oblk(t1[0])(t1[1])(t1[2])(t1[3])(t1[4])(t1[5])(t1[6])(t1[7]);
1206 }
1207 
1208 // *********************** Library routines *********************** //
1209 
1210 void Kalyna128::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1211 {
1212  CRYPTOPP_UNUSED(params);
1213  m_nb = static_cast<unsigned int>(16U / sizeof(word64));
1214  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1215 
1216  switch (keylen)
1217  {
1218  case 16: // 128
1219  m_kl = 16;
1220  m_mkey.New(2);
1221  m_rkeys.New(11*2);
1222  m_wspace.New(2*6);
1223 
1224  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 2, key, 16);
1225  SetKey_22(m_mkey.begin());
1226  break;
1227  case 32: // 256
1228  m_kl = 32;
1229  m_mkey.New(4);
1230  m_rkeys.New(15*2);
1231  m_wspace.New(6*2+4);
1232 
1233  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
1234  SetKey_24(m_mkey.begin());
1235  break;
1236  default:
1237  CRYPTOPP_ASSERT(0);
1238  }
1239 }
1240 
1241 void Kalyna128::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1242 {
1243  // Timing attack countermeasure. see comments in Rijndael for more details
1244  const int cacheLineSize = GetCacheLineSize();
1245  volatile word64 _u = 0;
1246  word64 u = _u;
1247 
1248  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1249  for (unsigned int i=0; i<256; i+=cacheLineSize)
1250  u ^= *reinterpret_cast<const word64*>(p+i);
1251  m_wspace[0] = u;
1252 
1253  switch ((m_nb << 8) | m_nk)
1254  {
1255  case (2 << 8) | 2:
1256  ProcessBlock_22(inBlock, xorBlock, outBlock);
1257  break;
1258  case (2 << 8) | 4:
1259  ProcessBlock_24(inBlock, xorBlock, outBlock);
1260  break;
1261  default:
1262  CRYPTOPP_ASSERT(0);
1263  }
1264 }
1265 
1266 void Kalyna256::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1267 {
1268  CRYPTOPP_UNUSED(params);
1269  m_nb = static_cast<unsigned int>(32U / sizeof(word64));
1270  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1271 
1272  switch (keylen)
1273  {
1274  case 32: // 256
1275  m_kl = 32;
1276  m_mkey.New(4);
1277  m_rkeys.New(15*4);
1278  m_wspace.New(5*4);
1279 
1280  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 4, key, 32);
1281  SetKey_44(m_mkey.begin());
1282  break;
1283  case 64: // 512
1284  m_kl = 64;
1285  m_mkey.New(8);
1286  m_rkeys.New(19*4);
1287  m_wspace.New(6*4+8);
1288 
1289  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
1290  SetKey_48(m_mkey.begin());
1291  break;
1292  default:
1293  CRYPTOPP_ASSERT(0);
1294  }
1295 }
1296 
1297 void Kalyna256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1298 {
1299  // Timing attack countermeasure. see comments in Rijndael for more details
1300  const int cacheLineSize = GetCacheLineSize();
1301  volatile word64 _u = 0;
1302  word64 u = _u;
1303 
1304  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1305  for (unsigned int i=0; i<256; i+=cacheLineSize)
1306  u ^= *reinterpret_cast<const word64*>(p+i);
1307  m_wspace[0] = u;
1308 
1309  switch ((m_nb << 8) | m_nk)
1310  {
1311  case (4 << 8) | 4:
1312  ProcessBlock_44(inBlock, xorBlock, outBlock);
1313  break;
1314  case (4 << 8) | 8:
1315  ProcessBlock_48(inBlock, xorBlock, outBlock);
1316  break;
1317  default:
1318  CRYPTOPP_ASSERT(0);
1319  }
1320 }
1321 
1322 void Kalyna512::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &params)
1323 {
1324  CRYPTOPP_UNUSED(params);
1325  m_nb = static_cast<unsigned int>(64U / sizeof(word64));
1326  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1327 
1328  switch (keylen)
1329  {
1330  case 64: // 512
1331  m_kl = 64;
1332  m_nb = static_cast<unsigned int>(64U / sizeof(word64));
1333  m_nk = static_cast<unsigned int>(keylen / sizeof(word64));
1334 
1335  m_mkey.New(8);
1336  m_rkeys.New(19*8);
1337  m_wspace.New(5*8);
1338 
1339  GetUserKey(LITTLE_ENDIAN_ORDER, m_mkey.begin(), 8, key, 64);
1340  SetKey_88(m_mkey.begin());
1341  break;
1342  default:
1343  CRYPTOPP_ASSERT(0);
1344  }
1345 }
1346 
1347 void Kalyna512::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
1348 {
1349  // Timing attack countermeasure. see comments in Rijndael for more details
1350  const int cacheLineSize = GetCacheLineSize();
1351  volatile word64 _u = 0;
1352  word64 u = _u;
1353 
1354  const byte* p = reinterpret_cast<const byte*>(KalynaTab::S);
1355  for (unsigned int i=0; i<256; i+=cacheLineSize)
1356  u ^= *reinterpret_cast<const word64*>(p+i);
1357  m_wspace[0] = u;
1358 
1359  ProcessBlock_88(inBlock, xorBlock, outBlock);
1360 }
1361 
1362 NAMESPACE_END
W64LIT
#define W64LIT(x)
Declare an unsigned word64.
Definition: config_int.h:119
byte
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:56
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
LITTLE_ENDIAN_ORDER
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
pch.h
Precompiled header file.
kalyna.h
Classes for the Kalyna block cipher.
GetBlock
Access a block of memory.
Definition: misc.h:2528
argnames.h
Standard names for retrieving values by name when working with NameValuePairs.
misc.h
Utility functions for the Crypto++ library.
PutBlock
Access a block of memory.
Definition: misc.h:2569
cpu.h
Functions for CPU features and intrinsics.
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:321