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