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