#include "shim/trace/sha256.h" #include #include #include "check.h" using shim::Sha256; static std::string hex_of(const std::string& s) { char h[65]; Sha256::digest_hex(s.data(), s.size(), h); return h; } int main() { // FIPS 180-2 vectors + the harness's empty-string value (mkfixture test_float_and_bigint_forms). CHECK_STR(hex_of(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); CHECK_STR(hex_of("abc"), "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); CHECK_STR(hex_of("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); CHECK_STR(hex_of(std::string(1000000, 'a')), "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); CHECK_STR(hex_of(std::string("\x00\xff", 2)), "06eb7d6a69ee19e5fbdf749018d3d2abfa04bcbd1365db312eb86dc7169389b8"); // Incremental updates across block boundaries equal the one-shot digest. const std::string big(1000000, 'a'); Sha256 s; std::size_t pos = 0; const std::size_t steps[] = {1, 63, 64, 65, 1000, 4096, 55, 56, 57, 100000}; while (pos < big.size()) { for (std::size_t st : steps) { const std::size_t n = (pos + st > big.size()) ? big.size() - pos : st; s.update(big.data() + pos, n); pos += n; if (pos >= big.size()) break; } } std::uint8_t d[32]; s.finish(d); char h[65]; Sha256::to_hex(d, h); CHECK_STR(std::string(h), "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); // Exactly 55 / 56 / 64 bytes (padding edge cases) agree with themselves chunked. for (std::size_t n : {55u, 56u, 63u, 64u, 65u, 119u, 120u, 128u}) { const std::string m(n, 'x'); Sha256 a; a.update(m.data(), 20); a.update(m.data() + 20, n - 20); std::uint8_t da[32]; a.finish(da); std::uint8_t db[32]; Sha256::digest(m.data(), n, db); CHECK(std::memcmp(da, db, 32) == 0); } return tracetest::finish("shim_trace_sha256"); }