quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

sha3.c (22238B)


      1 /*
      2  *  FIPS-202 compliant SHA3 implementation
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  */
      7 /*
      8  *  The SHA-3 Secure Hash Standard was published by NIST in 2015.
      9  *
     10  *  https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
     11  */
     12 
     13 #include "common.h"
     14 
     15 #if defined(MBEDTLS_SHA3_C)
     16 
     17 /*
     18  * These macros select manually unrolled implementations of parts of the main permutation function.
     19  *
     20  * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
     21  * from manually unrolling at higher optimisation levels.
     22  *
     23  * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
     24  * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
     25  * x86-64.
     26  */
     27 #if !defined(MBEDTLS_SHA3_THETA_UNROLL)
     28     #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
     29 #endif
     30 #if !defined(MBEDTLS_SHA3_CHI_UNROLL)
     31     #if defined(__OPTIMIZE_SIZE__)
     32         #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
     33     #else
     34         #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
     35     #endif
     36 #endif
     37 #if !defined(MBEDTLS_SHA3_PI_UNROLL)
     38     #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
     39 #endif
     40 #if !defined(MBEDTLS_SHA3_RHO_UNROLL)
     41     #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
     42 #endif
     43 
     44 #include "mbedtls/sha3.h"
     45 #include "mbedtls/platform_util.h"
     46 #include "mbedtls/error.h"
     47 
     48 #include <string.h>
     49 
     50 #if defined(MBEDTLS_SELF_TEST)
     51 #include "mbedtls/platform.h"
     52 #endif /* MBEDTLS_SELF_TEST */
     53 
     54 #define XOR_BYTE 0x6
     55 
     56 /* Precomputed masks for the iota transform.
     57  *
     58  * Each round uses a 64-bit mask value. In each mask values, only
     59  * bits whose position is of the form 2^k-1 can be set, thus only
     60  * 7 of 64 bits of the mask need to be known for each mask value.
     61  *
     62  * We use a compressed encoding of the mask where bits 63, 31 and 15
     63  * are moved to bits 4-6. This allows us to make each mask value
     64  * 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with
     65  * perhaps a little variation due to alignment). Decompressing this
     66  * requires a little code, but much less than the savings on the table.
     67  *
     68  * The impact on performance depends on the platform and compiler.
     69  * There's a bit more computation, but less memory bandwidth. A quick
     70  * benchmark on x86_64 shows a 7% speed improvement with GCC and a
     71  * 5% speed penalty with Clang, compared to the naive uint64_t[24] table.
     72  * YMMV.
     73  */
     74 /* Helper macro to set the values of the higher bits in unused low positions */
     75 #define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4)
     76 static const uint8_t iota_r_packed[24] = {
     77     H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00,
     78     H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09,
     79     H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a,
     80     H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03,
     81     H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a,
     82     H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08,
     83 };
     84 #undef H
     85 
     86 static const uint32_t rho[6] = {
     87     0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
     88 };
     89 
     90 static const uint32_t pi[6] = {
     91     0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
     92 };
     93 
     94 #define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
     95 #define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
     96 } while (0)
     97 #define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
     98 #define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
     99 
    100 /* The permutation function.  */
    101 static void keccak_f1600(mbedtls_sha3_context *ctx)
    102 {
    103     uint64_t lane[5];
    104     uint64_t *s = ctx->state;
    105     int i;
    106 
    107     for (int round = 0; round < 24; round++) {
    108         uint64_t t;
    109 
    110         /* Theta */
    111 #if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
    112         for (i = 0; i < 5; i++) {
    113             lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
    114         }
    115         for (i = 0; i < 5; i++) {
    116             t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
    117             s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
    118         }
    119 #else
    120         lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
    121         lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
    122         lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
    123         lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
    124         lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
    125 
    126         t = lane[4] ^ ROTR64(lane[1], 63);
    127         s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
    128 
    129         t = lane[0] ^ ROTR64(lane[2], 63);
    130         s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
    131 
    132         t = lane[1] ^ ROTR64(lane[3], 63);
    133         s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
    134 
    135         t = lane[2] ^ ROTR64(lane[4], 63);
    136         s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
    137 
    138         t = lane[3] ^ ROTR64(lane[0], 63);
    139         s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
    140 #endif
    141 
    142         /* Rho */
    143         for (i = 1; i < 25; i += 4) {
    144             uint32_t r = rho[(i - 1) >> 2];
    145 #if MBEDTLS_SHA3_RHO_UNROLL == 0
    146             for (int j = i; j < i + 4; j++) {
    147                 uint8_t r8 = (uint8_t) (r >> 24);
    148                 r <<= 8;
    149                 s[j] = ROTR64(s[j], r8);
    150             }
    151 #else
    152             s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
    153             s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
    154             s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
    155             s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
    156 #endif
    157         }
    158 
    159         /* Pi */
    160         t = s[1];
    161 #if MBEDTLS_SHA3_PI_UNROLL == 0
    162         for (i = 0; i < 24; i += 4) {
    163             uint32_t p = pi[i >> 2];
    164             for (unsigned j = 0; j < 4; j++) {
    165                 SWAP(s[p & 0xff], t);
    166                 p >>= 8;
    167             }
    168         }
    169 #else
    170         uint32_t p = pi[0];
    171         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    172         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    173         p = pi[1];
    174         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    175         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    176         p = pi[2];
    177         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    178         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    179         p = pi[3];
    180         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    181         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    182         p = pi[4];
    183         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    184         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    185         p = pi[5];
    186         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
    187         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
    188 #endif
    189 
    190         /* Chi */
    191 #if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
    192         for (i = 0; i <= 20; i += 5) {
    193             lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
    194             lane[3] = s[i + 3]; lane[4] = s[i + 4];
    195             s[i + 0] ^= (~lane[1]) & lane[2];
    196             s[i + 1] ^= (~lane[2]) & lane[3];
    197             s[i + 2] ^= (~lane[3]) & lane[4];
    198             s[i + 3] ^= (~lane[4]) & lane[0];
    199             s[i + 4] ^= (~lane[0]) & lane[1];
    200         }
    201 #else
    202         lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
    203         s[0] ^= (~lane[1]) & lane[2];
    204         s[1] ^= (~lane[2]) & lane[3];
    205         s[2] ^= (~lane[3]) & lane[4];
    206         s[3] ^= (~lane[4]) & lane[0];
    207         s[4] ^= (~lane[0]) & lane[1];
    208 
    209         lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
    210         s[5] ^= (~lane[1]) & lane[2];
    211         s[6] ^= (~lane[2]) & lane[3];
    212         s[7] ^= (~lane[3]) & lane[4];
    213         s[8] ^= (~lane[4]) & lane[0];
    214         s[9] ^= (~lane[0]) & lane[1];
    215 
    216         lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
    217         s[10] ^= (~lane[1]) & lane[2];
    218         s[11] ^= (~lane[2]) & lane[3];
    219         s[12] ^= (~lane[3]) & lane[4];
    220         s[13] ^= (~lane[4]) & lane[0];
    221         s[14] ^= (~lane[0]) & lane[1];
    222 
    223         lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
    224         s[15] ^= (~lane[1]) & lane[2];
    225         s[16] ^= (~lane[2]) & lane[3];
    226         s[17] ^= (~lane[3]) & lane[4];
    227         s[18] ^= (~lane[4]) & lane[0];
    228         s[19] ^= (~lane[0]) & lane[1];
    229 
    230         lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
    231         s[20] ^= (~lane[1]) & lane[2];
    232         s[21] ^= (~lane[2]) & lane[3];
    233         s[22] ^= (~lane[3]) & lane[4];
    234         s[23] ^= (~lane[4]) & lane[0];
    235         s[24] ^= (~lane[0]) & lane[1];
    236 #endif
    237 
    238         /* Iota */
    239         /* Decompress the round masks (see definition of rc) */
    240         s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
    241                  (iota_r_packed[round] & 0x20ull) << 26 |
    242                  (iota_r_packed[round] & 0x10ull) << 11 |
    243                  (iota_r_packed[round] & 0x8f));
    244     }
    245 }
    246 
    247 void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
    248 {
    249     memset(ctx, 0, sizeof(mbedtls_sha3_context));
    250 }
    251 
    252 void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
    253 {
    254     if (ctx == NULL) {
    255         return;
    256     }
    257 
    258     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
    259 }
    260 
    261 void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
    262                         const mbedtls_sha3_context *src)
    263 {
    264     *dst = *src;
    265 }
    266 
    267 /*
    268  * SHA-3 context setup
    269  */
    270 int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
    271 {
    272     switch (id) {
    273         case MBEDTLS_SHA3_224:
    274             ctx->olen = 224 / 8;
    275             ctx->max_block_size = 1152 / 8;
    276             break;
    277         case MBEDTLS_SHA3_256:
    278             ctx->olen = 256 / 8;
    279             ctx->max_block_size = 1088 / 8;
    280             break;
    281         case MBEDTLS_SHA3_384:
    282             ctx->olen = 384 / 8;
    283             ctx->max_block_size = 832 / 8;
    284             break;
    285         case MBEDTLS_SHA3_512:
    286             ctx->olen = 512 / 8;
    287             ctx->max_block_size = 576 / 8;
    288             break;
    289         default:
    290             return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
    291     }
    292 
    293     memset(ctx->state, 0, sizeof(ctx->state));
    294     ctx->index = 0;
    295 
    296     return 0;
    297 }
    298 
    299 /*
    300  * SHA-3 process buffer
    301  */
    302 int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
    303                         const uint8_t *input,
    304                         size_t ilen)
    305 {
    306     if (ilen >= 8) {
    307         // 8-byte align index
    308         int align_bytes = 8 - (ctx->index % 8);
    309         if (align_bytes) {
    310             for (; align_bytes > 0; align_bytes--) {
    311                 ABSORB(ctx, ctx->index, *input++);
    312                 ilen--;
    313                 ctx->index++;
    314             }
    315             if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
    316                 keccak_f1600(ctx);
    317             }
    318         }
    319 
    320         // process input in 8-byte chunks
    321         while (ilen >= 8) {
    322             ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
    323             input += 8;
    324             ilen -= 8;
    325             if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
    326                 keccak_f1600(ctx);
    327             }
    328         }
    329     }
    330 
    331     // handle remaining bytes
    332     while (ilen-- > 0) {
    333         ABSORB(ctx, ctx->index, *input++);
    334         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
    335             keccak_f1600(ctx);
    336         }
    337     }
    338 
    339     return 0;
    340 }
    341 
    342 int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
    343                         uint8_t *output, size_t olen)
    344 {
    345     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    346 
    347     /* Catch SHA-3 families, with fixed output length */
    348     if (ctx->olen > 0) {
    349         if (ctx->olen > olen) {
    350             ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
    351             goto exit;
    352         }
    353         olen = ctx->olen;
    354     }
    355 
    356     ABSORB(ctx, ctx->index, XOR_BYTE);
    357     ABSORB(ctx, ctx->max_block_size - 1, 0x80);
    358     keccak_f1600(ctx);
    359     ctx->index = 0;
    360 
    361     while (olen-- > 0) {
    362         *output++ = SQUEEZE(ctx, ctx->index);
    363 
    364         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
    365             keccak_f1600(ctx);
    366         }
    367     }
    368 
    369     ret = 0;
    370 
    371 exit:
    372     mbedtls_sha3_free(ctx);
    373     return ret;
    374 }
    375 
    376 /*
    377  * output = SHA-3( input buffer )
    378  */
    379 int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
    380                  size_t ilen, uint8_t *output, size_t olen)
    381 {
    382     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    383     mbedtls_sha3_context ctx;
    384 
    385     mbedtls_sha3_init(&ctx);
    386 
    387     /* Sanity checks are performed in every mbedtls_sha3_xxx() */
    388     if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
    389         goto exit;
    390     }
    391 
    392     if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
    393         goto exit;
    394     }
    395 
    396     if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
    397         goto exit;
    398     }
    399 
    400 exit:
    401     mbedtls_sha3_free(&ctx);
    402 
    403     return ret;
    404 }
    405 
    406 /**************** Self-tests ****************/
    407 
    408 #if defined(MBEDTLS_SELF_TEST)
    409 
    410 static const unsigned char test_data[2][4] =
    411 {
    412     "",
    413     "abc",
    414 };
    415 
    416 static const size_t test_data_len[2] =
    417 {
    418     0, /* "" */
    419     3  /* "abc" */
    420 };
    421 
    422 static const unsigned char test_hash_sha3_224[2][28] =
    423 {
    424     { /* "" */
    425         0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
    426         0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
    427         0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
    428         0x5B, 0x5A, 0x6B, 0xC7
    429     },
    430     { /* "abc" */
    431         0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
    432         0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
    433         0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
    434         0x73, 0xB4, 0x6F, 0xDF
    435     }
    436 };
    437 
    438 static const unsigned char test_hash_sha3_256[2][32] =
    439 {
    440     { /* "" */
    441         0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
    442         0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
    443         0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
    444         0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
    445     },
    446     { /* "abc" */
    447         0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
    448         0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
    449         0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
    450         0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
    451     }
    452 };
    453 
    454 static const unsigned char test_hash_sha3_384[2][48] =
    455 {
    456     { /* "" */
    457         0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
    458         0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
    459         0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
    460         0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
    461         0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
    462         0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
    463     },
    464     { /* "abc" */
    465         0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
    466         0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
    467         0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
    468         0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
    469         0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
    470         0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
    471     }
    472 };
    473 
    474 static const unsigned char test_hash_sha3_512[2][64] =
    475 {
    476     { /* "" */
    477         0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
    478         0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
    479         0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
    480         0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
    481         0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
    482         0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
    483         0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
    484         0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
    485     },
    486     { /* "abc" */
    487         0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
    488         0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
    489         0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
    490         0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
    491         0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
    492         0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
    493         0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
    494         0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
    495     }
    496 };
    497 
    498 static const unsigned char long_kat_hash_sha3_224[28] =
    499 {
    500     0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
    501     0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
    502     0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
    503     0xA7, 0xFD, 0x65, 0x3C
    504 };
    505 
    506 static const unsigned char long_kat_hash_sha3_256[32] =
    507 {
    508     0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
    509     0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
    510     0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
    511     0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
    512 };
    513 
    514 static const unsigned char long_kat_hash_sha3_384[48] =
    515 {
    516     0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
    517     0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
    518     0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
    519     0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
    520     0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
    521     0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
    522 };
    523 
    524 static const unsigned char long_kat_hash_sha3_512[64] =
    525 {
    526     0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
    527     0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
    528     0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
    529     0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
    530     0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
    531     0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
    532     0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
    533     0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
    534 };
    535 
    536 static int mbedtls_sha3_kat_test(int verbose,
    537                                  const char *type_name,
    538                                  mbedtls_sha3_id id,
    539                                  int test_num)
    540 {
    541     uint8_t hash[64];
    542     int result;
    543 
    544     result = mbedtls_sha3(id,
    545                           test_data[test_num], test_data_len[test_num],
    546                           hash, sizeof(hash));
    547     if (result != 0) {
    548         if (verbose != 0) {
    549             mbedtls_printf("  %s test %d error code: %d\n",
    550                            type_name, test_num, result);
    551         }
    552 
    553         return result;
    554     }
    555 
    556     switch (id) {
    557         case MBEDTLS_SHA3_224:
    558             result = memcmp(hash, test_hash_sha3_224[test_num], 28);
    559             break;
    560         case MBEDTLS_SHA3_256:
    561             result = memcmp(hash, test_hash_sha3_256[test_num], 32);
    562             break;
    563         case MBEDTLS_SHA3_384:
    564             result = memcmp(hash, test_hash_sha3_384[test_num], 48);
    565             break;
    566         case MBEDTLS_SHA3_512:
    567             result = memcmp(hash, test_hash_sha3_512[test_num], 64);
    568             break;
    569         default:
    570             break;
    571     }
    572 
    573     if (0 != result) {
    574         if (verbose != 0) {
    575             mbedtls_printf("  %s test %d failed\n", type_name, test_num);
    576         }
    577 
    578         return -1;
    579     }
    580 
    581     if (verbose != 0) {
    582         mbedtls_printf("  %s test %d passed\n", type_name, test_num);
    583     }
    584 
    585     return 0;
    586 }
    587 
    588 static int mbedtls_sha3_long_kat_test(int verbose,
    589                                       const char *type_name,
    590                                       mbedtls_sha3_id id)
    591 {
    592     mbedtls_sha3_context ctx;
    593     unsigned char buffer[1000];
    594     unsigned char hash[64];
    595     int result = 0;
    596 
    597     memset(buffer, 'a', 1000);
    598 
    599     if (verbose != 0) {
    600         mbedtls_printf("  %s long KAT test ", type_name);
    601     }
    602 
    603     mbedtls_sha3_init(&ctx);
    604 
    605     result = mbedtls_sha3_starts(&ctx, id);
    606     if (result != 0) {
    607         if (verbose != 0) {
    608             mbedtls_printf("setup failed\n ");
    609         }
    610     }
    611 
    612     /* Process 1,000,000 (one million) 'a' characters */
    613     for (int i = 0; i < 1000; i++) {
    614         result = mbedtls_sha3_update(&ctx, buffer, 1000);
    615         if (result != 0) {
    616             if (verbose != 0) {
    617                 mbedtls_printf("update error code: %i\n", result);
    618             }
    619 
    620             goto cleanup;
    621         }
    622     }
    623 
    624     result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
    625     if (result != 0) {
    626         if (verbose != 0) {
    627             mbedtls_printf("finish error code: %d\n", result);
    628         }
    629 
    630         goto cleanup;
    631     }
    632 
    633     switch (id) {
    634         case MBEDTLS_SHA3_224:
    635             result = memcmp(hash, long_kat_hash_sha3_224, 28);
    636             break;
    637         case MBEDTLS_SHA3_256:
    638             result = memcmp(hash, long_kat_hash_sha3_256, 32);
    639             break;
    640         case MBEDTLS_SHA3_384:
    641             result = memcmp(hash, long_kat_hash_sha3_384, 48);
    642             break;
    643         case MBEDTLS_SHA3_512:
    644             result = memcmp(hash, long_kat_hash_sha3_512, 64);
    645             break;
    646         default:
    647             break;
    648     }
    649 
    650     if (result != 0) {
    651         if (verbose != 0) {
    652             mbedtls_printf("failed\n");
    653         }
    654     }
    655 
    656     if (verbose != 0) {
    657         mbedtls_printf("passed\n");
    658     }
    659 
    660 cleanup:
    661     mbedtls_sha3_free(&ctx);
    662     return result;
    663 }
    664 
    665 int mbedtls_sha3_self_test(int verbose)
    666 {
    667     int i;
    668 
    669     /* SHA-3 Known Answer Tests (KAT) */
    670     for (i = 0; i < 2; i++) {
    671         if (0 != mbedtls_sha3_kat_test(verbose,
    672                                        "SHA3-224", MBEDTLS_SHA3_224, i)) {
    673             return 1;
    674         }
    675 
    676         if (0 != mbedtls_sha3_kat_test(verbose,
    677                                        "SHA3-256", MBEDTLS_SHA3_256, i)) {
    678             return 1;
    679         }
    680 
    681         if (0 != mbedtls_sha3_kat_test(verbose,
    682                                        "SHA3-384", MBEDTLS_SHA3_384, i)) {
    683             return 1;
    684         }
    685 
    686         if (0 != mbedtls_sha3_kat_test(verbose,
    687                                        "SHA3-512", MBEDTLS_SHA3_512, i)) {
    688             return 1;
    689         }
    690     }
    691 
    692     /* SHA-3 long KAT tests */
    693     if (0 != mbedtls_sha3_long_kat_test(verbose,
    694                                         "SHA3-224", MBEDTLS_SHA3_224)) {
    695         return 1;
    696     }
    697 
    698     if (0 != mbedtls_sha3_long_kat_test(verbose,
    699                                         "SHA3-256", MBEDTLS_SHA3_256)) {
    700         return 1;
    701     }
    702 
    703     if (0 != mbedtls_sha3_long_kat_test(verbose,
    704                                         "SHA3-384", MBEDTLS_SHA3_384)) {
    705         return 1;
    706     }
    707 
    708     if (0 != mbedtls_sha3_long_kat_test(verbose,
    709                                         "SHA3-512", MBEDTLS_SHA3_512)) {
    710         return 1;
    711     }
    712 
    713     if (verbose != 0) {
    714         mbedtls_printf("\n");
    715     }
    716 
    717     return 0;
    718 }
    719 #endif /* MBEDTLS_SELF_TEST */
    720 
    721 #endif /* MBEDTLS_SHA3_C */