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