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