]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/zfs-tests/tests/functional/checksum/skein_test.c
Vendor import of openzfs master @ 184df27eef0abdc7ab2105b21257f753834b936b
[FreeBSD/FreeBSD.git] / tests / zfs-tests / tests / functional / checksum / skein_test.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://opensource.org/licenses/CDDL-1.0.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright 2013 Saso Kiselkov. All rights reserved.
24  */
25
26 /*
27  * This is just to keep the compiler happy about sys/time.h not declaring
28  * gettimeofday due to -D_KERNEL (we can do this since we're actually
29  * running in userspace, but we need -D_KERNEL for the remaining Skein code).
30  */
31 #ifdef  _KERNEL
32 #undef  _KERNEL
33 #endif
34
35 #include <sys/skein.h>
36 #include <stdlib.h>
37 #include <strings.h>
38 #include <stdio.h>
39 #include <sys/time.h>
40 #include <sys/stdtypes.h>
41 #define NOTE(x)
42
43 /*
44  * Skein test suite using values from the Skein V1.3 specification found at:
45  * http://www.skein-hash.info/sites/default/files/skein1.3.pdf
46  */
47
48 /*
49  * Test messages from the Skein spec, Appendix C.
50  */
51 const uint8_t   test_msg0[] = {
52         0xFF
53 };
54
55 const uint8_t   test_msg1[] = {
56         0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
57         0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
58         0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
59         0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0
60 };
61
62 const uint8_t   test_msg2[] = {
63         0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
64         0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
65         0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
66         0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0,
67         0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8,
68         0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0,
69         0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8,
70         0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0
71 };
72
73 const uint8_t   test_msg3[] = {
74         0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
75         0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
76         0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
77         0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0,
78         0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8,
79         0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0,
80         0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8,
81         0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0,
82         0xBF, 0xBE, 0xBD, 0xBC, 0xBB, 0xBA, 0xB9, 0xB8,
83         0xB7, 0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1, 0xB0,
84         0xAF, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, 0xA8,
85         0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1, 0xA0,
86         0x9F, 0x9E, 0x9D, 0x9C, 0x9B, 0x9A, 0x99, 0x98,
87         0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
88         0x8F, 0x8E, 0x8D, 0x8C, 0x8B, 0x8A, 0x89, 0x88,
89         0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80
90 };
91
92 const uint8_t   test_msg4[] = {
93         0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
94         0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0,
95         0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8,
96         0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0,
97         0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8,
98         0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0,
99         0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8,
100         0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0,
101         0xBF, 0xBE, 0xBD, 0xBC, 0xBB, 0xBA, 0xB9, 0xB8,
102         0xB7, 0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1, 0xB0,
103         0xAF, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, 0xA8,
104         0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1, 0xA0,
105         0x9F, 0x9E, 0x9D, 0x9C, 0x9B, 0x9A, 0x99, 0x98,
106         0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
107         0x8F, 0x8E, 0x8D, 0x8C, 0x8B, 0x8A, 0x89, 0x88,
108         0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
109         0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78,
110         0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
111         0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68,
112         0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
113         0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58,
114         0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
115         0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48,
116         0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
117         0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38,
118         0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
119         0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28,
120         0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
121         0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
122         0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
123         0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
124         0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
125 };
126
127 /*
128  * Test digests from the Skein spec, Appendix C.
129  */
130 const uint8_t   skein_256_test_digests[][32] = {
131         {
132                 /* for test_msg0 */
133                 0x0B, 0x98, 0xDC, 0xD1, 0x98, 0xEA, 0x0E, 0x50,
134                 0xA7, 0xA2, 0x44, 0xC4, 0x44, 0xE2, 0x5C, 0x23,
135                 0xDA, 0x30, 0xC1, 0x0F, 0xC9, 0xA1, 0xF2, 0x70,
136                 0xA6, 0x63, 0x7F, 0x1F, 0x34, 0xE6, 0x7E, 0xD2
137         },
138         {
139                 /* for test_msg1 */
140                 0x8D, 0x0F, 0xA4, 0xEF, 0x77, 0x7F, 0xD7, 0x59,
141                 0xDF, 0xD4, 0x04, 0x4E, 0x6F, 0x6A, 0x5A, 0xC3,
142                 0xC7, 0x74, 0xAE, 0xC9, 0x43, 0xDC, 0xFC, 0x07,
143                 0x92, 0x7B, 0x72, 0x3B, 0x5D, 0xBF, 0x40, 0x8B
144         },
145         {
146                 /* for test_msg2 */
147                 0xDF, 0x28, 0xE9, 0x16, 0x63, 0x0D, 0x0B, 0x44,
148                 0xC4, 0xA8, 0x49, 0xDC, 0x9A, 0x02, 0xF0, 0x7A,
149                 0x07, 0xCB, 0x30, 0xF7, 0x32, 0x31, 0x82, 0x56,
150                 0xB1, 0x5D, 0x86, 0x5A, 0xC4, 0xAE, 0x16, 0x2F
151         }
152         /* no test digests for test_msg3 and test_msg4 */
153 };
154
155 const uint8_t   skein_512_test_digests[][64] = {
156         {
157                 /* for test_msg0 */
158                 0x71, 0xB7, 0xBC, 0xE6, 0xFE, 0x64, 0x52, 0x22,
159                 0x7B, 0x9C, 0xED, 0x60, 0x14, 0x24, 0x9E, 0x5B,
160                 0xF9, 0xA9, 0x75, 0x4C, 0x3A, 0xD6, 0x18, 0xCC,
161                 0xC4, 0xE0, 0xAA, 0xE1, 0x6B, 0x31, 0x6C, 0xC8,
162                 0xCA, 0x69, 0x8D, 0x86, 0x43, 0x07, 0xED, 0x3E,
163                 0x80, 0xB6, 0xEF, 0x15, 0x70, 0x81, 0x2A, 0xC5,
164                 0x27, 0x2D, 0xC4, 0x09, 0xB5, 0xA0, 0x12, 0xDF,
165                 0x2A, 0x57, 0x91, 0x02, 0xF3, 0x40, 0x61, 0x7A
166         },
167         {
168                 /* no test vector for test_msg1 */
169                 0,
170         },
171         {
172                 /* for test_msg2 */
173                 0x45, 0x86, 0x3B, 0xA3, 0xBE, 0x0C, 0x4D, 0xFC,
174                 0x27, 0xE7, 0x5D, 0x35, 0x84, 0x96, 0xF4, 0xAC,
175                 0x9A, 0x73, 0x6A, 0x50, 0x5D, 0x93, 0x13, 0xB4,
176                 0x2B, 0x2F, 0x5E, 0xAD, 0xA7, 0x9F, 0xC1, 0x7F,
177                 0x63, 0x86, 0x1E, 0x94, 0x7A, 0xFB, 0x1D, 0x05,
178                 0x6A, 0xA1, 0x99, 0x57, 0x5A, 0xD3, 0xF8, 0xC9,
179                 0xA3, 0xCC, 0x17, 0x80, 0xB5, 0xE5, 0xFA, 0x4C,
180                 0xAE, 0x05, 0x0E, 0x98, 0x98, 0x76, 0x62, 0x5B
181         },
182         {
183                 /* for test_msg3 */
184                 0x91, 0xCC, 0xA5, 0x10, 0xC2, 0x63, 0xC4, 0xDD,
185                 0xD0, 0x10, 0x53, 0x0A, 0x33, 0x07, 0x33, 0x09,
186                 0x62, 0x86, 0x31, 0xF3, 0x08, 0x74, 0x7E, 0x1B,
187                 0xCB, 0xAA, 0x90, 0xE4, 0x51, 0xCA, 0xB9, 0x2E,
188                 0x51, 0x88, 0x08, 0x7A, 0xF4, 0x18, 0x87, 0x73,
189                 0xA3, 0x32, 0x30, 0x3E, 0x66, 0x67, 0xA7, 0xA2,
190                 0x10, 0x85, 0x6F, 0x74, 0x21, 0x39, 0x00, 0x00,
191                 0x71, 0xF4, 0x8E, 0x8B, 0xA2, 0xA5, 0xAD, 0xB7
192         }
193         /* no test digests for test_msg4 */
194 };
195
196 const uint8_t   skein_1024_test_digests[][128] = {
197         {
198                 /* for test_msg0 */
199                 0xE6, 0x2C, 0x05, 0x80, 0x2E, 0xA0, 0x15, 0x24,
200                 0x07, 0xCD, 0xD8, 0x78, 0x7F, 0xDA, 0x9E, 0x35,
201                 0x70, 0x3D, 0xE8, 0x62, 0xA4, 0xFB, 0xC1, 0x19,
202                 0xCF, 0xF8, 0x59, 0x0A, 0xFE, 0x79, 0x25, 0x0B,
203                 0xCC, 0xC8, 0xB3, 0xFA, 0xF1, 0xBD, 0x24, 0x22,
204                 0xAB, 0x5C, 0x0D, 0x26, 0x3F, 0xB2, 0xF8, 0xAF,
205                 0xB3, 0xF7, 0x96, 0xF0, 0x48, 0x00, 0x03, 0x81,
206                 0x53, 0x1B, 0x6F, 0x00, 0xD8, 0x51, 0x61, 0xBC,
207                 0x0F, 0xFF, 0x4B, 0xEF, 0x24, 0x86, 0xB1, 0xEB,
208                 0xCD, 0x37, 0x73, 0xFA, 0xBF, 0x50, 0xAD, 0x4A,
209                 0xD5, 0x63, 0x9A, 0xF9, 0x04, 0x0E, 0x3F, 0x29,
210                 0xC6, 0xC9, 0x31, 0x30, 0x1B, 0xF7, 0x98, 0x32,
211                 0xE9, 0xDA, 0x09, 0x85, 0x7E, 0x83, 0x1E, 0x82,
212                 0xEF, 0x8B, 0x46, 0x91, 0xC2, 0x35, 0x65, 0x65,
213                 0x15, 0xD4, 0x37, 0xD2, 0xBD, 0xA3, 0x3B, 0xCE,
214                 0xC0, 0x01, 0xC6, 0x7F, 0xFD, 0xE1, 0x5B, 0xA8
215         },
216         {
217                 /* no test vector for test_msg1 */
218                 0
219         },
220         {
221                 /* no test vector for test_msg2 */
222                 0
223         },
224         {
225                 /* for test_msg3 */
226                 0x1F, 0x3E, 0x02, 0xC4, 0x6F, 0xB8, 0x0A, 0x3F,
227                 0xCD, 0x2D, 0xFB, 0xBC, 0x7C, 0x17, 0x38, 0x00,
228                 0xB4, 0x0C, 0x60, 0xC2, 0x35, 0x4A, 0xF5, 0x51,
229                 0x18, 0x9E, 0xBF, 0x43, 0x3C, 0x3D, 0x85, 0xF9,
230                 0xFF, 0x18, 0x03, 0xE6, 0xD9, 0x20, 0x49, 0x31,
231                 0x79, 0xED, 0x7A, 0xE7, 0xFC, 0xE6, 0x9C, 0x35,
232                 0x81, 0xA5, 0xA2, 0xF8, 0x2D, 0x3E, 0x0C, 0x7A,
233                 0x29, 0x55, 0x74, 0xD0, 0xCD, 0x7D, 0x21, 0x7C,
234                 0x48, 0x4D, 0x2F, 0x63, 0x13, 0xD5, 0x9A, 0x77,
235                 0x18, 0xEA, 0xD0, 0x7D, 0x07, 0x29, 0xC2, 0x48,
236                 0x51, 0xD7, 0xE7, 0xD2, 0x49, 0x1B, 0x90, 0x2D,
237                 0x48, 0x91, 0x94, 0xE6, 0xB7, 0xD3, 0x69, 0xDB,
238                 0x0A, 0xB7, 0xAA, 0x10, 0x6F, 0x0E, 0xE0, 0xA3,
239                 0x9A, 0x42, 0xEF, 0xC5, 0x4F, 0x18, 0xD9, 0x37,
240                 0x76, 0x08, 0x09, 0x85, 0xF9, 0x07, 0x57, 0x4F,
241                 0x99, 0x5E, 0xC6, 0xA3, 0x71, 0x53, 0xA5, 0x78
242         },
243         {
244                 /* for test_msg4 */
245                 0x84, 0x2A, 0x53, 0xC9, 0x9C, 0x12, 0xB0, 0xCF,
246                 0x80, 0xCF, 0x69, 0x49, 0x1B, 0xE5, 0xE2, 0xF7,
247                 0x51, 0x5D, 0xE8, 0x73, 0x3B, 0x6E, 0xA9, 0x42,
248                 0x2D, 0xFD, 0x67, 0x66, 0x65, 0xB5, 0xFA, 0x42,
249                 0xFF, 0xB3, 0xA9, 0xC4, 0x8C, 0x21, 0x77, 0x77,
250                 0x95, 0x08, 0x48, 0xCE, 0xCD, 0xB4, 0x8F, 0x64,
251                 0x0F, 0x81, 0xFB, 0x92, 0xBE, 0xF6, 0xF8, 0x8F,
252                 0x7A, 0x85, 0xC1, 0xF7, 0xCD, 0x14, 0x46, 0xC9,
253                 0x16, 0x1C, 0x0A, 0xFE, 0x8F, 0x25, 0xAE, 0x44,
254                 0x4F, 0x40, 0xD3, 0x68, 0x00, 0x81, 0xC3, 0x5A,
255                 0xA4, 0x3F, 0x64, 0x0F, 0xD5, 0xFA, 0x3C, 0x3C,
256                 0x03, 0x0B, 0xCC, 0x06, 0xAB, 0xAC, 0x01, 0xD0,
257                 0x98, 0xBC, 0xC9, 0x84, 0xEB, 0xD8, 0x32, 0x27,
258                 0x12, 0x92, 0x1E, 0x00, 0xB1, 0xBA, 0x07, 0xD6,
259                 0xD0, 0x1F, 0x26, 0x90, 0x70, 0x50, 0x25, 0x5E,
260                 0xF2, 0xC8, 0xE2, 0x4F, 0x71, 0x6C, 0x52, 0xA5
261         }
262 };
263
264 int
265 main(int argc, char *argv[])
266 {
267         boolean_t       failed = B_FALSE;
268         uint64_t        cpu_mhz = 0;
269
270         if (argc == 2)
271                 cpu_mhz = atoi(argv[1]);
272
273 #define SKEIN_ALGO_TEST(_m, mode, diglen, testdigest)                   \
274         do {                                                            \
275                 Skein ## mode ## _Ctxt_t        ctx;                    \
276                 uint8_t                         digest[diglen / 8];     \
277                 (void) Skein ## mode ## _Init(&ctx, diglen);            \
278                 (void) Skein ## mode ## _Update(&ctx, _m, sizeof (_m)); \
279                 (void) Skein ## mode ## _Final(&ctx, digest);           \
280                 (void) printf("Skein" #mode "/" #diglen                 \
281                     "\tMessage: " #_m "\tResult: ");                    \
282                 if (bcmp(digest, testdigest, diglen / 8) == 0) {        \
283                         (void) printf("OK\n");                          \
284                 } else {                                                \
285                         (void) printf("FAILED!\n");                     \
286                         failed = B_TRUE;                                \
287                 }                                                       \
288                 NOTE(CONSTCOND)                                         \
289         } while (0)
290
291 #define SKEIN_PERF_TEST(mode, diglen)                                   \
292         do {                                                            \
293                 Skein ## mode ## _Ctxt_t ctx;                           \
294                 uint8_t         digest[diglen / 8];                     \
295                 uint8_t         block[131072];                          \
296                 uint64_t        delta;                                  \
297                 double          cpb = 0;                                \
298                 int             i;                                      \
299                 struct timeval  start, end;                             \
300                 bzero(block, sizeof (block));                           \
301                 (void) gettimeofday(&start, NULL);                      \
302                 (void) Skein ## mode ## _Init(&ctx, diglen);            \
303                 for (i = 0; i < 8192; i++) {                            \
304                         (void) Skein ## mode ## _Update(&ctx, block,    \
305                             sizeof (block));                            \
306                 }                                                       \
307                 (void) Skein ## mode ## _Final(&ctx, digest);           \
308                 (void) gettimeofday(&end, NULL);                        \
309                 delta = (end.tv_sec * 1000000llu + end.tv_usec) -       \
310                     (start.tv_sec * 1000000llu + start.tv_usec);        \
311                 if (cpu_mhz != 0) {                                     \
312                         cpb = (cpu_mhz * 1e6 * ((double)delta /         \
313                             1000000)) / (8192 * 128 * 1024);            \
314                 }                                                       \
315                 (void) printf("Skein" #mode "/" #diglen "\t%llu us "    \
316                     "(%.02f CPB)\n", (u_longlong_t)delta, cpb);         \
317                 NOTE(CONSTCOND)                                         \
318         } while (0)
319
320         (void) printf("Running algorithm correctness tests:\n");
321         SKEIN_ALGO_TEST(test_msg0, _256, 256, skein_256_test_digests[0]);
322         SKEIN_ALGO_TEST(test_msg1, _256, 256, skein_256_test_digests[1]);
323         SKEIN_ALGO_TEST(test_msg2, _256, 256, skein_256_test_digests[2]);
324         SKEIN_ALGO_TEST(test_msg0, _512, 512, skein_512_test_digests[0]);
325         SKEIN_ALGO_TEST(test_msg2, _512, 512, skein_512_test_digests[2]);
326         SKEIN_ALGO_TEST(test_msg3, _512, 512, skein_512_test_digests[3]);
327         SKEIN_ALGO_TEST(test_msg0, 1024, 1024, skein_1024_test_digests[0]);
328         SKEIN_ALGO_TEST(test_msg3, 1024, 1024, skein_1024_test_digests[3]);
329         SKEIN_ALGO_TEST(test_msg4, 1024, 1024, skein_1024_test_digests[4]);
330         if (failed)
331                 return (1);
332
333         (void) printf("Running performance tests (hashing 1024 MiB of "
334             "data):\n");
335         SKEIN_PERF_TEST(_256, 256);
336         SKEIN_PERF_TEST(_512, 512);
337         SKEIN_PERF_TEST(1024, 1024);
338
339         return (0);
340 }