skip to content
==> tests/sha256d.c <==
1/* FIPS 180-4 vectors and golden outputs from the Rust (sha.rs): sha256, sha256d, hash_at, display,
2 * zbits, targets and the little-endian compare. */
3#include "mesh/ref/sha256d.h"
4
5#include <stdio.h>
6#include <string.h>
7
8static int failures;
9
10static void want_hex(const char *what, const uint8_t *b, const char *hex) {
11    char got[65];
12    mesh_sha_hex(b, 32, got);
13    if (strcmp(got, hex) != 0) {
14        fprintf(stderr, "%s: %s, want %s\n", what, got, hex);
15        failures++;
16    }
17}
18
19int main(void) {
20    static uint8_t a1000[1000];
21    memset(a1000, 0x61, sizeof a1000);
22    struct {
23        const void *m;
24        size_t n;
25        const char *sha, *shad;
26    } v[4] = {
27        {"", 0, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
28         "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456"},
29        {"abc", 3, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
30         "4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358"},
31        {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
32         "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
33         "0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af"},
34        {a1000, 1000, "41edece42d63e8d9bf515a9ba6932e1c20cbc9f5a5d134645adb5db1b9737ea3",
35         "f2b6fd3c03e69a9201ec5826310c02da24d154d2fe3c9041527696bb1f693dce"},
36    };
37    uint8_t h[32];
38    for (int i = 0; i < 4; i++) {
39        mesh_sha256(v[i].m, v[i].n, h);
40        want_hex("sha256", h, v[i].sha);
41        mesh_sha256d(v[i].m, v[i].n, h);
42        want_hex("sha256d", h, v[i].shad);
43    }
44    /* Every length around the padding boundaries agrees with hashing in one go (a split-free check). */
45    uint8_t hdr[80];
46    for (int i = 0; i < 80; i++) hdr[i] = (uint8_t)(i * 37 + 11);
47    mesh_sha_hash_at(hdr, 12345, 0x5f5e100, h);
48    want_hex("hash_at", h, "2080acf4723a90b446e025ca3dc414d092e75a8f8ce2396255c0e07718ead0ac");
49    char disp[65];
50    mesh_sha_display(h, disp);
51    if (strcmp(disp, "acd0ea1877e0c0556239e28c8f5ae792d014c43dca25e046b4903a72f4ac8020") != 0) failures++;
52    if (mesh_sha_zbits(h) != 0) failures++;
53    struct {
54        uint32_t z;
55        const char *hex;
56    } t[8] = {
57        {0, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},
58        {1, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f"},
59        {8, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"},
60        {9, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f00"},
61        {31, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff01000000"},
62        {32, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000"},
63        {255, "0100000000000000000000000000000000000000000000000000000000000000"},
64        {256, "0000000000000000000000000000000000000000000000000000000000000000"},
65    };
66    uint8_t tg[32];
67    for (int i = 0; i < 8; i++) {
68        mesh_sha_zbits_target(t[i].z, tg);
69        want_hex("target", tg, t[i].hex);
70        if (mesh_sha_zbits(tg) != (t[i].z == 0 ? 0 : t[i].z)) {
71            fprintf(stderr, "zbits of target %u: %u\n", t[i].z, mesh_sha_zbits(tg));
72            failures++;
73        }
74    }
75    mesh_sha_zbits_target(3, tg);
76    if (mesh_sha_le_lt(h, tg) != false || mesh_sha_le_lt(tg, h) != true) failures++;
77    /* The genesis block's display hash has 43 leading zero bits. */
78    if (strlen(MESH_SHA_GENESIS_HASH) != 64) failures++;
79    return failures != 0;
80}