Security Scol plugin
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 {
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
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 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
976 OutBlock oblk(xorBlock, outBlock);
977 oblk(t1[0])(t1[1]);
978}
979
980void 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
1029 OutBlock oblk(xorBlock, outBlock);
1030 oblk(t1[0])(t1[1]);
1031}
1032
1033void 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
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
1082 OutBlock oblk(xorBlock, outBlock);
1083 oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1084}
1085
1086void 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
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
1143 OutBlock oblk(xorBlock, outBlock);
1144 oblk(t1[0])(t1[1])(t1[2])(t1[3]);
1145}
1146
1147void 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
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
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
1210void 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
1241void 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
1266void 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
1297void 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
1322void 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
1347void 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
1362NAMESPACE_END
Standard names for retrieving values by name when working with NameValuePairs.
Access a block of memory.
Definition misc.h:2766
Interface for retrieving values given their names.
Definition cryptlib.h:322
Access a block of memory.
Definition misc.h:2807
Library configuration file.
unsigned char byte
8-bit unsigned datatype
Definition config_int.h:56
Functions for CPU features and intrinsics.
int GetCacheLineSize()
Provides the cache line size.
Definition cpu.h:889
Classes for the Kalyna block cipher.
Utility functions for the Crypto++ library.
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Copy bytes in a buffer to an array of elements in big-endian order.
Definition misc.h:2291
Precompiled header file.