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).
35 #include <sys/skein.h>
40 #include <sys/stdtypes.h>
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
49 * Test messages from the Skein spec, Appendix C.
51 const uint8_t test_msg0[] = {
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
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
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
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
128 * Test digests from the Skein spec, Appendix C.
130 const uint8_t skein_256_test_digests[][32] = {
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
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
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
152 /* no test digests for test_msg3 and test_msg4 */
155 const uint8_t skein_512_test_digests[][64] = {
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
168 /* no test vector for test_msg1 */
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
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
193 /* no test digests for test_msg4 */
196 const uint8_t skein_1024_test_digests[][128] = {
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
217 /* no test vector for test_msg1 */
221 /* no test vector for test_msg2 */
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
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
265 main(int argc, char *argv[])
267 boolean_t failed = B_FALSE;
268 uint64_t cpu_mhz = 0;
271 cpu_mhz = atoi(argv[1]);
273 #define SKEIN_ALGO_TEST(_m, mode, diglen, testdigest) \
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"); \
285 (void) printf("FAILED!\n"); \
291 #define SKEIN_PERF_TEST(mode, diglen) \
293 Skein ## mode ## _Ctxt_t ctx; \
294 uint8_t digest[diglen / 8]; \
295 uint8_t block[131072]; \
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, \
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); \
315 (void) printf("Skein" #mode "/" #diglen "\t%llu us " \
316 "(%.02f CPB)\n", (u_longlong_t)delta, cpb); \
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]);
333 (void) printf("Running performance tests (hashing 1024 MiB of "
335 SKEIN_PERF_TEST(_256, 256);
336 SKEIN_PERF_TEST(_512, 512);
337 SKEIN_PERF_TEST(1024, 1024);