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 Edon-R code). 30 */ 31#ifdef _KERNEL 32#undef _KERNEL 33#endif 34 35#include <sys/edonr.h> 36#include <stdlib.h> 37#include <string.h> 38#include <stdio.h> 39#include <sys/note.h> 40#include <sys/time.h> 41#include <sys/stdtypes.h> 42 43/* 44 * Test messages from: 45 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf 46 */ 47const char *test_msg0 = "abc"; 48const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn" 49 "lmnomnopnopq"; 50const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" 51 "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; 52 53/* 54 * Test digests computed by hand. There's no formal standard or spec for edonr. 55 */ 56const uint8_t edonr_224_test_digests[][28] = { 57 { 58 /* for test_msg0 */ 59 0x56, 0x63, 0xc4, 0x93, 0x95, 0x20, 0xfa, 0xf6, 60 0x12, 0x31, 0x65, 0xa4, 0x66, 0xf2, 0x56, 0x01, 61 0x95, 0x2e, 0xa9, 0xe4, 0x24, 0xdd, 0xc9, 0x6b, 62 0xef, 0xd0, 0x40, 0x94 63 }, 64 { 65 /* for test_msg1 */ 66 0xd0, 0x13, 0xe4, 0x87, 0x4d, 0x06, 0x8d, 0xca, 67 0x4e, 0x14, 0xb9, 0x37, 0x2f, 0xce, 0x12, 0x20, 68 0x60, 0xf8, 0x5c, 0x0a, 0xfd, 0x7a, 0x7d, 0x97, 69 0x88, 0x2b, 0x05, 0x75 70 } 71 /* no test vector for test_msg2 */ 72}; 73 74const uint8_t edonr_256_test_digests[][32] = { 75 { 76 /* for test_msg0 */ 77 0x54, 0xd7, 0x8b, 0x13, 0xc7, 0x4e, 0xda, 0x5a, 78 0xed, 0xc2, 0x71, 0xcc, 0x88, 0x1f, 0xb2, 0x2f, 79 0x83, 0x99, 0xaf, 0xd3, 0x04, 0x0b, 0x6a, 0x39, 80 0x2d, 0x73, 0x94, 0x05, 0x50, 0x8d, 0xd8, 0x51 81 }, 82 { 83 /* for test_msg1 */ 84 0x49, 0x2d, 0x0b, 0x19, 0xab, 0x1e, 0xde, 0x3a, 85 0xea, 0x9b, 0xf2, 0x39, 0x3a, 0xb1, 0x21, 0xde, 86 0x21, 0xf6, 0x80, 0x1f, 0xad, 0xbe, 0x8b, 0x07, 87 0xc7, 0xfb, 0xe6, 0x99, 0x0e, 0x4d, 0x73, 0x63 88 } 89 /* no test vectorfor test_msg2 */ 90}; 91 92const uint8_t edonr_384_test_digests[][48] = { 93 { 94 /* for test_msg0 */ 95 0x0e, 0x7c, 0xd7, 0x85, 0x78, 0x77, 0xe0, 0x89, 96 0x5b, 0x1c, 0xdf, 0x49, 0xf4, 0x1d, 0x20, 0x9c, 97 0x72, 0x7d, 0x2e, 0x57, 0x9b, 0x9b, 0x9a, 0xdc, 98 0x60, 0x27, 0x97, 0x82, 0xb9, 0x90, 0x72, 0xec, 99 0x7e, 0xce, 0xd3, 0x16, 0x5f, 0x47, 0x75, 0x48, 100 0xfa, 0x60, 0x72, 0x7e, 0x01, 0xc7, 0x7c, 0xc6 101 }, 102 { 103 /* no test vector for test_msg1 */ 104 0 105 }, 106 { 107 /* for test_msg2 */ 108 0xe2, 0x34, 0xa1, 0x02, 0x83, 0x76, 0xae, 0xe6, 109 0x82, 0xd9, 0x38, 0x32, 0x0e, 0x00, 0x78, 0xd2, 110 0x34, 0xdb, 0xb9, 0xbd, 0xf0, 0x08, 0xa8, 0x0f, 111 0x63, 0x1c, 0x3d, 0x4a, 0xfd, 0x0a, 0xe9, 0x59, 112 0xdc, 0xd4, 0xce, 0xcd, 0x8d, 0x67, 0x6c, 0xea, 113 0xbb, 0x1a, 0x32, 0xed, 0x5c, 0x6b, 0xf1, 0x7f 114 } 115}; 116 117const uint8_t edonr_512_test_digests[][64] = { 118 { 119 /* for test_msg0 */ 120 0x1b, 0x14, 0xdb, 0x15, 0x5f, 0x1d, 0x40, 0x65, 121 0x94, 0xb8, 0xce, 0xf7, 0x0a, 0x43, 0x62, 0xec, 122 0x6b, 0x5d, 0xe6, 0xa5, 0xda, 0xf5, 0x0e, 0xc9, 123 0x99, 0xe9, 0x87, 0xc1, 0x9d, 0x30, 0x49, 0xe2, 124 0xde, 0x59, 0x77, 0xbb, 0x05, 0xb1, 0xbb, 0x22, 125 0x00, 0x50, 0xa1, 0xea, 0x5b, 0x46, 0xa9, 0xf1, 126 0x74, 0x0a, 0xca, 0xfb, 0xf6, 0xb4, 0x50, 0x32, 127 0xad, 0xc9, 0x0c, 0x62, 0x83, 0x72, 0xc2, 0x2b 128 }, 129 { 130 /* no test vector for test_msg1 */ 131 0 132 }, 133 { 134 /* for test_msg2 */ 135 0x53, 0x51, 0x07, 0x0d, 0xc5, 0x1c, 0x3b, 0x2b, 136 0xac, 0xa5, 0xa6, 0x0d, 0x02, 0x52, 0xcc, 0xb4, 137 0xe4, 0x92, 0x1a, 0x96, 0xfe, 0x5a, 0x69, 0xe7, 138 0x6d, 0xad, 0x48, 0xfd, 0x21, 0xa0, 0x84, 0x5a, 139 0xd5, 0x7f, 0x88, 0x0b, 0x3e, 0x4a, 0x90, 0x7b, 140 0xc5, 0x03, 0x15, 0x18, 0x42, 0xbb, 0x94, 0x9e, 141 0x1c, 0xba, 0x74, 0x39, 0xa6, 0x40, 0x9a, 0x34, 142 0xb8, 0x43, 0x6c, 0xb4, 0x69, 0x21, 0x58, 0x3c 143 } 144}; 145 146int 147main(int argc, char *argv[]) 148{ 149 boolean_t failed = B_FALSE; 150 uint64_t cpu_mhz = 0; 151 152 if (argc == 2) 153 cpu_mhz = atoi(argv[1]); 154 155#define EDONR_ALGO_TEST(_m, mode, testdigest) \ 156 do { \ 157 EdonRState ctx; \ 158 uint8_t digest[mode / 8]; \ 159 EdonRInit(&ctx, mode); \ 160 EdonRUpdate(&ctx, (const uint8_t *) _m, strlen(_m) * 8);\ 161 EdonRFinal(&ctx, digest); \ 162 (void) printf("Edon-R-%-6sMessage: " #_m \ 163 "\tResult: ", #mode); \ 164 if (bcmp(digest, testdigest, mode / 8) == 0) { \ 165 (void) printf("OK\n"); \ 166 } else { \ 167 (void) printf("FAILED!\n"); \ 168 failed = B_TRUE; \ 169 } \ 170 NOTE(CONSTCOND) \ 171 } while (0) 172 173#define EDONR_PERF_TEST(mode) \ 174 do { \ 175 EdonRState ctx; \ 176 uint8_t digest[mode / 8]; \ 177 uint8_t block[131072]; \ 178 uint64_t delta; \ 179 double cpb = 0; \ 180 int i; \ 181 struct timeval start, end; \ 182 bzero(block, sizeof (block)); \ 183 (void) gettimeofday(&start, NULL); \ 184 EdonRInit(&ctx, mode); \ 185 for (i = 0; i < 8192; i++) \ 186 EdonRUpdate(&ctx, block, sizeof (block) * 8); \ 187 EdonRFinal(&ctx, digest); \ 188 (void) gettimeofday(&end, NULL); \ 189 delta = (end.tv_sec * 1000000llu + end.tv_usec) - \ 190 (start.tv_sec * 1000000llu + start.tv_usec); \ 191 if (cpu_mhz != 0) { \ 192 cpb = (cpu_mhz * 1e6 * ((double)delta / \ 193 1000000)) / (8192 * 128 * 1024); \ 194 } \ 195 (void) printf("Edon-R-%-6s%llu us (%.02f CPB)\n", #mode,\ 196 (u_longlong_t)delta, cpb); \ 197 NOTE(CONSTCOND) \ 198 } while (0) 199 200 (void) printf("Running algorithm correctness tests:\n"); 201 EDONR_ALGO_TEST(test_msg0, 224, edonr_224_test_digests[0]); 202 EDONR_ALGO_TEST(test_msg1, 224, edonr_224_test_digests[1]); 203 EDONR_ALGO_TEST(test_msg0, 256, edonr_256_test_digests[0]); 204 EDONR_ALGO_TEST(test_msg1, 256, edonr_256_test_digests[1]); 205 EDONR_ALGO_TEST(test_msg0, 384, edonr_384_test_digests[0]); 206 EDONR_ALGO_TEST(test_msg2, 384, edonr_384_test_digests[2]); 207 EDONR_ALGO_TEST(test_msg0, 512, edonr_512_test_digests[0]); 208 EDONR_ALGO_TEST(test_msg2, 512, edonr_512_test_digests[2]); 209 if (failed) 210 return (1); 211 212 (void) printf("Running performance tests (hashing 1024 MiB of " 213 "data):\n"); 214 EDONR_PERF_TEST(256); 215 EDONR_PERF_TEST(512); 216 217 return (0); 218} 219