Crypto++ 8.2
Free C&
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
20NAMESPACE_BEGIN(CryptoPP)
21NAMESPACE_BEGIN(KalynaTab)
22
23// T can be shared between Kupyna and Kalyna; IT, S and IS are Kalyna specific
24extern const word64 T[8][256]; // Columns
25extern const word64 IT[8][256]; // Inverse
26extern const byte S[4][256]; // Substitution
27extern const byte IS[4][256]; // Inverse
28
29NAMESPACE_END
30NAMESPACE_END
31
32ANONYMOUS_NAMESPACE_BEGIN
33
34// The typedef here is to sidestep problems with byte in the global namespace
35typedef unsigned char byte;
36
37using CryptoPP::word64;
38using CryptoPP::KalynaTab::T;
39using CryptoPP::KalynaTab::S;
40using CryptoPP::KalynaTab::IT;
41using CryptoPP::KalynaTab::IS;
42
43template <unsigned int NB>
44inline 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 {
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
87template <unsigned int NB>
88inline 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
110template <unsigned int NB>
111inline 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
131template <unsigned int NB>
132inline 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
152template <unsigned int NB>
153static 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
173inline 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
181inline 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
193inline 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
213inline 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
221inline 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
233inline 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
253inline 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
261inline 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
273inline 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
293inline 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
301inline 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
313inline 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
333inline 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
341inline 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
353inline 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
373inline 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
381inline 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
393inline 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
413ANONYMOUS_NAMESPACE_END
414
415NAMESPACE_BEGIN(CryptoPP)
416
417// *********************** UncheckedSetKey specializations *********************** //
418
419void 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
494void 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
595void 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
698void 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
820void 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
935void 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
977 OutBlock oblk(xorBlock, outBlock);
978 oblk(t1[0])(t1[1]);
979}
980
981void 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
1031 OutBlock oblk(xorBlock, outBlock);
1032 oblk(t1[0])(t1[1]);
1033}
1034
1035void 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
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
1085 OutBlock oblk(xorBlock, outBlock);
1086 oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1087}
1088
1089void 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
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
1147 OutBlock oblk(xorBlock, outBlock);
1148 oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1149}
1150
1151void 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
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
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
1215void 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
1246void 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
1273void 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
1304void 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
1331void 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
1356void 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
1372NAMESPACE_END
Standard names for retrieving values by name when working with NameValuePairs.
Access a block of memory.
Definition: misc.h:2455
Interface for retrieving values given their names.
Definition: cryptlib.h:294
Access a block of memory.
Definition: misc.h:2496
Library configuration file.
Functions for CPU features and intrinsics.
int GetCacheLineSize()
Provides the cache line size.
Definition: cpu.h:328
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
Classes for the Kalyna block cipher.
Utility functions for the Crypto++ library.
Crypto++ library namespace.
Precompiled header file.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69