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 #include <note.h> 41 42 /* 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 45 */ 46 47 /* 48 * Test messages from the Skein spec, Appendix C. 49 */ 50 const uint8_t test_msg0[] = { 51 0xFF 52 }; 53 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 59 }; 60 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 70 }; 71 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 89 }; 90 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 124 }; 125 126 /* 127 * Test digests from the Skein spec, Appendix C. 128 */ 129 const uint8_t skein_256_test_digests[][32] = { 130 { 131 /* for test_msg0 */ 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 136 }, 137 { 138 /* for test_msg1 */ 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 143 }, 144 { 145 /* for test_msg2 */ 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 150 } 151 /* no test digests for test_msg3 and test_msg4 */ 152 }; 153 154 const uint8_t skein_512_test_digests[][64] = { 155 { 156 /* for test_msg0 */ 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 165 }, 166 { 167 /* no test vector for test_msg1 */ 168 0 169 }, 170 { 171 /* for test_msg2 */ 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 180 }, 181 { 182 /* for test_msg3 */ 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 191 } 192 /* no test digests for test_msg4 */ 193 }; 194 195 const uint8_t skein_1024_test_digests[][128] = { 196 { 197 /* for test_msg0 */ 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 214 }, 215 { 216 /* no test vector for test_msg1 */ 217 0 218 }, 219 { 220 /* no test vector for test_msg2 */ 221 0 222 }, 223 { 224 /* for test_msg3 */ 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 241 }, 242 { 243 /* for test_msg4 */ 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 260 } 261 }; 262 263 int 264 main(int argc, char *argv[]) 265 { 266 boolean_t failed = B_FALSE; 267 uint64_t cpu_mhz = 0; 268 269 if (argc == 2) 270 cpu_mhz = atoi(argv[1]); 271 272 #define SKEIN_ALGO_TEST(_m, mode, diglen, testdigest) \ 273 do { \ 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"); \ 283 } else { \ 284 (void) printf("FAILED!\n"); \ 285 failed = B_TRUE; \ 286 } \ 287 NOTE(CONSTCOND) \ 288 } while (0) 289 290 #define SKEIN_PERF_TEST(mode, diglen) \ 291 do { \ 292 Skein ## mode ## _Ctxt_t ctx; \ 293 uint8_t digest[diglen / 8]; \ 294 uint8_t block[131072]; \ 295 uint64_t delta; \ 296 double cpb = 0; \ 297 int i; \ 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, \ 304 sizeof (block)); \ 305 } \ 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); \ 313 } \ 314 (void) printf("Skein" #mode "/" #diglen "\t%llu us " \ 315 "(%.02f CPB)\n", (u_longlong_t)delta, cpb); \ 316 NOTE(CONSTCOND) \ 317 } while (0) 318 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]); 329 if (failed) 330 return (1); 331 332 (void) printf("Running performance tests (hashing 1024 MiB of " 333 "data):\n"); 334 SKEIN_PERF_TEST(_256, 256); 335 SKEIN_PERF_TEST(_512, 512); 336 SKEIN_PERF_TEST(1024, 1024); 337 338 return (0); 339 } 340