e60c9ae5cddf0c324a0a53aa45ccf1f7580d628c
[platform/upstream/nettle.git] / gosthash94.c
1 /* gost.c - an implementation of GOST Hash Function
2  * based on the Russian Standard GOST R 34.11-94.
3  * See also RFC 4357.
4  *
5  * Copyright: 2009-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * Ported to nettle by Nikos Mavrogiannopoulos.
29  */
30
31 #if HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <assert.h>
36 #include <string.h>
37
38 #include "macros.h"
39 #include "nettle-write.h"
40 #include "gosthash94.h"
41
42 /* pre-initialized GOST lookup tables based on rotated S-Box */
43 static const uint32_t gosthash94_sbox[4][256] = {
44   {
45     0x72000, 0x75000, 0x74800, 0x71000, 0x76800,
46     0x74000, 0x70000, 0x77000, 0x73000, 0x75800,
47     0x70800, 0x76000, 0x73800, 0x77800, 0x72800,
48     0x71800, 0x5A000, 0x5D000, 0x5C800, 0x59000,
49     0x5E800, 0x5C000, 0x58000, 0x5F000, 0x5B000,
50     0x5D800, 0x58800, 0x5E000, 0x5B800, 0x5F800,
51     0x5A800, 0x59800, 0x22000, 0x25000, 0x24800,
52     0x21000, 0x26800, 0x24000, 0x20000, 0x27000,
53     0x23000, 0x25800, 0x20800, 0x26000, 0x23800,
54     0x27800, 0x22800, 0x21800, 0x62000, 0x65000,
55     0x64800, 0x61000, 0x66800, 0x64000, 0x60000,
56     0x67000, 0x63000, 0x65800, 0x60800, 0x66000,
57     0x63800, 0x67800, 0x62800, 0x61800, 0x32000,
58     0x35000, 0x34800, 0x31000, 0x36800, 0x34000,
59     0x30000, 0x37000, 0x33000, 0x35800, 0x30800,
60     0x36000, 0x33800, 0x37800, 0x32800, 0x31800,
61     0x6A000, 0x6D000, 0x6C800, 0x69000, 0x6E800,
62     0x6C000, 0x68000, 0x6F000, 0x6B000, 0x6D800,
63     0x68800, 0x6E000, 0x6B800, 0x6F800, 0x6A800,
64     0x69800, 0x7A000, 0x7D000, 0x7C800, 0x79000,
65     0x7E800, 0x7C000, 0x78000, 0x7F000, 0x7B000,
66     0x7D800, 0x78800, 0x7E000, 0x7B800, 0x7F800,
67     0x7A800, 0x79800, 0x52000, 0x55000, 0x54800,
68     0x51000, 0x56800, 0x54000, 0x50000, 0x57000,
69     0x53000, 0x55800, 0x50800, 0x56000, 0x53800,
70     0x57800, 0x52800, 0x51800, 0x12000, 0x15000,
71     0x14800, 0x11000, 0x16800, 0x14000, 0x10000,
72     0x17000, 0x13000, 0x15800, 0x10800, 0x16000,
73     0x13800, 0x17800, 0x12800, 0x11800, 0x1A000,
74     0x1D000, 0x1C800, 0x19000, 0x1E800, 0x1C000,
75     0x18000, 0x1F000, 0x1B000, 0x1D800, 0x18800,
76     0x1E000, 0x1B800, 0x1F800, 0x1A800, 0x19800,
77     0x42000, 0x45000, 0x44800, 0x41000, 0x46800,
78     0x44000, 0x40000, 0x47000, 0x43000, 0x45800,
79     0x40800, 0x46000, 0x43800, 0x47800, 0x42800,
80     0x41800, 0xA000,  0xD000,  0xC800,  0x9000,
81     0xE800,  0xC000,  0x8000,  0xF000,  0xB000,
82     0xD800,  0x8800,  0xE000,  0xB800,  0xF800,
83     0xA800,  0x9800,  0x2000,  0x5000,  0x4800,
84     0x1000,  0x6800,  0x4000,  0x0,     0x7000,
85     0x3000,  0x5800,  0x800,   0x6000,  0x3800,
86     0x7800,  0x2800,  0x1800,  0x3A000, 0x3D000,
87     0x3C800, 0x39000, 0x3E800, 0x3C000, 0x38000,
88     0x3F000, 0x3B000, 0x3D800, 0x38800, 0x3E000,
89     0x3B800, 0x3F800, 0x3A800, 0x39800, 0x2A000,
90     0x2D000, 0x2C800, 0x29000, 0x2E800, 0x2C000,
91     0x28000, 0x2F000, 0x2B000, 0x2D800, 0x28800,
92     0x2E000, 0x2B800, 0x2F800, 0x2A800, 0x29800,
93     0x4A000, 0x4D000, 0x4C800, 0x49000, 0x4E800,
94     0x4C000, 0x48000, 0x4F000, 0x4B000, 0x4D800,
95     0x48800, 0x4E000, 0x4B800, 0x4F800, 0x4A800,
96     0x49800
97   }, {
98     0x3A80000, 0x3C00000, 0x3880000, 0x3E80000, 0x3D00000,
99     0x3980000, 0x3A00000, 0x3900000, 0x3F00000, 0x3F80000,
100     0x3E00000, 0x3B80000, 0x3B00000, 0x3800000, 0x3C80000,
101     0x3D80000, 0x6A80000, 0x6C00000, 0x6880000, 0x6E80000,
102     0x6D00000, 0x6980000, 0x6A00000, 0x6900000, 0x6F00000,
103     0x6F80000, 0x6E00000, 0x6B80000, 0x6B00000, 0x6800000,
104     0x6C80000, 0x6D80000, 0x5280000, 0x5400000, 0x5080000,
105     0x5680000, 0x5500000, 0x5180000, 0x5200000, 0x5100000,
106     0x5700000, 0x5780000, 0x5600000, 0x5380000, 0x5300000,
107     0x5000000, 0x5480000, 0x5580000, 0xA80000,  0xC00000,
108     0x880000,  0xE80000,  0xD00000,  0x980000,  0xA00000,
109     0x900000,  0xF00000,  0xF80000,  0xE00000,  0xB80000,
110     0xB00000,  0x800000,  0xC80000,  0xD80000,  0x280000,
111     0x400000,  0x80000,   0x680000,  0x500000,  0x180000,
112     0x200000,  0x100000,  0x700000,  0x780000,  0x600000,
113     0x380000,  0x300000,  0x0,       0x480000,  0x580000,
114     0x4280000, 0x4400000, 0x4080000, 0x4680000, 0x4500000,
115     0x4180000, 0x4200000, 0x4100000, 0x4700000, 0x4780000,
116     0x4600000, 0x4380000, 0x4300000, 0x4000000, 0x4480000,
117     0x4580000, 0x4A80000, 0x4C00000, 0x4880000, 0x4E80000,
118     0x4D00000, 0x4980000, 0x4A00000, 0x4900000, 0x4F00000,
119     0x4F80000, 0x4E00000, 0x4B80000, 0x4B00000, 0x4800000,
120     0x4C80000, 0x4D80000, 0x7A80000, 0x7C00000, 0x7880000,
121     0x7E80000, 0x7D00000, 0x7980000, 0x7A00000, 0x7900000,
122     0x7F00000, 0x7F80000, 0x7E00000, 0x7B80000, 0x7B00000,
123     0x7800000, 0x7C80000, 0x7D80000, 0x7280000, 0x7400000,
124     0x7080000, 0x7680000, 0x7500000, 0x7180000, 0x7200000,
125     0x7100000, 0x7700000, 0x7780000, 0x7600000, 0x7380000,
126     0x7300000, 0x7000000, 0x7480000, 0x7580000, 0x2280000,
127     0x2400000, 0x2080000, 0x2680000, 0x2500000, 0x2180000,
128     0x2200000, 0x2100000, 0x2700000, 0x2780000, 0x2600000,
129     0x2380000, 0x2300000, 0x2000000, 0x2480000, 0x2580000,
130     0x3280000, 0x3400000, 0x3080000, 0x3680000, 0x3500000,
131     0x3180000, 0x3200000, 0x3100000, 0x3700000, 0x3780000,
132     0x3600000, 0x3380000, 0x3300000, 0x3000000, 0x3480000,
133     0x3580000, 0x6280000, 0x6400000, 0x6080000, 0x6680000,
134     0x6500000, 0x6180000, 0x6200000, 0x6100000, 0x6700000,
135     0x6780000, 0x6600000, 0x6380000, 0x6300000, 0x6000000,
136     0x6480000, 0x6580000, 0x5A80000, 0x5C00000, 0x5880000,
137     0x5E80000, 0x5D00000, 0x5980000, 0x5A00000, 0x5900000,
138     0x5F00000, 0x5F80000, 0x5E00000, 0x5B80000, 0x5B00000,
139     0x5800000, 0x5C80000, 0x5D80000, 0x1280000, 0x1400000,
140     0x1080000, 0x1680000, 0x1500000, 0x1180000, 0x1200000,
141     0x1100000, 0x1700000, 0x1780000, 0x1600000, 0x1380000,
142     0x1300000, 0x1000000, 0x1480000, 0x1580000, 0x2A80000,
143     0x2C00000, 0x2880000, 0x2E80000, 0x2D00000, 0x2980000,
144     0x2A00000, 0x2900000, 0x2F00000, 0x2F80000, 0x2E00000,
145     0x2B80000, 0x2B00000, 0x2800000, 0x2C80000, 0x2D80000,
146     0x1A80000, 0x1C00000, 0x1880000, 0x1E80000, 0x1D00000,
147     0x1980000, 0x1A00000, 0x1900000, 0x1F00000, 0x1F80000,
148     0x1E00000, 0x1B80000, 0x1B00000, 0x1800000, 0x1C80000,
149     0x1D80000
150   }, {
151     0x30000002, 0x60000002, 0x38000002, 0x8000002,
152     0x28000002, 0x78000002, 0x68000002, 0x40000002, 
153     0x20000002, 0x50000002, 0x48000002, 0x70000002, 
154     0x2,        0x18000002, 0x58000002, 0x10000002, 
155     0xB0000005, 0xE0000005, 0xB8000005, 0x88000005,
156     0xA8000005, 0xF8000005, 0xE8000005, 0xC0000005,
157     0xA0000005, 0xD0000005, 0xC8000005, 0xF0000005, 
158     0x80000005, 0x98000005, 0xD8000005, 0x90000005, 
159     0x30000005, 0x60000005, 0x38000005, 0x8000005, 
160     0x28000005, 0x78000005, 0x68000005, 0x40000005,
161     0x20000005, 0x50000005, 0x48000005, 0x70000005, 
162     0x5,        0x18000005, 0x58000005, 0x10000005, 
163     0x30000000, 0x60000000, 0x38000000, 0x8000000, 
164     0x28000000, 0x78000000, 0x68000000, 0x40000000, 
165     0x20000000, 0x50000000, 0x48000000, 0x70000000,
166     0x0,        0x18000000, 0x58000000, 0x10000000, 
167     0xB0000003, 0xE0000003, 0xB8000003, 0x88000003, 
168     0xA8000003, 0xF8000003, 0xE8000003, 0xC0000003, 
169     0xA0000003, 0xD0000003, 0xC8000003, 0xF0000003, 
170     0x80000003, 0x98000003, 0xD8000003, 0x90000003,
171     0x30000001, 0x60000001, 0x38000001, 0x8000001,
172     0x28000001, 0x78000001, 0x68000001, 0x40000001, 
173     0x20000001, 0x50000001, 0x48000001, 0x70000001, 
174     0x1,        0x18000001, 0x58000001, 0x10000001, 
175     0xB0000000, 0xE0000000, 0xB8000000, 0x88000000,
176     0xA8000000, 0xF8000000, 0xE8000000, 0xC0000000,
177     0xA0000000, 0xD0000000, 0xC8000000, 0xF0000000, 
178     0x80000000, 0x98000000, 0xD8000000, 0x90000000, 
179     0xB0000006, 0xE0000006, 0xB8000006, 0x88000006, 
180     0xA8000006, 0xF8000006, 0xE8000006, 0xC0000006,
181     0xA0000006, 0xD0000006, 0xC8000006, 0xF0000006,
182     0x80000006, 0x98000006, 0xD8000006, 0x90000006, 
183     0xB0000001, 0xE0000001, 0xB8000001, 0x88000001, 
184     0xA8000001, 0xF8000001, 0xE8000001, 0xC0000001, 
185     0xA0000001, 0xD0000001, 0xC8000001, 0xF0000001,
186     0x80000001, 0x98000001, 0xD8000001, 0x90000001,
187     0x30000003, 0x60000003, 0x38000003, 0x8000003, 
188     0x28000003, 0x78000003, 0x68000003, 0x40000003, 
189     0x20000003, 0x50000003, 0x48000003, 0x70000003, 
190     0x3,        0x18000003, 0x58000003, 0x10000003,
191     0x30000004, 0x60000004, 0x38000004, 0x8000004,
192     0x28000004, 0x78000004, 0x68000004, 0x40000004, 
193     0x20000004, 0x50000004, 0x48000004, 0x70000004, 
194     0x4,        0x18000004, 0x58000004, 0x10000004, 
195     0xB0000002, 0xE0000002, 0xB8000002, 0x88000002,
196     0xA8000002, 0xF8000002, 0xE8000002, 0xC0000002,
197     0xA0000002, 0xD0000002, 0xC8000002, 0xF0000002, 
198     0x80000002, 0x98000002, 0xD8000002, 0x90000002, 
199     0xB0000004, 0xE0000004, 0xB8000004, 0x88000004, 
200     0xA8000004, 0xF8000004, 0xE8000004, 0xC0000004,
201     0xA0000004, 0xD0000004, 0xC8000004, 0xF0000004,
202     0x80000004, 0x98000004, 0xD8000004, 0x90000004, 
203     0x30000006, 0x60000006, 0x38000006, 0x8000006, 
204     0x28000006, 0x78000006, 0x68000006, 0x40000006, 
205     0x20000006, 0x50000006, 0x48000006, 0x70000006,
206     0x6,        0x18000006, 0x58000006, 0x10000006, 
207     0xB0000007, 0xE0000007, 0xB8000007, 0x88000007, 
208     0xA8000007, 0xF8000007, 0xE8000007, 0xC0000007, 
209     0xA0000007, 0xD0000007, 0xC8000007, 0xF0000007, 
210     0x80000007, 0x98000007, 0xD8000007, 0x90000007,
211     0x30000007, 0x60000007, 0x38000007, 0x8000007,
212     0x28000007, 0x78000007, 0x68000007, 0x40000007, 
213     0x20000007, 0x50000007, 0x48000007, 0x70000007, 
214     0x7,        0x18000007, 0x58000007, 0x10000007
215   }, {
216     0xE8,  0xD8,  0xA0,  0x88,  0x98,  0xF8,  0xA8,  0xC8,  0x80,  0xD0,
217     0xF0,  0xB8,  0xB0,  0xC0,  0x90,  0xE0,  0x7E8, 0x7D8, 0x7A0, 0x788,
218     0x798, 0x7F8, 0x7A8, 0x7C8, 0x780, 0x7D0, 0x7F0, 0x7B8, 0x7B0, 0x7C0,
219     0x790, 0x7E0, 0x6E8, 0x6D8, 0x6A0, 0x688, 0x698, 0x6F8, 0x6A8, 0x6C8,
220     0x680, 0x6D0, 0x6F0, 0x6B8, 0x6B0, 0x6C0, 0x690, 0x6E0, 0x68,  0x58,
221     0x20,  0x8,   0x18,  0x78,  0x28,   0x48,  0x0,   0x50,  0x70,  0x38,
222     0x30,  0x40,  0x10,  0x60,  0x2E8, 0x2D8, 0x2A0, 0x288, 0x298, 0x2F8,
223     0x2A8, 0x2C8, 0x280, 0x2D0, 0x2F0, 0x2B8, 0x2B0, 0x2C0, 0x290, 0x2E0,
224     0x3E8, 0x3D8, 0x3A0, 0x388, 0x398, 0x3F8, 0x3A8, 0x3C8, 0x380, 0x3D0,
225     0x3F0, 0x3B8, 0x3B0, 0x3C0, 0x390, 0x3E0, 0x568, 0x558, 0x520, 0x508,
226     0x518, 0x578, 0x528, 0x548, 0x500, 0x550, 0x570, 0x538, 0x530, 0x540,
227     0x510, 0x560, 0x268, 0x258, 0x220, 0x208, 0x218, 0x278, 0x228, 0x248,
228     0x200, 0x250, 0x270, 0x238, 0x230, 0x240, 0x210, 0x260, 0x4E8, 0x4D8,
229     0x4A0, 0x488, 0x498, 0x4F8, 0x4A8, 0x4C8, 0x480, 0x4D0, 0x4F0, 0x4B8,
230     0x4B0, 0x4C0, 0x490, 0x4E0, 0x168, 0x158, 0x120, 0x108, 0x118, 0x178,
231     0x128, 0x148, 0x100, 0x150, 0x170, 0x138, 0x130, 0x140, 0x110, 0x160,
232     0x1E8, 0x1D8, 0x1A0, 0x188, 0x198, 0x1F8, 0x1A8, 0x1C8, 0x180, 0x1D0,
233     0x1F0, 0x1B8, 0x1B0, 0x1C0, 0x190, 0x1E0, 0x768, 0x758, 0x720, 0x708,
234     0x718, 0x778, 0x728, 0x748, 0x700, 0x750, 0x770, 0x738, 0x730, 0x740,
235     0x710, 0x760, 0x368, 0x358, 0x320, 0x308, 0x318, 0x378, 0x328, 0x348,
236     0x300, 0x350, 0x370, 0x338, 0x330, 0x340, 0x310, 0x360, 0x5E8, 0x5D8,
237     0x5A0, 0x588, 0x598, 0x5F8, 0x5A8, 0x5C8, 0x580, 0x5D0, 0x5F0, 0x5B8,
238     0x5B0, 0x5C0, 0x590, 0x5E0, 0x468, 0x458, 0x420, 0x408, 0x418, 0x478,
239     0x428, 0x448, 0x400, 0x450, 0x470, 0x438, 0x430, 0x440, 0x410, 0x460,
240     0x668, 0x658, 0x620, 0x608, 0x618, 0x678, 0x628, 0x648, 0x600, 0x650,
241     0x670, 0x638, 0x630, 0x640, 0x610, 0x660
242   }
243 };
244
245 /**
246  * Initialize algorithm context before calculating hash
247  * with test parameters set.
248  *
249  * @param ctx context to initalize
250  */
251 void
252 gosthash94_init (struct gosthash94_ctx *ctx)
253 {
254     memset (ctx, 0, sizeof (struct gosthash94_ctx));
255 }
256
257 /*
258  *  A macro that performs a full encryption round of GOST 28147-89.
259  *  Temporary variables tmp assumed and variables r and l for left and right
260  *  blocks.
261  */
262 #define GOST_ENCRYPT_ROUND(key1, key2, sbox) \
263   tmp = (key1) + r; \
264   l ^= (sbox)[0][tmp & 0xff] ^ (sbox)[1][(tmp >> 8) & 0xff] ^ \
265     (sbox)[2][(tmp >> 16) & 0xff] ^ (sbox)[3][tmp >> 24]; \
266   tmp = (key2) + l; \
267   r ^= (sbox)[0][tmp & 0xff] ^ (sbox)[1][(tmp >> 8) & 0xff] ^ \
268     (sbox)[2][(tmp >> 16) & 0xff] ^ (sbox)[3][tmp >> 24];
269
270 /* encrypt a block with the given key */
271 #define GOST_ENCRYPT(result, i, key, hash, sbox) \
272   r = hash[i], l = hash[i + 1]; \
273   GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
274   GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
275   GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
276   GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
277   GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
278   GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
279   GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
280   GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
281   GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
282   GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
283   GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
284   GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
285   GOST_ENCRYPT_ROUND(key[7], key[6], sbox) \
286   GOST_ENCRYPT_ROUND(key[5], key[4], sbox) \
287   GOST_ENCRYPT_ROUND(key[3], key[2], sbox) \
288   GOST_ENCRYPT_ROUND(key[1], key[0], sbox) \
289   result[i] = l, result[i + 1] = r;
290
291 /**
292  * The core transformation. Process a 512-bit block.
293  *
294  * @param hash intermediate message hash
295  * @param block the message block to process
296  */
297 static void
298 gost_block_compress (struct gosthash94_ctx *ctx, const uint32_t *block)
299 {
300     unsigned i;
301     uint32_t key[8], u[8], v[8], w[8], s[8];
302     uint32_t l, r, tmp;
303
304     /* u := hash, v := <256-bit message block> */
305     memcpy (u, ctx->hash, sizeof (u));
306     memcpy (v, block, sizeof (v));
307
308     /* w := u xor v */
309     w[0] = u[0] ^ v[0], w[1] = u[1] ^ v[1];
310     w[2] = u[2] ^ v[2], w[3] = u[3] ^ v[3];
311     w[4] = u[4] ^ v[4], w[5] = u[5] ^ v[5];
312     w[6] = u[6] ^ v[6], w[7] = u[7] ^ v[7];
313
314     /* calculate keys, encrypt hash and store result to the s[] array */
315     for (i = 0;; i += 2)
316       {
317           /* key generation: key_i := P(w) */
318           key[0] =
319               (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) |
320               ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24);
321           key[1] =
322               ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) |
323               ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16);
324           key[2] =
325               ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) |
326               (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8);
327           key[3] =
328               ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) |
329               ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000);
330           key[4] =
331               (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) |
332               ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24);
333           key[5] =
334               ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) |
335               ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16);
336           key[6] =
337               ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) |
338               (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8);
339           key[7] =
340               ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) |
341               ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
342
343           /* encryption: s_i := E_{key_i} (h_i) */
344           GOST_ENCRYPT (s, i, key, ctx->hash, gosthash94_sbox);
345
346           if (i == 0)
347             {
348                 /* w:= A(u) ^ A^2(v) */
349                 w[0] = u[2] ^ v[4], w[1] = u[3] ^ v[5];
350                 w[2] = u[4] ^ v[6], w[3] = u[5] ^ v[7];
351                 w[4] = u[6] ^ (v[0] ^= v[2]);
352                 w[5] = u[7] ^ (v[1] ^= v[3]);
353                 w[6] = (u[0] ^= u[2]) ^ (v[2] ^= v[4]);
354                 w[7] = (u[1] ^= u[3]) ^ (v[3] ^= v[5]);
355             }
356           else if ((i & 2) != 0)
357             {
358                 if (i == 6)
359                     break;
360
361                 /* w := A^2(u) xor A^4(v) xor C_3; u := A(u) xor C_3 */
362                 /* C_3=0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 */
363                 u[2] ^= u[4] ^ 0x000000ff;
364                 u[3] ^= u[5] ^ 0xff00ffff;
365                 u[4] ^= 0xff00ff00;
366                 u[5] ^= 0xff00ff00;
367                 u[6] ^= 0x00ff00ff;
368                 u[7] ^= 0x00ff00ff;
369                 u[0] ^= 0x00ffff00;
370                 u[1] ^= 0xff0000ff;
371
372                 w[0] = u[4] ^ v[0];
373                 w[2] = u[6] ^ v[2];
374                 w[4] = u[0] ^ (v[4] ^= v[6]);
375                 w[6] = u[2] ^ (v[6] ^= v[0]);
376                 w[1] = u[5] ^ v[1];
377                 w[3] = u[7] ^ v[3];
378                 w[5] = u[1] ^ (v[5] ^= v[7]);
379                 w[7] = u[3] ^ (v[7] ^= v[1]);
380             }
381           else
382             {
383                 /* i==4 here */
384                 /* w:= A( A^2(u) xor C_3 ) xor A^6(v) */
385                 w[0] = u[6] ^ v[4], w[1] = u[7] ^ v[5];
386                 w[2] = u[0] ^ v[6], w[3] = u[1] ^ v[7];
387                 w[4] = u[2] ^ (v[0] ^= v[2]);
388                 w[5] = u[3] ^ (v[1] ^= v[3]);
389                 w[6] = (u[4] ^= u[6]) ^ (v[2] ^= v[4]);
390                 w[7] = (u[5] ^= u[7]) ^ (v[3] ^= v[5]);
391             }
392       }
393
394     /* step hash function: x(block, hash) := psi^61(hash xor psi(block xor psi^12(S))) */
395
396     /* 12 rounds of the LFSR and xor in <message block> */
397     u[0] = block[0] ^ s[6];
398     u[1] = block[1] ^ s[7];
399     u[2] =
400         block[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] &
401                                                                     0xffff)
402         ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] &
403                                                                0xffff0000)
404         ^ (s[7] >> 16);
405     u[3] =
406         block[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1]
407                                                                        <<
408                                                                        16)
409         ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6]
410         ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^
411         (s[7] >> 16);
412     u[4] =
413         block[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^
414         (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^
415         (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6]
416                                                                      >> 16)
417         ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
418     u[5] =
419         block[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^
420         (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16)
421         ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6]
422                                                                        >>
423                                                                        16)
424         ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16);
425     u[6] =
426         block[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16)
427         ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6]
428         ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16);
429     u[7] =
430         block[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^
431         (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^
432         (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^
433         (s[7] << 16) ^ (s[7] >> 16);
434
435     /* 1 round of the LFSR (a mixing transformation) and xor with <hash> */
436     v[0] = ctx->hash[0] ^ (u[1] << 16) ^ (u[0] >> 16);
437     v[1] = ctx->hash[1] ^ (u[2] << 16) ^ (u[1] >> 16);
438     v[2] = ctx->hash[2] ^ (u[3] << 16) ^ (u[2] >> 16);
439     v[3] = ctx->hash[3] ^ (u[4] << 16) ^ (u[3] >> 16);
440     v[4] = ctx->hash[4] ^ (u[5] << 16) ^ (u[4] >> 16);
441     v[5] = ctx->hash[5] ^ (u[6] << 16) ^ (u[5] >> 16);
442     v[6] = ctx->hash[6] ^ (u[7] << 16) ^ (u[6] >> 16);
443     v[7] =
444         ctx->
445         hash[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[1] & 0xffff0000)
446         ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000) ^ (u[7] >> 16);
447
448     /* 61 rounds of LFSR, mixing up hash */
449     ctx->hash[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^
450         (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^
451         (v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^
452         (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff);
453     ctx->hash[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^
454         (v[1] & 0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^
455         (v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^
456         (v[7] & 0xffff0000) ^ (v[7] >> 16);
457     ctx->hash[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^
458         (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^
459         v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^
460         (v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16);
461     ctx->hash[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^
462         (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^
463         (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^
464         (v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16);
465     ctx->hash[4] =
466         (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ (v[3] <<
467                                                                     16) ^
468         (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] <<
469                                                                     16) ^
470         (v[6] >> 16) ^ (v[7] << 16);
471     ctx->hash[5] =
472         (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^
473         (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3] ^
474         (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^
475         (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] &
476                                                              0xffff0000);
477     ctx->hash[6] =
478         v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ (v[4] >>
479                                                                    16) ^
480         (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^
481         v[6] ^ (v[7] << 16) ^ v[7];
482     ctx->hash[7] =
483         v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^
484         (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^
485         (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
486 }
487
488 /**
489  * This function calculates hash value by 256-bit blocks.
490  * It updates 256-bit check sum as follows:
491  *    *(uint256_t)(ctx->sum) += *(uint256_t*)block;
492  * and then updates intermediate hash value ctx->hash 
493  * by calling gost_block_compress().
494  *
495  * @param ctx algorithm context
496  * @param block the 256-bit message block to process
497  */
498 static void
499 gost_compute_sum_and_hash (struct gosthash94_ctx *ctx, const uint8_t *block)
500 {
501     uint32_t block_le[8];
502     unsigned i, carry;
503
504     /* compute the 256-bit sum */
505     for (i = carry = 0; i < 8; i++, block += 4)
506       {
507           block_le[i] = LE_READ_UINT32(block);
508           ctx->sum[i] += carry;
509           carry = (ctx->sum[i] < carry);
510           ctx->sum[i] += block_le[i];
511           carry += (ctx->sum[i] < block_le[i]);
512       }
513
514     /* update message hash */
515     gost_block_compress (ctx, block_le);
516 }
517
518 /**
519  * Calculate message hash.
520  * Can be called repeatedly with chunks of the message to be hashed.
521  *
522  * @param ctx the algorithm context containing current hashing state
523  * @param msg message chunk
524  * @param size length of the message chunk
525  */
526 void
527 gosthash94_update (struct gosthash94_ctx *ctx,
528                    size_t length, const uint8_t *msg)
529 {
530     unsigned index = (unsigned) ctx->length & 31;
531     ctx->length += length;
532
533     /* fill partial block */
534     if (index)
535       {
536           unsigned left = GOSTHASH94_BLOCK_SIZE - index;
537           memcpy (ctx->message + index, msg, (length < left ? length : left));
538           if (length < left)
539               return;
540
541           /* process partial block */
542           gost_compute_sum_and_hash (ctx, ctx->message);
543           msg += left;
544           length -= left;
545       }
546     while (length >= GOSTHASH94_BLOCK_SIZE)
547       {
548           gost_compute_sum_and_hash (ctx, msg);
549           msg += GOSTHASH94_BLOCK_SIZE;
550           length -= GOSTHASH94_BLOCK_SIZE;
551       }
552     if (length)
553       {
554           /* save leftovers */
555           memcpy (ctx->message, msg, length);
556       }
557 }
558
559 /**
560  * Finish hashing and store message digest into given array.
561  *
562  * @param ctx the algorithm context containing current hashing state
563  * @param result calculated hash in binary form
564  */
565 void
566 gosthash94_digest (struct gosthash94_ctx *ctx,
567                    size_t length, uint8_t *result)
568 {
569     unsigned index = ctx->length & 31;
570     uint32_t msg32[8];
571
572     assert(length <= GOSTHASH94_DIGEST_SIZE);
573
574     /* pad the last block with zeroes and hash it */
575     if (index > 0)
576       {
577           memset (ctx->message + index, 0, 32 - index);
578           gost_compute_sum_and_hash (ctx, ctx->message);
579       }
580
581     /* hash the message length and the sum */
582     msg32[0] = ctx->length << 3;
583     msg32[1] = ctx->length >> 29;
584     memset (msg32 + 2, 0, sizeof (uint32_t) * 6);
585
586     gost_block_compress (ctx, msg32);
587     gost_block_compress (ctx, ctx->sum);
588
589     /* convert hash state to result bytes */
590     _nettle_write_le32(length, result, ctx->hash);
591     gosthash94_init (ctx);
592 }