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