libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

unit_sha512_256.c (37458B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 
      3 /*
      4   This file is part of GNU libmicrohttpd.
      5   Copyright (C) 2025 Christian Grothoff
      6 
      7   GNU libmicrohttpd is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   GNU libmicrohttpd is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   Alternatively, you can redistribute GNU libmicrohttpd and/or
     18   modify it under the terms of the GNU General Public License as
     19   published by the Free Software Foundation; either version 2 of
     20   the License, or (at your option) any later version, together
     21   with the eCos exception, as follows:
     22 
     23     As a special exception, if other files instantiate templates or
     24     use macros or inline functions from this file, or you compile this
     25     file and link it with other works to produce a work based on this
     26     file, this file does not by itself cause the resulting work to be
     27     covered by the GNU General Public License. However the source code
     28     for this file must still be made available in accordance with
     29     section (3) of the GNU General Public License v2.
     30 
     31     This exception does not invalidate any other reasons why a work
     32     based on this file might be covered by the GNU General Public
     33     License.
     34 
     35   You should have received copies of the GNU Lesser General Public
     36   License and the GNU General Public License along with this library;
     37   if not, see <https://www.gnu.org/licenses/>.
     38 */
     39 
     40 /**
     41  * @file src/test/unit/unit_sha512_256.c
     42  * @brief  The tests for SHA-512/256
     43  * @author Karlson2k (Evgeny Grin)
     44  * @author Christian Grothoff
     45  */
     46 
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <stdint.h>
     51 
     52 #include "mhd_sys_options.h"
     53 
     54 #if MHD_SHA512_256_EXTR_OPENSSL
     55 #include "../mhd2/sha512_256_ext_openssl.c"
     56 #elif MHD_SHA512_256_EXTR_MBEDTLS
     57 #include "../mhd2/sha512_256_ext_mbedtls.c"
     58 #else
     59 #include "../mhd2/sha256_int.c"
     60 #endif
     61 
     62 #include "../mhd2/mhd_sha512_256.h"
     63 
     64 #define SHA512_256_DIGEST_STRING_SIZE (mhd_SHA256_DIGEST_SIZE * 2 + 1)
     65 
     66 /**
     67  * Verbose output?
     68  */
     69 static int verbose;
     70 
     71 
     72 /**
     73  * Check whether one of strings in array is equal to @a param.
     74  * String @a argv[0] is ignored.
     75  * @param argc number of strings in @a argv, as passed to main function
     76  * @param argv array of strings, as passed to main function
     77  * @param param parameter to look for.
     78  * @return zero if @a argv is NULL, @a param is NULL or empty string,
     79  *         @a argc is less then 2 or @a param is not found in @a argv,
     80  *         non-zero if one of strings in @a argv is equal to @a param.
     81  */
     82 static int
     83 has_param (int argc, char *const argv[], const char *param)
     84 {
     85   int i;
     86   if (! argv || ! param || ! param[0])
     87     return 0;
     88 
     89   for (i = 1; i < argc; i++)
     90   {
     91     if (argv[i] && (strcmp (argv[i], param) == 0) )
     92       return ! 0;
     93   }
     94 
     95   return 0;
     96 }
     97 
     98 
     99 /* Helper function to convert hex string to binary */
    100 static size_t
    101 hex2bin (const char *hex,
    102          uint8_t *bin,
    103          size_t max_len)
    104 {
    105   size_t len = strlen (hex) / 2;
    106   if (len > max_len)
    107     len = max_len;
    108 
    109   for (size_t i = 0; i < len; i++)
    110   {
    111     sscanf (hex + 2 * i, "%2hhx", &bin[i]);
    112   }
    113   return len;
    114 }
    115 
    116 
    117 /* Helper function to compare digest with expected hex string */
    118 static int
    119 check_digest (const uint8_t *digest,
    120               size_t digest_len,
    121               const char *expected_hex,
    122               const char *test_name)
    123 {
    124   uint8_t expected[64];
    125   size_t expected_len = hex2bin (expected_hex, expected, sizeof(expected));
    126 
    127   if (expected_len != digest_len)
    128   {
    129     printf ("FAIL: %s - length mismatch\n",
    130             test_name);
    131     return 0;
    132   }
    133 
    134   if (memcmp (digest, expected, digest_len) != 0)
    135   {
    136     printf ("FAIL: %s\n", test_name);
    137     printf ("  Expected: %s\n", expected_hex);
    138     printf ("  Got:      ");
    139     for (size_t i = 0; i < digest_len; i++)
    140     {
    141       printf ("%02x", digest[i]);
    142     }
    143     printf ("\n");
    144     return 0;
    145   }
    146 
    147   if (verbose)
    148     printf ("PASS: %s\n",
    149             test_name);
    150   return 1;
    151 }
    152 
    153 
    154 struct str_with_len
    155 {
    156   const char *const str;
    157   const size_t len;
    158 };
    159 
    160 #define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
    161 
    162 struct data_unit1
    163 {
    164   const struct str_with_len str_l;
    165   const uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    166 };
    167 
    168 static const struct data_unit1 data_units1[] = {
    169   {D_STR_W_LEN ("abc"),
    170    {0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, 0x9B, 0x2E, 0x29, 0xB7,
    171     0x6B, 0x4C, 0x7D, 0xAB, 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46,
    172     0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23}},
    173   {D_STR_W_LEN ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" \
    174                 "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
    175    {0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8, 0x40, 0xDA, 0x39, 0x88,
    176     0x12, 0x1D, 0x31, 0xBE, 0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14,
    177     0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A}},
    178   {D_STR_W_LEN (""), /* The empty zero-size input */
    179    {0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28, 0xab, 0x87, 0xc3, 0x62,
    180     0x2c, 0x51, 0x14, 0x06, 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
    181     0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a}},
    182   {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."),
    183    {0xc8, 0x7c, 0x5a, 0x55, 0x27, 0x77, 0x1b, 0xe7, 0x69, 0x3c, 0x50, 0x79,
    184     0x32, 0xad, 0x7c, 0x79, 0xe9, 0x60, 0xa0, 0x18, 0xb7, 0x78, 0x2b, 0x6f,
    185     0xa9, 0x7b, 0xa3, 0xa0, 0xb5, 0x18, 0x17, 0xa5}},
    186   {D_STR_W_LEN ("Simple string."),
    187    {0xde, 0xcb, 0x3c, 0x81, 0x65, 0x4b, 0xa0, 0xf5, 0xf0, 0x45, 0x6b, 0x7e,
    188     0x61, 0xf5, 0x0d, 0xf5, 0x38, 0xa4, 0xfc, 0xb1, 0x8a, 0x95, 0xff, 0x59,
    189     0xbc, 0x04, 0x82, 0xcf, 0x23, 0xb2, 0x32, 0x56}},
    190   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"),
    191    {0xfc, 0x31, 0x89, 0x44, 0x3f, 0x9c, 0x26, 0x8f, 0x62, 0x6a, 0xea, 0x08,
    192     0xa7, 0x56, 0xab, 0xe7, 0xb7, 0x26, 0xb0, 0x5f, 0x70, 0x1c, 0xb0, 0x82,
    193     0x22, 0x31, 0x2c, 0xcf, 0xd6, 0x71, 0x0a, 0x26, }},
    194   {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"),
    195    {0xd2, 0x6d, 0x24, 0x81, 0xa4, 0xf9, 0x0a, 0x72, 0xd2, 0x7f, 0xc1, 0xac,
    196     0xac, 0xe1, 0xc0, 0x6b, 0x39, 0x94, 0xac, 0x73, 0x50, 0x2e, 0x27, 0x97,
    197     0xa3, 0x65, 0x37, 0x4e, 0xbb, 0x5c, 0x27, 0xe9}},
    198   {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \
    199                 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"),
    200    {0xad, 0xe9, 0x5d, 0x55, 0x3b, 0x9e, 0x45, 0x69, 0xdb, 0x53, 0xa4, 0x04,
    201     0x92, 0xe7, 0x87, 0x94, 0xff, 0xc9, 0x98, 0x5f, 0x93, 0x03, 0x86, 0x45,
    202     0xe1, 0x97, 0x17, 0x72, 0x7c, 0xbc, 0x31, 0x15}},
    203   {D_STR_W_LEN ("/long/long/long/long/long/long/long/long/long/long/long" \
    204                 "/long/long/long/long/long/long/long/long/long/long/long" \
    205                 "/long/long/long/long/long/long/long/long/long/long/long" \
    206                 "/long/long/long/long/long/long/long/long/long/long/long" \
    207                 "/long/long/long/long/long/long/long/long/long/long/long" \
    208                 "/long/long/long/long/long/long/long/long/long/long/long" \
    209                 "/long/long/long/long/path?with%20some=parameters"),
    210    {0xbc, 0xab, 0xc6, 0x2c, 0x0a, 0x22, 0xd5, 0xcb, 0xac, 0xac, 0xe9, 0x25,
    211     0xcf, 0xce, 0xaa, 0xaf, 0x0e, 0xa1, 0xed, 0x42, 0x46, 0x8a, 0xe2, 0x01,
    212     0xee, 0x2f, 0xdb, 0x39, 0x75, 0x47, 0x73, 0xf1}}
    213 };
    214 
    215 static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]);
    216 
    217 struct bin_with_len
    218 {
    219   const uint8_t bin[512];
    220   const size_t len;
    221 };
    222 
    223 struct data_unit2
    224 {
    225   const struct bin_with_len bin_l;
    226   const uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    227 };
    228 
    229 /* Size must be less than 512 bytes! */
    230 static const struct data_unit2 data_units2[] = {
    231   { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    232        112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */
    233     {0xfc, 0x31, 0x89, 0x44, 0x3f, 0x9c, 0x26, 0x8f, 0x62, 0x6a, 0xea, 0x08,
    234      0xa7, 0x56, 0xab, 0xe7, 0xb7, 0x26, 0xb0, 0x5f, 0x70, 0x1c, 0xb0, 0x82,
    235      0x22, 0x31, 0x2c, 0xcf, 0xd6, 0x71, 0x0a, 0x26}},
    236   { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    237        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    238        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
    239        65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65},
    240       72 }, /* 'A' x 72 times */
    241     {0x36, 0x5d, 0x41, 0x0e, 0x55, 0xd1, 0xfd, 0xe6, 0xc3, 0xb8, 0x68, 0xcc,
    242      0xed, 0xeb, 0xcd, 0x0d, 0x2e, 0x34, 0xb2, 0x5c, 0xdf, 0xe7, 0x79, 0xe2,
    243      0xe9, 0x65, 0x07, 0x33, 0x78, 0x0d, 0x01, 0x89}},
    244   { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
    245        37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
    246        55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
    247        73}, 55}, /* 19..73 sequence */
    248     {0xb9, 0xe5, 0x74, 0x11, 0xbf, 0xa2, 0x0e, 0x98, 0xbe, 0x08, 0x69, 0x2e,
    249      0x17, 0x9e, 0xc3, 0xfe, 0x61, 0xe3, 0x7a, 0x80, 0x2e, 0x25, 0x8c, 0xf3,
    250      0x76, 0xda, 0x9f, 0x5f, 0xcd, 0x87, 0x48, 0x0d}},
    251   { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
    252        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
    253        44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
    254        62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */
    255     {0x80, 0x15, 0x83, 0xed, 0x7d, 0xef, 0x9f, 0xdf, 0xfb, 0x83, 0x1f, 0xc5,
    256      0x8b, 0x50, 0x37, 0x81, 0x00, 0xc3, 0x4f, 0xfd, 0xfe, 0xc2, 0x9b, 0xaf,
    257      0xfe, 0x15, 0x66, 0xe5, 0x08, 0x42, 0x5e, 0xae}},
    258   { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
    259        56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
    260        74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
    261        92}, 55}, /* 38..92 sequence */
    262     {0x76, 0x2f, 0x27, 0x4d, 0xfa, 0xd5, 0xa9, 0x21, 0x4e, 0xe9, 0x56, 0x22,
    263      0x54, 0x38, 0x71, 0x3e, 0xef, 0x14, 0xa9, 0x22, 0x37, 0xf3, 0xb0, 0x50,
    264      0x3d, 0x95, 0x40, 0xb7, 0x08, 0x64, 0xa9, 0xfd}},
    265   { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    266        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
    267        39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
    268        57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72}, 72}, /* 1..72 sequence */
    269     {0x3f, 0x5c, 0xd3, 0xec, 0x40, 0xc4, 0xb9, 0x78, 0x35, 0x57, 0xc6, 0x4f,
    270      0x3e, 0x46, 0x82, 0xdc, 0xd4, 0x46, 0x11, 0xd0, 0xb3, 0x0a, 0xbb, 0x89,
    271      0xf1, 0x1d, 0x34, 0xb5, 0xf9, 0xd5, 0x10, 0x35}},
    272   { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    273        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
    274        39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
    275        57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
    276        75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
    277        93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
    278        109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
    279        123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
    280        137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
    281        151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
    282        165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
    283        179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
    284        193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
    285        207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
    286        221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
    287        235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
    288        249, 250, 251, 252, 253, 254, 255}, 256}, /* 0..255 sequence */
    289     {0x08, 0x37, 0xa1, 0x1d, 0x99, 0x4d, 0x5a, 0xa8, 0x60, 0xd0, 0x69, 0x17,
    290      0xa8, 0xa0, 0xf6, 0x3e, 0x31, 0x11, 0xb9, 0x56, 0x33, 0xde, 0xeb, 0x15,
    291      0xee, 0xd9, 0x94, 0x93, 0x76, 0xf3, 0x7d, 0x36, }},
    292   { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
    293        185, 184, 183, 182, 181, 180,
    294        179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
    295        165, 164, 163, 162, 161, 160,
    296        159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146,
    297        145, 144, 143, 142, 141, 140,
    298        139}, 61},  /* 199..139 sequence */
    299     {0xcf, 0x21, 0x4b, 0xb2, 0xdd, 0x40, 0x98, 0xdf, 0x3a, 0xb7, 0x21, 0xb4,
    300      0x69, 0x0e, 0x19, 0x36, 0x24, 0xa9, 0xbe, 0x30, 0xf7, 0xd0, 0x75, 0xb0,
    301      0x39, 0x94, 0x82, 0xda, 0x55, 0x97, 0xe4, 0x79}},
    302   { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
    303        241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228,
    304        227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, 214,
    305        213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
    306        199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
    307        185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172,
    308        171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 158,
    309        157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
    310        143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130,
    311        129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116,
    312        115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102,
    313        101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
    314        84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,
    315        66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
    316        48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31,
    317        30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
    318        12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255},  /* 255..1 sequence */
    319     {0x22, 0x31, 0xf2, 0xa1, 0xb4, 0x89, 0xb2, 0x44, 0xf7, 0x66, 0xa0, 0xb8,
    320      0x31, 0xed, 0xb7, 0x73, 0x8a, 0x34, 0xdc, 0x11, 0xc8, 0x2c, 0xf2, 0xb5,
    321      0x88, 0x60, 0x39, 0x6b, 0x5c, 0x06, 0x70, 0x37}},
    322   { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233,
    323        235, 179, 166, 219, 60, 135, 12, 62, 153, 36, 94, 13, 28, 6, 183, 71,
    324        222, 179, 18, 77, 200, 67, 187, 139, 166, 31, 3, 90, 125, 9, 56, 37,
    325        31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28, 219, 174,
    326        50, 32, 154, 80, 238, 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73,
    327        220, 173, 79, 20, 242, 68, 64, 102, 208, 107, 196, 48, 183, 50, 59,
    328        161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202, 153, 2, 185,
    329        114, 157, 73, 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201,
    330        204, 83, 191, 103, 214, 191, 20, 214, 126, 45, 220, 142, 102, 131, 239,
    331        87, 73, 97, 255, 105, 143, 97, 205, 209, 30, 157, 156, 22, 114, 114,
    332        230, 29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18,
    333        30, 51, 116, 158, 12, 244, 213, 212, 159, 212, 164, 89, 126, 53, 207,
    334        50, 34, 244, 204, 207, 211, 144, 45, 72, 211, 143, 117, 230, 217, 29,
    335        42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212, 97, 141,
    336        190, 123, 5, 21, 7, 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206,
    337        177, 133, 62, 105, 21, 248, 70, 106, 4, 150, 115, 14, 217, 22, 47, 103,
    338        104, 212, 247, 74, 74, 208, 87, 104}, 255},  /* pseudo-random data */
    339     {0xb8, 0xdb, 0x2c, 0x2e, 0xf3, 0x12, 0x77, 0x14, 0xf9, 0x34, 0x2d, 0xfa,
    340      0xda, 0x42, 0xbe, 0xfe, 0x67, 0x3a, 0x8a, 0xf6, 0x71, 0x36, 0x00, 0xff,
    341      0x77, 0xa5, 0x83, 0x14, 0x55, 0x2a, 0x05, 0xaf}},
    342   { { {66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    343        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    344        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    345        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    346        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    347        66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
    348        66, 66}, 110},  /* 'B' x 110 times */
    349     {0xc8, 0x9e, 0x0d, 0x8f, 0x7b, 0x35, 0xfd, 0x3e, 0xdc, 0x90, 0x87, 0x64,
    350      0x45, 0x94, 0x94, 0x21, 0xb3, 0x8e, 0xb5, 0xc7, 0x54, 0xc8, 0xee, 0xde,
    351      0xfc, 0x77, 0xd6, 0xe3, 0x9f, 0x81, 0x8e, 0x78}},
    352   { { {67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    353        67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    354        67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    355        67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    356        67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    357        67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
    358        67, 67, 67}, 111},  /* 'C' x 111 times */
    359     {0x86, 0xca, 0x6d, 0x2a, 0x72, 0xe2, 0x8c, 0x17, 0x89, 0x86, 0x89, 0x1b,
    360      0x36, 0xf9, 0x6d, 0xda, 0x8c, 0xd6, 0x30, 0xb2, 0xd3, 0x60, 0x39, 0xfb,
    361      0xc9, 0x04, 0xc5, 0x11, 0xcd, 0x2d, 0xe3, 0x62}},
    362   { { {68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    363        68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    364        68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    365        68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    366        68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    367        68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
    368        68, 68, 68, 68}, 112},  /* 'D' x 112 times */
    369     {0xdf, 0x9d, 0x4a, 0xcf, 0x81, 0x0d, 0x3a, 0xd4, 0x8e, 0xa4, 0x65, 0x9e,
    370      0x1e, 0x15, 0xe4, 0x15, 0x1b, 0x37, 0xb6, 0xeb, 0x17, 0xab, 0xf6, 0xb1,
    371      0xbc, 0x30, 0x46, 0x34, 0x24, 0x56, 0x1c, 0x06}},
    372   { { {69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    373        69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    374        69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    375        69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    376        69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    377        69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
    378        69, 69, 69, 69, 69}, 113},  /* 'E' x 113 times */
    379     {0xa5, 0xf1, 0x47, 0x74, 0xf8, 0x2b, 0xed, 0x23, 0xe4, 0x10, 0x59, 0x8f,
    380      0x7e, 0xb1, 0x30, 0xe5, 0x7e, 0xd1, 0x4b, 0xbc, 0x72, 0x58, 0x58, 0x81,
    381      0xbb, 0xa0, 0xa5, 0xb6, 0x15, 0x39, 0x49, 0xa1}},
    382   { { {70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    383        70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    384        70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    385        70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    386        70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    387        70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    388        70, 70, 70, 70, 70, 70}, 114},  /* 'F' x 114 times */
    389     {0xe6, 0xa3, 0xc9, 0x63, 0xd5, 0x28, 0x6e, 0x2d, 0xfb, 0x71, 0xdf, 0xd4,
    390      0xff, 0xc2, 0xd4, 0x2b, 0x5d, 0x9b, 0x76, 0x28, 0xd2, 0xcb, 0x15, 0xc8,
    391      0x81, 0x57, 0x14, 0x09, 0xc3, 0x8e, 0x92, 0xce}},
    392   { { {76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    393        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    394        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    395        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    396        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    397        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    398        76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
    399        76}, 127},  /* 'L' x 127 times */
    400     {0x5d, 0x18, 0xff, 0xd7, 0xbe, 0x23, 0xb2, 0xb2, 0xbd, 0xe3, 0x13, 0x12,
    401      0x1c, 0x16, 0x89, 0x14, 0x4a, 0x42, 0xb4, 0x3f, 0xab, 0xc8, 0x41, 0x14,
    402      0x62, 0x00, 0xb5, 0x53, 0xa7, 0xd6, 0xd5, 0x35}},
    403   { { {77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    404        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    405        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    406        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    407        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    408        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    409        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
    410        77, 77}, 128},  /* 'M' x 128 times */
    411     {0x6e, 0xf0, 0xda, 0x81, 0x3d, 0x50, 0x1d, 0x31, 0xf1, 0x4a, 0xf8, 0xd9,
    412      0x7d, 0xd2, 0x13, 0xdd, 0xa4, 0x46, 0x15, 0x0b, 0xb8, 0x5a, 0x8a, 0xc6,
    413      0x1e, 0x3a, 0x1f, 0x21, 0x35, 0xa2, 0xbb, 0x4f}},
    414   { { {78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    415        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    416        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    417        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    418        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    419        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    420        78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
    421        78, 78, 78}, 129},  /* 'N' x 129 times */
    422     {0xee, 0xce, 0xd5, 0x34, 0xab, 0x14, 0x13, 0x9e, 0x8f, 0x5c, 0xb4, 0xef,
    423      0xac, 0xaf, 0xc5, 0xeb, 0x1d, 0x2f, 0xe3, 0xc5, 0xca, 0x09, 0x29, 0x96,
    424      0xfa, 0x84, 0xff, 0x12, 0x26, 0x6a, 0x50, 0x49}},
    425   { { {97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    426        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    427        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    428        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    429        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    430        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    431        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    432        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    433        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    434        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    435        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    436        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    437        97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
    438        97, 97, 97, 97}, 238},  /* 'a' x 238 times */
    439     {0xb4, 0x24, 0xe5, 0x7b, 0xa7, 0x37, 0xe3, 0xc4, 0xac, 0x35, 0x21, 0x17,
    440      0x98, 0xec, 0xb9, 0xae, 0x45, 0x13, 0x24, 0xa4, 0x2c, 0x76, 0xae, 0x7d,
    441      0x17, 0x75, 0x27, 0x8a, 0xaa, 0x4a, 0x48, 0x60}},
    442   { { {98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    443        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    444        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    445        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    446        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    447        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    448        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    449        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    450        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    451        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    452        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    453        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    454        98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
    455        98, 98, 98, 98, 98}, 239},  /* 'b' x 239 times */
    456     {0xcd, 0x93, 0xb8, 0xab, 0x6a, 0x74, 0xbd, 0x34, 0x8c, 0x43, 0x76, 0x0c,
    457      0x2a, 0xd0, 0x6e, 0xd8, 0x76, 0xcf, 0xdf, 0x2a, 0x21, 0x04, 0xfb, 0xf6,
    458      0x16, 0x53, 0x68, 0xf6, 0x10, 0xc3, 0xa1, 0xac}},
    459   { { {99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    460        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    461        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    462        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    463        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    464        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    465        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    466        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    467        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    468        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    469        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    470        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    471        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
    472        99, 99, 99, 99, 99, 99}, 240},  /* 'c' x 240 times */
    473     {0x5f, 0x60, 0xea, 0x44, 0xb6, 0xc6, 0x9e, 0xfe, 0xfc, 0x0e, 0x6a, 0x0a,
    474      0x99, 0x40, 0x1b, 0x61, 0x43, 0x58, 0xba, 0x4a, 0x0a, 0xee, 0x6b, 0x52,
    475      0x10, 0xdb, 0x32, 0xd9, 0x7f, 0x12, 0xba, 0x70}},
    476   { { {48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    477        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    478        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    479        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    480        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    481        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    482        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    483        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    484        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    485        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    486        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    487        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    488        48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
    489        48, 48, 48, 48, 48, 48, 48}, 241}, /* '0' x 241 times */
    490     {0x3c, 0xcb, 0xcf, 0x50, 0x79, 0xd5, 0xb6, 0xf5, 0xbf, 0x25, 0x07, 0xfb,
    491      0x4d, 0x1f, 0xa3, 0x77, 0xc3, 0x6f, 0xe8, 0xe3, 0xc4, 0x4b, 0xf8, 0xcd,
    492      0x90, 0x93, 0xf1, 0x3e, 0x08, 0x09, 0xa7, 0x69}}
    493 };
    494 
    495 static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]);
    496 
    497 
    498 /*
    499  *  Helper functions
    500  */
    501 
    502 /**
    503  * Print bin as hex
    504  *
    505  * @param bin binary data
    506  * @param len number of bytes in bin
    507  * @param hex pointer to len*2+1 bytes buffer
    508  */
    509 static void
    510 bin2hex (const uint8_t *bin,
    511          size_t len,
    512          char *hex)
    513 {
    514   while (len-- > 0)
    515   {
    516     unsigned int b1, b2;
    517     b1 = (*bin >> 4) & 0xf;
    518     *hex++ = (char) ((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0'));
    519     b2 = *bin++ & 0xf;
    520     *hex++ = (char) ((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0'));
    521   }
    522   *hex = 0;
    523 }
    524 
    525 
    526 static int
    527 check_result (const char *test_name,
    528               unsigned int check_num,
    529               const uint8_t calculated[mhd_SHA512_256_DIGEST_SIZE],
    530               const uint8_t expected[mhd_SHA512_256_DIGEST_SIZE])
    531 {
    532   int failed = memcmp (calculated, expected, mhd_SHA512_256_DIGEST_SIZE);
    533   check_num++; /* Print 1-based numbers */
    534   if (failed)
    535   {
    536     char calc_str[mhd_SHA512_256_DIGEST_SIZE * 2 + 1];
    537     char expc_str[mhd_SHA512_256_DIGEST_SIZE * 2 + 1];
    538     bin2hex (calculated, mhd_SHA512_256_DIGEST_SIZE, calc_str);
    539     bin2hex (expected, mhd_SHA512_256_DIGEST_SIZE, expc_str);
    540     fprintf (stderr,
    541              "FAILED: %s check %u: calculated digest %s, expected digest %s.\n",
    542              test_name, check_num, calc_str, expc_str);
    543     fflush (stderr);
    544   }
    545   else if (verbose)
    546   {
    547     char calc_str[mhd_SHA512_256_DIGEST_SIZE * 2 + 1];
    548     bin2hex (calculated, mhd_SHA512_256_DIGEST_SIZE, calc_str);
    549     printf ("PASSED: %s check %u: calculated digest %s matches " \
    550             "expected digest.\n",
    551             test_name, check_num, calc_str);
    552     fflush (stdout);
    553   }
    554   return failed ? 1 : 0;
    555 }
    556 
    557 
    558 /*
    559  *  Tests
    560  */
    561 
    562 /* Calculated SHA-512/256 as one pass for whole data */
    563 static int
    564 test1_str (void)
    565 {
    566   int num_failed = 0;
    567   unsigned int i;
    568   struct mhd_Sha512_256Ctx ctx;
    569 
    570   for (i = 0; i < units1_num; i++)
    571   {
    572     uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    573 
    574     mhd_SHA512_256_init_one_time (&ctx);
    575     mhd_SHA512_256_update (&ctx,
    576                            data_units1[i].str_l.len,
    577                            (const uint8_t *) data_units1[i].str_l.str);
    578     mhd_SHA512_256_finish_reset (&ctx,
    579                                  digest);
    580     num_failed += check_result (__FUNCTION__,
    581                                 i,
    582                                 digest,
    583                                 data_units1[i].digest);
    584     mhd_SHA512_256_deinit (&ctx);
    585   }
    586   return num_failed;
    587 }
    588 
    589 
    590 static int
    591 test1_bin (void)
    592 {
    593   int num_failed = 0;
    594   unsigned int i;
    595   struct mhd_Sha512_256Ctx ctx;
    596 
    597   for (i = 0; i < units2_num; i++)
    598   {
    599     uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    600 
    601     mhd_SHA512_256_init_one_time (&ctx);
    602     mhd_SHA512_256_update (&ctx,
    603                            data_units2[i].bin_l.len,
    604                            data_units2[i].bin_l.bin);
    605     mhd_SHA512_256_finish_reset (&ctx,
    606                                  digest);
    607     num_failed += check_result (__FUNCTION__,
    608                                 i,
    609                                 digest,
    610                                 data_units2[i].digest);
    611     mhd_SHA512_256_deinit (&ctx);
    612   }
    613   return num_failed;
    614 }
    615 
    616 
    617 /* Calculated SHA-512/256 as two iterations for whole data */
    618 static int
    619 test2_str (void)
    620 {
    621   int num_failed = 0;
    622   unsigned int i;
    623   struct mhd_Sha512_256Ctx ctx;
    624 
    625   for (i = 0; i < units1_num; i++)
    626   {
    627     uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    628     size_t part_s = data_units1[i].str_l.len / 4;
    629 
    630     mhd_SHA512_256_init_one_time (&ctx);
    631     mhd_SHA512_256_update (&ctx,
    632                            0,
    633                            (const uint8_t *) "");
    634     mhd_SHA512_256_update (&ctx,
    635                            part_s,
    636                            (const uint8_t *) data_units1[i].str_l.str);
    637     mhd_SHA512_256_update (&ctx,
    638                            0,
    639                            (const uint8_t *) "");
    640     mhd_SHA512_256_update (&ctx,
    641                            data_units1[i].str_l.len - part_s,
    642                            (const uint8_t *) data_units1[i].str_l.str + part_s);
    643     mhd_SHA512_256_update (&ctx,
    644                            0,
    645                            (const uint8_t *) "");
    646     mhd_SHA512_256_finish_reset (&ctx,
    647                                  digest);
    648     num_failed += check_result (__FUNCTION__,
    649                                 i,
    650                                 digest,
    651                                 data_units1[i].digest);
    652     mhd_SHA512_256_deinit (&ctx);
    653   }
    654   return num_failed;
    655 }
    656 
    657 
    658 static int
    659 test2_bin (void)
    660 {
    661   int num_failed = 0;
    662   unsigned int i;
    663   struct mhd_Sha512_256Ctx ctx;
    664 
    665   for (i = 0; i < units2_num; i++)
    666   {
    667     uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    668     size_t part_s = data_units2[i].bin_l.len * 2 / 3;
    669 
    670     mhd_SHA512_256_init_one_time (&ctx);
    671     mhd_SHA512_256_update (&ctx,
    672                            part_s,
    673                            data_units2[i].bin_l.bin);
    674     mhd_SHA512_256_update (&ctx,
    675                            0,
    676                            (const uint8_t *) "");
    677     mhd_SHA512_256_update (&ctx,
    678                            data_units2[i].bin_l.len - part_s,
    679                            data_units2[i].bin_l.bin + part_s);
    680     mhd_SHA512_256_finish_reset (&ctx,
    681                                  digest);
    682     num_failed += check_result (__FUNCTION__,
    683                                 i,
    684                                 digest,
    685                                 data_units2[i].digest);
    686     mhd_SHA512_256_deinit (&ctx);
    687   }
    688   return num_failed;
    689 }
    690 
    691 
    692 /* Use data set number 7 as it has the longest sequence */
    693 #define DATA_POS 6
    694 #define MAX_OFFSET 63
    695 
    696 static int
    697 test_unaligned (void)
    698 {
    699   int num_failed = 0;
    700   unsigned int offset;
    701   uint8_t *buf;
    702   uint8_t *digest_buf;
    703   struct mhd_Sha512_256Ctx ctx;
    704   const struct data_unit2 *const tdata = data_units2 + DATA_POS;
    705 
    706   buf = malloc (tdata->bin_l.len + MAX_OFFSET);
    707   digest_buf = malloc (mhd_SHA512_256_DIGEST_SIZE + MAX_OFFSET);
    708   if ((NULL == buf) || (NULL == digest_buf))
    709     exit (99);
    710 
    711   for (offset = MAX_OFFSET; offset >= 1; --offset)
    712   {
    713     uint8_t *unaligned_digest;
    714     uint8_t *unaligned_buf;
    715 
    716     unaligned_buf = buf + offset;
    717     memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len);
    718     unaligned_digest = digest_buf + MAX_OFFSET - offset;
    719     memset (unaligned_digest, 0, mhd_SHA512_256_DIGEST_SIZE);
    720 
    721     mhd_SHA512_256_init_one_time (&ctx);
    722     mhd_SHA512_256_update (&ctx,
    723                            tdata->bin_l.len,
    724                            unaligned_buf);
    725     mhd_SHA512_256_finish_reset (&ctx,
    726                                  unaligned_digest);
    727     num_failed += check_result (__FUNCTION__,
    728                                 MAX_OFFSET - offset,
    729                                 unaligned_digest,
    730                                 tdata->digest);
    731     mhd_SHA512_256_deinit (&ctx);
    732   }
    733   free (digest_buf);
    734   free (buf);
    735   return num_failed;
    736 }
    737 
    738 
    739 int
    740 main (int argc,
    741       char **argv)
    742 {
    743   struct Test
    744   {
    745     const char *name;
    746     const char *input;
    747     const char *digest;
    748   } tests[] = {
    749     {
    750       "Empty string (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)",
    751       "",
    752       "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"
    753     },
    754     {
    755       "abc",
    756       "616263",
    757       "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"
    758     },
    759     {
    760       "896-bit message abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
    761       "61626364656667686263646566676869636465666768696a6465666768696a6b65666768696a6b6c666768696a6b6c6d6768696a6b6c6d6e68696a6b6c6d6e6f696a6b6c6d6e6f706a6b6c6d6e6f70716b6c6d6e6f7071726c6d6e6f707172736d6e6f70717273746e6f707172737475",
    762       "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"
    763     },
    764     {
    765       "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    766       "6162636462636465636465666465666765666768666768696768696a68696a6b696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
    767       "bde8e1f9f19bb9fd3406c90ec6bc47bd36d8ada9f11880dbc8a22a7078b6a461"
    768     },
    769     {
    770       "One byte 0x00",
    771       "00",
    772       "10baad1713566ac2333467bddb0597dec9066120dd72ac2dcb8394221dcbe43d"
    773     },
    774     {
    775       "The quick brown fox jumps over the lazy dog",
    776       "54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67",
    777       "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d"
    778     },
    779     { NULL, NULL, NULL }
    780   };
    781   struct mhd_Sha512_256Ctx ctx;
    782   uint8_t digest[mhd_SHA512_256_DIGEST_SIZE];
    783   uint8_t data[1024];
    784   size_t data_len;
    785   unsigned int passed = 0;
    786   unsigned int total = 0;
    787   int num_failed;
    788 
    789   if (has_param (argc, argv, "-v") ||
    790       has_param (argc, argv, "--verbose"))
    791     verbose = 1;
    792 
    793 
    794   while (NULL != tests[total].name)
    795   {
    796     const struct Test *t = &tests[total];
    797 
    798     mhd_SHA512_256_init_one_time (&ctx);
    799     if (! mhd_SHA512_256_has_err (&ctx))
    800     {
    801       data_len = hex2bin (t->input,
    802                           data,
    803                           sizeof(data));
    804       if (0 != data_len)
    805         mhd_SHA512_256_update (&ctx,
    806                                data_len,
    807                                data);
    808       mhd_SHA512_256_finish_deinit (&ctx,
    809                                     digest);
    810       if (! mhd_SHA512_256_has_err (&ctx))
    811       {
    812         if (check_digest (digest,
    813                           mhd_SHA512_256_DIGEST_SIZE,
    814                           t->digest,
    815                           t->name))
    816           passed++;
    817       }
    818       else
    819       {
    820         printf ("FAIL: %s - error in finish\n",
    821                 t->name);
    822       }
    823     }
    824     else
    825     {
    826       printf ("FAIL: %s - error in init\n",
    827               t->name);
    828     }
    829     mhd_SHA512_256_deinit (&ctx);
    830     total++;
    831   }
    832 
    833   num_failed = total - passed;
    834 
    835   num_failed += test1_str ();
    836   num_failed += test1_bin ();
    837 
    838   num_failed += test2_str ();
    839   num_failed += test2_bin ();
    840 
    841   num_failed += test_unaligned ();
    842 
    843   if ((0 != num_failed) || verbose)
    844     fprintf (stderr,
    845              "Result: %d tests failed\n",
    846              num_failed);
    847 
    848   return (0 == num_failed) ? 0 : 1;
    849 }