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