Add GOST R 34.11-94 to nettle_hashes
[gd/nettle] / gost28147.c
1 /* gost28147.c - GOST 28147-89 cipher implementation
2  *
3  * based on Russian standard GOST 28147-89
4  * For English description, check RFC 5830.
5  * S-Boxes are expanded from the tables defined in RFC4357:
6  *   https://tools.ietf.org/html/rfc4357
7  *
8  * Copyright: 2019 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
9  * Copyright: 2009-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the
13  * "Software"), to deal in the Software without restriction, including
14  * without limitation the rights to use, copy, modify, merge, publish,
15  * distribute, sublicense, and/or sell copies of the Software, and to
16  * permit persons to whom the Software is furnished to do so, subject to
17  * the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29  */
30
31 #if HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "macros.h"
36 #include "gost28147.h"
37 #include "gost28147-internal.h"
38
39 /* pre-initialized GOST lookup tables based on rotated S-Box */
40 const struct gost28147_param gost28147_param_test_3411 =
41 {
42   {
43     { /* 0 */
44       0x00072000, 0x00075000, 0x00074800, 0x00071000,
45       0x00076800, 0x00074000, 0x00070000, 0x00077000,
46       0x00073000, 0x00075800, 0x00070800, 0x00076000,
47       0x00073800, 0x00077800, 0x00072800, 0x00071800,
48       0x0005a000, 0x0005d000, 0x0005c800, 0x00059000,
49       0x0005e800, 0x0005c000, 0x00058000, 0x0005f000,
50       0x0005b000, 0x0005d800, 0x00058800, 0x0005e000,
51       0x0005b800, 0x0005f800, 0x0005a800, 0x00059800,
52       0x00022000, 0x00025000, 0x00024800, 0x00021000,
53       0x00026800, 0x00024000, 0x00020000, 0x00027000,
54       0x00023000, 0x00025800, 0x00020800, 0x00026000,
55       0x00023800, 0x00027800, 0x00022800, 0x00021800,
56       0x00062000, 0x00065000, 0x00064800, 0x00061000,
57       0x00066800, 0x00064000, 0x00060000, 0x00067000,
58       0x00063000, 0x00065800, 0x00060800, 0x00066000,
59       0x00063800, 0x00067800, 0x00062800, 0x00061800,
60       0x00032000, 0x00035000, 0x00034800, 0x00031000,
61       0x00036800, 0x00034000, 0x00030000, 0x00037000,
62       0x00033000, 0x00035800, 0x00030800, 0x00036000,
63       0x00033800, 0x00037800, 0x00032800, 0x00031800,
64       0x0006a000, 0x0006d000, 0x0006c800, 0x00069000,
65       0x0006e800, 0x0006c000, 0x00068000, 0x0006f000,
66       0x0006b000, 0x0006d800, 0x00068800, 0x0006e000,
67       0x0006b800, 0x0006f800, 0x0006a800, 0x00069800,
68       0x0007a000, 0x0007d000, 0x0007c800, 0x00079000,
69       0x0007e800, 0x0007c000, 0x00078000, 0x0007f000,
70       0x0007b000, 0x0007d800, 0x00078800, 0x0007e000,
71       0x0007b800, 0x0007f800, 0x0007a800, 0x00079800,
72       0x00052000, 0x00055000, 0x00054800, 0x00051000,
73       0x00056800, 0x00054000, 0x00050000, 0x00057000,
74       0x00053000, 0x00055800, 0x00050800, 0x00056000,
75       0x00053800, 0x00057800, 0x00052800, 0x00051800,
76       0x00012000, 0x00015000, 0x00014800, 0x00011000,
77       0x00016800, 0x00014000, 0x00010000, 0x00017000,
78       0x00013000, 0x00015800, 0x00010800, 0x00016000,
79       0x00013800, 0x00017800, 0x00012800, 0x00011800,
80       0x0001a000, 0x0001d000, 0x0001c800, 0x00019000,
81       0x0001e800, 0x0001c000, 0x00018000, 0x0001f000,
82       0x0001b000, 0x0001d800, 0x00018800, 0x0001e000,
83       0x0001b800, 0x0001f800, 0x0001a800, 0x00019800,
84       0x00042000, 0x00045000, 0x00044800, 0x00041000,
85       0x00046800, 0x00044000, 0x00040000, 0x00047000,
86       0x00043000, 0x00045800, 0x00040800, 0x00046000,
87       0x00043800, 0x00047800, 0x00042800, 0x00041800,
88       0x0000a000, 0x0000d000, 0x0000c800, 0x00009000,
89       0x0000e800, 0x0000c000, 0x00008000, 0x0000f000,
90       0x0000b000, 0x0000d800, 0x00008800, 0x0000e000,
91       0x0000b800, 0x0000f800, 0x0000a800, 0x00009800,
92       0x00002000, 0x00005000, 0x00004800, 0x00001000,
93       0x00006800, 0x00004000, 0x00000000, 0x00007000,
94       0x00003000, 0x00005800, 0x00000800, 0x00006000,
95       0x00003800, 0x00007800, 0x00002800, 0x00001800,
96       0x0003a000, 0x0003d000, 0x0003c800, 0x00039000,
97       0x0003e800, 0x0003c000, 0x00038000, 0x0003f000,
98       0x0003b000, 0x0003d800, 0x00038800, 0x0003e000,
99       0x0003b800, 0x0003f800, 0x0003a800, 0x00039800,
100       0x0002a000, 0x0002d000, 0x0002c800, 0x00029000,
101       0x0002e800, 0x0002c000, 0x00028000, 0x0002f000,
102       0x0002b000, 0x0002d800, 0x00028800, 0x0002e000,
103       0x0002b800, 0x0002f800, 0x0002a800, 0x00029800,
104       0x0004a000, 0x0004d000, 0x0004c800, 0x00049000,
105       0x0004e800, 0x0004c000, 0x00048000, 0x0004f000,
106       0x0004b000, 0x0004d800, 0x00048800, 0x0004e000,
107       0x0004b800, 0x0004f800, 0x0004a800, 0x00049800,
108     }, { /* 1 */
109       0x03a80000, 0x03c00000, 0x03880000, 0x03e80000,
110       0x03d00000, 0x03980000, 0x03a00000, 0x03900000,
111       0x03f00000, 0x03f80000, 0x03e00000, 0x03b80000,
112       0x03b00000, 0x03800000, 0x03c80000, 0x03d80000,
113       0x06a80000, 0x06c00000, 0x06880000, 0x06e80000,
114       0x06d00000, 0x06980000, 0x06a00000, 0x06900000,
115       0x06f00000, 0x06f80000, 0x06e00000, 0x06b80000,
116       0x06b00000, 0x06800000, 0x06c80000, 0x06d80000,
117       0x05280000, 0x05400000, 0x05080000, 0x05680000,
118       0x05500000, 0x05180000, 0x05200000, 0x05100000,
119       0x05700000, 0x05780000, 0x05600000, 0x05380000,
120       0x05300000, 0x05000000, 0x05480000, 0x05580000,
121       0x00a80000, 0x00c00000, 0x00880000, 0x00e80000,
122       0x00d00000, 0x00980000, 0x00a00000, 0x00900000,
123       0x00f00000, 0x00f80000, 0x00e00000, 0x00b80000,
124       0x00b00000, 0x00800000, 0x00c80000, 0x00d80000,
125       0x00280000, 0x00400000, 0x00080000, 0x00680000,
126       0x00500000, 0x00180000, 0x00200000, 0x00100000,
127       0x00700000, 0x00780000, 0x00600000, 0x00380000,
128       0x00300000, 0x00000000, 0x00480000, 0x00580000,
129       0x04280000, 0x04400000, 0x04080000, 0x04680000,
130       0x04500000, 0x04180000, 0x04200000, 0x04100000,
131       0x04700000, 0x04780000, 0x04600000, 0x04380000,
132       0x04300000, 0x04000000, 0x04480000, 0x04580000,
133       0x04a80000, 0x04c00000, 0x04880000, 0x04e80000,
134       0x04d00000, 0x04980000, 0x04a00000, 0x04900000,
135       0x04f00000, 0x04f80000, 0x04e00000, 0x04b80000,
136       0x04b00000, 0x04800000, 0x04c80000, 0x04d80000,
137       0x07a80000, 0x07c00000, 0x07880000, 0x07e80000,
138       0x07d00000, 0x07980000, 0x07a00000, 0x07900000,
139       0x07f00000, 0x07f80000, 0x07e00000, 0x07b80000,
140       0x07b00000, 0x07800000, 0x07c80000, 0x07d80000,
141       0x07280000, 0x07400000, 0x07080000, 0x07680000,
142       0x07500000, 0x07180000, 0x07200000, 0x07100000,
143       0x07700000, 0x07780000, 0x07600000, 0x07380000,
144       0x07300000, 0x07000000, 0x07480000, 0x07580000,
145       0x02280000, 0x02400000, 0x02080000, 0x02680000,
146       0x02500000, 0x02180000, 0x02200000, 0x02100000,
147       0x02700000, 0x02780000, 0x02600000, 0x02380000,
148       0x02300000, 0x02000000, 0x02480000, 0x02580000,
149       0x03280000, 0x03400000, 0x03080000, 0x03680000,
150       0x03500000, 0x03180000, 0x03200000, 0x03100000,
151       0x03700000, 0x03780000, 0x03600000, 0x03380000,
152       0x03300000, 0x03000000, 0x03480000, 0x03580000,
153       0x06280000, 0x06400000, 0x06080000, 0x06680000,
154       0x06500000, 0x06180000, 0x06200000, 0x06100000,
155       0x06700000, 0x06780000, 0x06600000, 0x06380000,
156       0x06300000, 0x06000000, 0x06480000, 0x06580000,
157       0x05a80000, 0x05c00000, 0x05880000, 0x05e80000,
158       0x05d00000, 0x05980000, 0x05a00000, 0x05900000,
159       0x05f00000, 0x05f80000, 0x05e00000, 0x05b80000,
160       0x05b00000, 0x05800000, 0x05c80000, 0x05d80000,
161       0x01280000, 0x01400000, 0x01080000, 0x01680000,
162       0x01500000, 0x01180000, 0x01200000, 0x01100000,
163       0x01700000, 0x01780000, 0x01600000, 0x01380000,
164       0x01300000, 0x01000000, 0x01480000, 0x01580000,
165       0x02a80000, 0x02c00000, 0x02880000, 0x02e80000,
166       0x02d00000, 0x02980000, 0x02a00000, 0x02900000,
167       0x02f00000, 0x02f80000, 0x02e00000, 0x02b80000,
168       0x02b00000, 0x02800000, 0x02c80000, 0x02d80000,
169       0x01a80000, 0x01c00000, 0x01880000, 0x01e80000,
170       0x01d00000, 0x01980000, 0x01a00000, 0x01900000,
171       0x01f00000, 0x01f80000, 0x01e00000, 0x01b80000,
172       0x01b00000, 0x01800000, 0x01c80000, 0x01d80000,
173     }, { /* 2 */
174       0x30000002, 0x60000002, 0x38000002, 0x08000002,
175       0x28000002, 0x78000002, 0x68000002, 0x40000002,
176       0x20000002, 0x50000002, 0x48000002, 0x70000002,
177       0x00000002, 0x18000002, 0x58000002, 0x10000002,
178       0xb0000005, 0xe0000005, 0xb8000005, 0x88000005,
179       0xa8000005, 0xf8000005, 0xe8000005, 0xc0000005,
180       0xa0000005, 0xd0000005, 0xc8000005, 0xf0000005,
181       0x80000005, 0x98000005, 0xd8000005, 0x90000005,
182       0x30000005, 0x60000005, 0x38000005, 0x08000005,
183       0x28000005, 0x78000005, 0x68000005, 0x40000005,
184       0x20000005, 0x50000005, 0x48000005, 0x70000005,
185       0x00000005, 0x18000005, 0x58000005, 0x10000005,
186       0x30000000, 0x60000000, 0x38000000, 0x08000000,
187       0x28000000, 0x78000000, 0x68000000, 0x40000000,
188       0x20000000, 0x50000000, 0x48000000, 0x70000000,
189       0x00000000, 0x18000000, 0x58000000, 0x10000000,
190       0xb0000003, 0xe0000003, 0xb8000003, 0x88000003,
191       0xa8000003, 0xf8000003, 0xe8000003, 0xc0000003,
192       0xa0000003, 0xd0000003, 0xc8000003, 0xf0000003,
193       0x80000003, 0x98000003, 0xd8000003, 0x90000003,
194       0x30000001, 0x60000001, 0x38000001, 0x08000001,
195       0x28000001, 0x78000001, 0x68000001, 0x40000001,
196       0x20000001, 0x50000001, 0x48000001, 0x70000001,
197       0x00000001, 0x18000001, 0x58000001, 0x10000001,
198       0xb0000000, 0xe0000000, 0xb8000000, 0x88000000,
199       0xa8000000, 0xf8000000, 0xe8000000, 0xc0000000,
200       0xa0000000, 0xd0000000, 0xc8000000, 0xf0000000,
201       0x80000000, 0x98000000, 0xd8000000, 0x90000000,
202       0xb0000006, 0xe0000006, 0xb8000006, 0x88000006,
203       0xa8000006, 0xf8000006, 0xe8000006, 0xc0000006,
204       0xa0000006, 0xd0000006, 0xc8000006, 0xf0000006,
205       0x80000006, 0x98000006, 0xd8000006, 0x90000006,
206       0xb0000001, 0xe0000001, 0xb8000001, 0x88000001,
207       0xa8000001, 0xf8000001, 0xe8000001, 0xc0000001,
208       0xa0000001, 0xd0000001, 0xc8000001, 0xf0000001,
209       0x80000001, 0x98000001, 0xd8000001, 0x90000001,
210       0x30000003, 0x60000003, 0x38000003, 0x08000003,
211       0x28000003, 0x78000003, 0x68000003, 0x40000003,
212       0x20000003, 0x50000003, 0x48000003, 0x70000003,
213       0x00000003, 0x18000003, 0x58000003, 0x10000003,
214       0x30000004, 0x60000004, 0x38000004, 0x08000004,
215       0x28000004, 0x78000004, 0x68000004, 0x40000004,
216       0x20000004, 0x50000004, 0x48000004, 0x70000004,
217       0x00000004, 0x18000004, 0x58000004, 0x10000004,
218       0xb0000002, 0xe0000002, 0xb8000002, 0x88000002,
219       0xa8000002, 0xf8000002, 0xe8000002, 0xc0000002,
220       0xa0000002, 0xd0000002, 0xc8000002, 0xf0000002,
221       0x80000002, 0x98000002, 0xd8000002, 0x90000002,
222       0xb0000004, 0xe0000004, 0xb8000004, 0x88000004,
223       0xa8000004, 0xf8000004, 0xe8000004, 0xc0000004,
224       0xa0000004, 0xd0000004, 0xc8000004, 0xf0000004,
225       0x80000004, 0x98000004, 0xd8000004, 0x90000004,
226       0x30000006, 0x60000006, 0x38000006, 0x08000006,
227       0x28000006, 0x78000006, 0x68000006, 0x40000006,
228       0x20000006, 0x50000006, 0x48000006, 0x70000006,
229       0x00000006, 0x18000006, 0x58000006, 0x10000006,
230       0xb0000007, 0xe0000007, 0xb8000007, 0x88000007,
231       0xa8000007, 0xf8000007, 0xe8000007, 0xc0000007,
232       0xa0000007, 0xd0000007, 0xc8000007, 0xf0000007,
233       0x80000007, 0x98000007, 0xd8000007, 0x90000007,
234       0x30000007, 0x60000007, 0x38000007, 0x08000007,
235       0x28000007, 0x78000007, 0x68000007, 0x40000007,
236       0x20000007, 0x50000007, 0x48000007, 0x70000007,
237       0x00000007, 0x18000007, 0x58000007, 0x10000007,
238     }, { /* 3 */
239       0x000000e8, 0x000000d8, 0x000000a0, 0x00000088,
240       0x00000098, 0x000000f8, 0x000000a8, 0x000000c8,
241       0x00000080, 0x000000d0, 0x000000f0, 0x000000b8,
242       0x000000b0, 0x000000c0, 0x00000090, 0x000000e0,
243       0x000007e8, 0x000007d8, 0x000007a0, 0x00000788,
244       0x00000798, 0x000007f8, 0x000007a8, 0x000007c8,
245       0x00000780, 0x000007d0, 0x000007f0, 0x000007b8,
246       0x000007b0, 0x000007c0, 0x00000790, 0x000007e0,
247       0x000006e8, 0x000006d8, 0x000006a0, 0x00000688,
248       0x00000698, 0x000006f8, 0x000006a8, 0x000006c8,
249       0x00000680, 0x000006d0, 0x000006f0, 0x000006b8,
250       0x000006b0, 0x000006c0, 0x00000690, 0x000006e0,
251       0x00000068, 0x00000058, 0x00000020, 0x00000008,
252       0x00000018, 0x00000078, 0x00000028, 0x00000048,
253       0x00000000, 0x00000050, 0x00000070, 0x00000038,
254       0x00000030, 0x00000040, 0x00000010, 0x00000060,
255       0x000002e8, 0x000002d8, 0x000002a0, 0x00000288,
256       0x00000298, 0x000002f8, 0x000002a8, 0x000002c8,
257       0x00000280, 0x000002d0, 0x000002f0, 0x000002b8,
258       0x000002b0, 0x000002c0, 0x00000290, 0x000002e0,
259       0x000003e8, 0x000003d8, 0x000003a0, 0x00000388,
260       0x00000398, 0x000003f8, 0x000003a8, 0x000003c8,
261       0x00000380, 0x000003d0, 0x000003f0, 0x000003b8,
262       0x000003b0, 0x000003c0, 0x00000390, 0x000003e0,
263       0x00000568, 0x00000558, 0x00000520, 0x00000508,
264       0x00000518, 0x00000578, 0x00000528, 0x00000548,
265       0x00000500, 0x00000550, 0x00000570, 0x00000538,
266       0x00000530, 0x00000540, 0x00000510, 0x00000560,
267       0x00000268, 0x00000258, 0x00000220, 0x00000208,
268       0x00000218, 0x00000278, 0x00000228, 0x00000248,
269       0x00000200, 0x00000250, 0x00000270, 0x00000238,
270       0x00000230, 0x00000240, 0x00000210, 0x00000260,
271       0x000004e8, 0x000004d8, 0x000004a0, 0x00000488,
272       0x00000498, 0x000004f8, 0x000004a8, 0x000004c8,
273       0x00000480, 0x000004d0, 0x000004f0, 0x000004b8,
274       0x000004b0, 0x000004c0, 0x00000490, 0x000004e0,
275       0x00000168, 0x00000158, 0x00000120, 0x00000108,
276       0x00000118, 0x00000178, 0x00000128, 0x00000148,
277       0x00000100, 0x00000150, 0x00000170, 0x00000138,
278       0x00000130, 0x00000140, 0x00000110, 0x00000160,
279       0x000001e8, 0x000001d8, 0x000001a0, 0x00000188,
280       0x00000198, 0x000001f8, 0x000001a8, 0x000001c8,
281       0x00000180, 0x000001d0, 0x000001f0, 0x000001b8,
282       0x000001b0, 0x000001c0, 0x00000190, 0x000001e0,
283       0x00000768, 0x00000758, 0x00000720, 0x00000708,
284       0x00000718, 0x00000778, 0x00000728, 0x00000748,
285       0x00000700, 0x00000750, 0x00000770, 0x00000738,
286       0x00000730, 0x00000740, 0x00000710, 0x00000760,
287       0x00000368, 0x00000358, 0x00000320, 0x00000308,
288       0x00000318, 0x00000378, 0x00000328, 0x00000348,
289       0x00000300, 0x00000350, 0x00000370, 0x00000338,
290       0x00000330, 0x00000340, 0x00000310, 0x00000360,
291       0x000005e8, 0x000005d8, 0x000005a0, 0x00000588,
292       0x00000598, 0x000005f8, 0x000005a8, 0x000005c8,
293       0x00000580, 0x000005d0, 0x000005f0, 0x000005b8,
294       0x000005b0, 0x000005c0, 0x00000590, 0x000005e0,
295       0x00000468, 0x00000458, 0x00000420, 0x00000408,
296       0x00000418, 0x00000478, 0x00000428, 0x00000448,
297       0x00000400, 0x00000450, 0x00000470, 0x00000438,
298       0x00000430, 0x00000440, 0x00000410, 0x00000460,
299       0x00000668, 0x00000658, 0x00000620, 0x00000608,
300       0x00000618, 0x00000678, 0x00000628, 0x00000648,
301       0x00000600, 0x00000650, 0x00000670, 0x00000638,
302       0x00000630, 0x00000640, 0x00000610, 0x00000660,
303     }
304   }
305 };
306
307 const struct gost28147_param gost28147_param_CryptoPro_3411 =
308 {
309   {
310     { /* 0 */
311       0x0002d000, 0x0002a000, 0x0002a800, 0x0002b000,
312       0x0002c000, 0x00028800, 0x00029800, 0x0002b800,
313       0x0002e800, 0x0002e000, 0x0002f000, 0x00028000,
314       0x0002c800, 0x00029000, 0x0002d800, 0x0002f800,
315       0x0007d000, 0x0007a000, 0x0007a800, 0x0007b000,
316       0x0007c000, 0x00078800, 0x00079800, 0x0007b800,
317       0x0007e800, 0x0007e000, 0x0007f000, 0x00078000,
318       0x0007c800, 0x00079000, 0x0007d800, 0x0007f800,
319       0x00025000, 0x00022000, 0x00022800, 0x00023000,
320       0x00024000, 0x00020800, 0x00021800, 0x00023800,
321       0x00026800, 0x00026000, 0x00027000, 0x00020000,
322       0x00024800, 0x00021000, 0x00025800, 0x00027800,
323       0x00005000, 0x00002000, 0x00002800, 0x00003000,
324       0x00004000, 0x00000800, 0x00001800, 0x00003800,
325       0x00006800, 0x00006000, 0x00007000, 0x00000000,
326       0x00004800, 0x00001000, 0x00005800, 0x00007800,
327       0x00015000, 0x00012000, 0x00012800, 0x00013000,
328       0x00014000, 0x00010800, 0x00011800, 0x00013800,
329       0x00016800, 0x00016000, 0x00017000, 0x00010000,
330       0x00014800, 0x00011000, 0x00015800, 0x00017800,
331       0x0006d000, 0x0006a000, 0x0006a800, 0x0006b000,
332       0x0006c000, 0x00068800, 0x00069800, 0x0006b800,
333       0x0006e800, 0x0006e000, 0x0006f000, 0x00068000,
334       0x0006c800, 0x00069000, 0x0006d800, 0x0006f800,
335       0x0005d000, 0x0005a000, 0x0005a800, 0x0005b000,
336       0x0005c000, 0x00058800, 0x00059800, 0x0005b800,
337       0x0005e800, 0x0005e000, 0x0005f000, 0x00058000,
338       0x0005c800, 0x00059000, 0x0005d800, 0x0005f800,
339       0x0004d000, 0x0004a000, 0x0004a800, 0x0004b000,
340       0x0004c000, 0x00048800, 0x00049800, 0x0004b800,
341       0x0004e800, 0x0004e000, 0x0004f000, 0x00048000,
342       0x0004c800, 0x00049000, 0x0004d800, 0x0004f800,
343       0x0000d000, 0x0000a000, 0x0000a800, 0x0000b000,
344       0x0000c000, 0x00008800, 0x00009800, 0x0000b800,
345       0x0000e800, 0x0000e000, 0x0000f000, 0x00008000,
346       0x0000c800, 0x00009000, 0x0000d800, 0x0000f800,
347       0x0003d000, 0x0003a000, 0x0003a800, 0x0003b000,
348       0x0003c000, 0x00038800, 0x00039800, 0x0003b800,
349       0x0003e800, 0x0003e000, 0x0003f000, 0x00038000,
350       0x0003c800, 0x00039000, 0x0003d800, 0x0003f800,
351       0x00035000, 0x00032000, 0x00032800, 0x00033000,
352       0x00034000, 0x00030800, 0x00031800, 0x00033800,
353       0x00036800, 0x00036000, 0x00037000, 0x00030000,
354       0x00034800, 0x00031000, 0x00035800, 0x00037800,
355       0x0001d000, 0x0001a000, 0x0001a800, 0x0001b000,
356       0x0001c000, 0x00018800, 0x00019800, 0x0001b800,
357       0x0001e800, 0x0001e000, 0x0001f000, 0x00018000,
358       0x0001c800, 0x00019000, 0x0001d800, 0x0001f800,
359       0x00065000, 0x00062000, 0x00062800, 0x00063000,
360       0x00064000, 0x00060800, 0x00061800, 0x00063800,
361       0x00066800, 0x00066000, 0x00067000, 0x00060000,
362       0x00064800, 0x00061000, 0x00065800, 0x00067800,
363       0x00075000, 0x00072000, 0x00072800, 0x00073000,
364       0x00074000, 0x00070800, 0x00071800, 0x00073800,
365       0x00076800, 0x00076000, 0x00077000, 0x00070000,
366       0x00074800, 0x00071000, 0x00075800, 0x00077800,
367       0x00055000, 0x00052000, 0x00052800, 0x00053000,
368       0x00054000, 0x00050800, 0x00051800, 0x00053800,
369       0x00056800, 0x00056000, 0x00057000, 0x00050000,
370       0x00054800, 0x00051000, 0x00055800, 0x00057800,
371       0x00045000, 0x00042000, 0x00042800, 0x00043000,
372       0x00044000, 0x00040800, 0x00041800, 0x00043800,
373       0x00046800, 0x00046000, 0x00047000, 0x00040000,
374       0x00044800, 0x00041000, 0x00045800, 0x00047800,
375     }, { /* 1 */
376       0x02380000, 0x02780000, 0x02600000, 0x02700000,
377       0x02480000, 0x02200000, 0x02080000, 0x02000000,
378       0x02180000, 0x02580000, 0x02280000, 0x02100000,
379       0x02300000, 0x02500000, 0x02400000, 0x02680000,
380       0x05380000, 0x05780000, 0x05600000, 0x05700000,
381       0x05480000, 0x05200000, 0x05080000, 0x05000000,
382       0x05180000, 0x05580000, 0x05280000, 0x05100000,
383       0x05300000, 0x05500000, 0x05400000, 0x05680000,
384       0x03b80000, 0x03f80000, 0x03e00000, 0x03f00000,
385       0x03c80000, 0x03a00000, 0x03880000, 0x03800000,
386       0x03980000, 0x03d80000, 0x03a80000, 0x03900000,
387       0x03b00000, 0x03d00000, 0x03c00000, 0x03e80000,
388       0x06380000, 0x06780000, 0x06600000, 0x06700000,
389       0x06480000, 0x06200000, 0x06080000, 0x06000000,
390       0x06180000, 0x06580000, 0x06280000, 0x06100000,
391       0x06300000, 0x06500000, 0x06400000, 0x06680000,
392       0x00380000, 0x00780000, 0x00600000, 0x00700000,
393       0x00480000, 0x00200000, 0x00080000, 0x00000000,
394       0x00180000, 0x00580000, 0x00280000, 0x00100000,
395       0x00300000, 0x00500000, 0x00400000, 0x00680000,
396       0x07b80000, 0x07f80000, 0x07e00000, 0x07f00000,
397       0x07c80000, 0x07a00000, 0x07880000, 0x07800000,
398       0x07980000, 0x07d80000, 0x07a80000, 0x07900000,
399       0x07b00000, 0x07d00000, 0x07c00000, 0x07e80000,
400       0x01380000, 0x01780000, 0x01600000, 0x01700000,
401       0x01480000, 0x01200000, 0x01080000, 0x01000000,
402       0x01180000, 0x01580000, 0x01280000, 0x01100000,
403       0x01300000, 0x01500000, 0x01400000, 0x01680000,
404       0x04380000, 0x04780000, 0x04600000, 0x04700000,
405       0x04480000, 0x04200000, 0x04080000, 0x04000000,
406       0x04180000, 0x04580000, 0x04280000, 0x04100000,
407       0x04300000, 0x04500000, 0x04400000, 0x04680000,
408       0x07380000, 0x07780000, 0x07600000, 0x07700000,
409       0x07480000, 0x07200000, 0x07080000, 0x07000000,
410       0x07180000, 0x07580000, 0x07280000, 0x07100000,
411       0x07300000, 0x07500000, 0x07400000, 0x07680000,
412       0x00b80000, 0x00f80000, 0x00e00000, 0x00f00000,
413       0x00c80000, 0x00a00000, 0x00880000, 0x00800000,
414       0x00980000, 0x00d80000, 0x00a80000, 0x00900000,
415       0x00b00000, 0x00d00000, 0x00c00000, 0x00e80000,
416       0x03380000, 0x03780000, 0x03600000, 0x03700000,
417       0x03480000, 0x03200000, 0x03080000, 0x03000000,
418       0x03180000, 0x03580000, 0x03280000, 0x03100000,
419       0x03300000, 0x03500000, 0x03400000, 0x03680000,
420       0x02b80000, 0x02f80000, 0x02e00000, 0x02f00000,
421       0x02c80000, 0x02a00000, 0x02880000, 0x02800000,
422       0x02980000, 0x02d80000, 0x02a80000, 0x02900000,
423       0x02b00000, 0x02d00000, 0x02c00000, 0x02e80000,
424       0x06b80000, 0x06f80000, 0x06e00000, 0x06f00000,
425       0x06c80000, 0x06a00000, 0x06880000, 0x06800000,
426       0x06980000, 0x06d80000, 0x06a80000, 0x06900000,
427       0x06b00000, 0x06d00000, 0x06c00000, 0x06e80000,
428       0x05b80000, 0x05f80000, 0x05e00000, 0x05f00000,
429       0x05c80000, 0x05a00000, 0x05880000, 0x05800000,
430       0x05980000, 0x05d80000, 0x05a80000, 0x05900000,
431       0x05b00000, 0x05d00000, 0x05c00000, 0x05e80000,
432       0x04b80000, 0x04f80000, 0x04e00000, 0x04f00000,
433       0x04c80000, 0x04a00000, 0x04880000, 0x04800000,
434       0x04980000, 0x04d80000, 0x04a80000, 0x04900000,
435       0x04b00000, 0x04d00000, 0x04c00000, 0x04e80000,
436       0x01b80000, 0x01f80000, 0x01e00000, 0x01f00000,
437       0x01c80000, 0x01a00000, 0x01880000, 0x01800000,
438       0x01980000, 0x01d80000, 0x01a80000, 0x01900000,
439       0x01b00000, 0x01d00000, 0x01c00000, 0x01e80000,
440     }, { /* 2 */
441       0xb8000003, 0xb0000003, 0xa0000003, 0xd8000003,
442       0xc8000003, 0xe0000003, 0x90000003, 0xd0000003,
443       0x88000003, 0xc0000003, 0x80000003, 0xf0000003,
444       0xf8000003, 0xe8000003, 0x98000003, 0xa8000003,
445       0x38000003, 0x30000003, 0x20000003, 0x58000003,
446       0x48000003, 0x60000003, 0x10000003, 0x50000003,
447       0x08000003, 0x40000003, 0x00000003, 0x70000003,
448       0x78000003, 0x68000003, 0x18000003, 0x28000003,
449       0x38000001, 0x30000001, 0x20000001, 0x58000001,
450       0x48000001, 0x60000001, 0x10000001, 0x50000001,
451       0x08000001, 0x40000001, 0x00000001, 0x70000001,
452       0x78000001, 0x68000001, 0x18000001, 0x28000001,
453       0x38000002, 0x30000002, 0x20000002, 0x58000002,
454       0x48000002, 0x60000002, 0x10000002, 0x50000002,
455       0x08000002, 0x40000002, 0x00000002, 0x70000002,
456       0x78000002, 0x68000002, 0x18000002, 0x28000002,
457       0xb8000006, 0xb0000006, 0xa0000006, 0xd8000006,
458       0xc8000006, 0xe0000006, 0x90000006, 0xd0000006,
459       0x88000006, 0xc0000006, 0x80000006, 0xf0000006,
460       0xf8000006, 0xe8000006, 0x98000006, 0xa8000006,
461       0xb8000004, 0xb0000004, 0xa0000004, 0xd8000004,
462       0xc8000004, 0xe0000004, 0x90000004, 0xd0000004,
463       0x88000004, 0xc0000004, 0x80000004, 0xf0000004,
464       0xf8000004, 0xe8000004, 0x98000004, 0xa8000004,
465       0xb8000007, 0xb0000007, 0xa0000007, 0xd8000007,
466       0xc8000007, 0xe0000007, 0x90000007, 0xd0000007,
467       0x88000007, 0xc0000007, 0x80000007, 0xf0000007,
468       0xf8000007, 0xe8000007, 0x98000007, 0xa8000007,
469       0x38000000, 0x30000000, 0x20000000, 0x58000000,
470       0x48000000, 0x60000000, 0x10000000, 0x50000000,
471       0x08000000, 0x40000000, 0x00000000, 0x70000000,
472       0x78000000, 0x68000000, 0x18000000, 0x28000000,
473       0x38000005, 0x30000005, 0x20000005, 0x58000005,
474       0x48000005, 0x60000005, 0x10000005, 0x50000005,
475       0x08000005, 0x40000005, 0x00000005, 0x70000005,
476       0x78000005, 0x68000005, 0x18000005, 0x28000005,
477       0xb8000000, 0xb0000000, 0xa0000000, 0xd8000000,
478       0xc8000000, 0xe0000000, 0x90000000, 0xd0000000,
479       0x88000000, 0xc0000000, 0x80000000, 0xf0000000,
480       0xf8000000, 0xe8000000, 0x98000000, 0xa8000000,
481       0xb8000002, 0xb0000002, 0xa0000002, 0xd8000002,
482       0xc8000002, 0xe0000002, 0x90000002, 0xd0000002,
483       0x88000002, 0xc0000002, 0x80000002, 0xf0000002,
484       0xf8000002, 0xe8000002, 0x98000002, 0xa8000002,
485       0xb8000005, 0xb0000005, 0xa0000005, 0xd8000005,
486       0xc8000005, 0xe0000005, 0x90000005, 0xd0000005,
487       0x88000005, 0xc0000005, 0x80000005, 0xf0000005,
488       0xf8000005, 0xe8000005, 0x98000005, 0xa8000005,
489       0x38000004, 0x30000004, 0x20000004, 0x58000004,
490       0x48000004, 0x60000004, 0x10000004, 0x50000004,
491       0x08000004, 0x40000004, 0x00000004, 0x70000004,
492       0x78000004, 0x68000004, 0x18000004, 0x28000004,
493       0x38000007, 0x30000007, 0x20000007, 0x58000007,
494       0x48000007, 0x60000007, 0x10000007, 0x50000007,
495       0x08000007, 0x40000007, 0x00000007, 0x70000007,
496       0x78000007, 0x68000007, 0x18000007, 0x28000007,
497       0x38000006, 0x30000006, 0x20000006, 0x58000006,
498       0x48000006, 0x60000006, 0x10000006, 0x50000006,
499       0x08000006, 0x40000006, 0x00000006, 0x70000006,
500       0x78000006, 0x68000006, 0x18000006, 0x28000006,
501       0xb8000001, 0xb0000001, 0xa0000001, 0xd8000001,
502       0xc8000001, 0xe0000001, 0x90000001, 0xd0000001,
503       0x88000001, 0xc0000001, 0x80000001, 0xf0000001,
504       0xf8000001, 0xe8000001, 0x98000001, 0xa8000001,
505     }, { /* 3 */
506       0x000000e8, 0x000000f0, 0x000000a0, 0x00000088,
507       0x000000b8, 0x00000080, 0x000000a8, 0x000000d0,
508       0x00000098, 0x000000e0, 0x000000c0, 0x000000f8,
509       0x000000b0, 0x00000090, 0x000000c8, 0x000000d8,
510       0x000001e8, 0x000001f0, 0x000001a0, 0x00000188,
511       0x000001b8, 0x00000180, 0x000001a8, 0x000001d0,
512       0x00000198, 0x000001e0, 0x000001c0, 0x000001f8,
513       0x000001b0, 0x00000190, 0x000001c8, 0x000001d8,
514       0x00000568, 0x00000570, 0x00000520, 0x00000508,
515       0x00000538, 0x00000500, 0x00000528, 0x00000550,
516       0x00000518, 0x00000560, 0x00000540, 0x00000578,
517       0x00000530, 0x00000510, 0x00000548, 0x00000558,
518       0x000004e8, 0x000004f0, 0x000004a0, 0x00000488,
519       0x000004b8, 0x00000480, 0x000004a8, 0x000004d0,
520       0x00000498, 0x000004e0, 0x000004c0, 0x000004f8,
521       0x000004b0, 0x00000490, 0x000004c8, 0x000004d8,
522       0x000002e8, 0x000002f0, 0x000002a0, 0x00000288,
523       0x000002b8, 0x00000280, 0x000002a8, 0x000002d0,
524       0x00000298, 0x000002e0, 0x000002c0, 0x000002f8,
525       0x000002b0, 0x00000290, 0x000002c8, 0x000002d8,
526       0x000005e8, 0x000005f0, 0x000005a0, 0x00000588,
527       0x000005b8, 0x00000580, 0x000005a8, 0x000005d0,
528       0x00000598, 0x000005e0, 0x000005c0, 0x000005f8,
529       0x000005b0, 0x00000590, 0x000005c8, 0x000005d8,
530       0x00000268, 0x00000270, 0x00000220, 0x00000208,
531       0x00000238, 0x00000200, 0x00000228, 0x00000250,
532       0x00000218, 0x00000260, 0x00000240, 0x00000278,
533       0x00000230, 0x00000210, 0x00000248, 0x00000258,
534       0x000007e8, 0x000007f0, 0x000007a0, 0x00000788,
535       0x000007b8, 0x00000780, 0x000007a8, 0x000007d0,
536       0x00000798, 0x000007e0, 0x000007c0, 0x000007f8,
537       0x000007b0, 0x00000790, 0x000007c8, 0x000007d8,
538       0x00000468, 0x00000470, 0x00000420, 0x00000408,
539       0x00000438, 0x00000400, 0x00000428, 0x00000450,
540       0x00000418, 0x00000460, 0x00000440, 0x00000478,
541       0x00000430, 0x00000410, 0x00000448, 0x00000458,
542       0x00000368, 0x00000370, 0x00000320, 0x00000308,
543       0x00000338, 0x00000300, 0x00000328, 0x00000350,
544       0x00000318, 0x00000360, 0x00000340, 0x00000378,
545       0x00000330, 0x00000310, 0x00000348, 0x00000358,
546       0x000003e8, 0x000003f0, 0x000003a0, 0x00000388,
547       0x000003b8, 0x00000380, 0x000003a8, 0x000003d0,
548       0x00000398, 0x000003e0, 0x000003c0, 0x000003f8,
549       0x000003b0, 0x00000390, 0x000003c8, 0x000003d8,
550       0x00000768, 0x00000770, 0x00000720, 0x00000708,
551       0x00000738, 0x00000700, 0x00000728, 0x00000750,
552       0x00000718, 0x00000760, 0x00000740, 0x00000778,
553       0x00000730, 0x00000710, 0x00000748, 0x00000758,
554       0x000006e8, 0x000006f0, 0x000006a0, 0x00000688,
555       0x000006b8, 0x00000680, 0x000006a8, 0x000006d0,
556       0x00000698, 0x000006e0, 0x000006c0, 0x000006f8,
557       0x000006b0, 0x00000690, 0x000006c8, 0x000006d8,
558       0x00000068, 0x00000070, 0x00000020, 0x00000008,
559       0x00000038, 0x00000000, 0x00000028, 0x00000050,
560       0x00000018, 0x00000060, 0x00000040, 0x00000078,
561       0x00000030, 0x00000010, 0x00000048, 0x00000058,
562       0x00000168, 0x00000170, 0x00000120, 0x00000108,
563       0x00000138, 0x00000100, 0x00000128, 0x00000150,
564       0x00000118, 0x00000160, 0x00000140, 0x00000178,
565       0x00000130, 0x00000110, 0x00000148, 0x00000158,
566       0x00000668, 0x00000670, 0x00000620, 0x00000608,
567       0x00000638, 0x00000600, 0x00000628, 0x00000650,
568       0x00000618, 0x00000660, 0x00000640, 0x00000678,
569       0x00000630, 0x00000610, 0x00000648, 0x00000658,
570     }
571   }
572 };
573
574 /*
575  *  A macro that performs a full encryption round of GOST 28147-89.
576  */
577 #define GOST_ENCRYPT_ROUND(l, r, key1, key2, sbox) \
578   do { \
579     uint32_t round_tmp; \
580       \
581     round_tmp = (key1) + r; \
582     l ^= (sbox)[0][(round_tmp & 0xff)] ^ \
583          (sbox)[1][((round_tmp >> 8) & 0xff)] ^ \
584          (sbox)[2][((round_tmp >> 16) & 0xff)] ^ \
585          (sbox)[3][(round_tmp >> 24)]; \
586     round_tmp = (key2) + l; \
587     r ^= (sbox)[0][(round_tmp & 0xff)] ^ \
588          (sbox)[1][((round_tmp >> 8) & 0xff)] ^ \
589          (sbox)[2][((round_tmp >> 16) & 0xff)] ^ \
590          (sbox)[3][(round_tmp >> 24)]; \
591   } while (0)
592
593 /* encrypt a block with the given key */
594 void _gost28147_encrypt_block (const uint32_t *key, const uint32_t sbox[4][256],
595                                const uint32_t *in, uint32_t *out)
596 {
597   uint32_t l, r;
598
599   r = in[0], l = in[1];
600   GOST_ENCRYPT_ROUND(l, r, key[0], key[1], sbox);
601   GOST_ENCRYPT_ROUND(l, r, key[2], key[3], sbox);
602   GOST_ENCRYPT_ROUND(l, r, key[4], key[5], sbox);
603   GOST_ENCRYPT_ROUND(l, r, key[6], key[7], sbox);
604   GOST_ENCRYPT_ROUND(l, r, key[0], key[1], sbox);
605   GOST_ENCRYPT_ROUND(l, r, key[2], key[3], sbox);
606   GOST_ENCRYPT_ROUND(l, r, key[4], key[5], sbox);
607   GOST_ENCRYPT_ROUND(l, r, key[6], key[7], sbox);
608   GOST_ENCRYPT_ROUND(l, r, key[0], key[1], sbox);
609   GOST_ENCRYPT_ROUND(l, r, key[2], key[3], sbox);
610   GOST_ENCRYPT_ROUND(l, r, key[4], key[5], sbox);
611   GOST_ENCRYPT_ROUND(l, r, key[6], key[7], sbox);
612   GOST_ENCRYPT_ROUND(l, r, key[7], key[6], sbox);
613   GOST_ENCRYPT_ROUND(l, r, key[5], key[4], sbox);
614   GOST_ENCRYPT_ROUND(l, r, key[3], key[2], sbox);
615   GOST_ENCRYPT_ROUND(l, r, key[1], key[0], sbox);
616   *out = l, *(out + 1) = r;
617 }