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