diff --git a/samples/apps/smallbank/fbs/tests/small_bank_serdes_bench.cpp b/samples/apps/smallbank/fbs/tests/small_bank_serdes_bench.cpp index 8a3c29aa12e..17dfff21079 100644 --- a/samples/apps/smallbank/fbs/tests/small_bank_serdes_bench.cpp +++ b/samples/apps/smallbank/fbs/tests/small_bank_serdes_bench.cpp @@ -131,7 +131,7 @@ static void run_mt_benchmark(picobench::state& s, std::vector data) s.start_timer(); for (int i = 0; i < s.iterations(); i++) { - crypto::Sha256Hash rh({{data.data(), data.size()}}); + crypto::Sha256Hash rh({data.data(), data.size()}); tree.append(rh); clobber_memory(); } diff --git a/src/consensus/pbft/pbft_types.h b/src/consensus/pbft/pbft_types.h index 0764ce73876..44c79407706 100644 --- a/src/consensus/pbft/pbft_types.h +++ b/src/consensus/pbft/pbft_types.h @@ -100,7 +100,7 @@ namespace pbft auto pp_view = tx.get_view(pbft_pre_prepares_map); pp_view->put(0, pp); auto sig_view = tx.get_view(signatures); - ccf::Signature sig_value({root}); + ccf::Signature sig_value(root); sig_view->put(0, sig_value); return tx.commit_reserved(); }, @@ -122,7 +122,7 @@ namespace pbft if (p) { auto sig_view = tx.get_view(signatures); - ccf::Signature sig_value({root}); + ccf::Signature sig_value(root); sig_view->put(0, sig_value); auto success = tx.commit(); if (success == kv::CommitSuccess::OK) diff --git a/src/crypto/hash.cpp b/src/crypto/hash.cpp index 21726313a39..e90a6c27aaa 100644 --- a/src/crypto/hash.cpp +++ b/src/crypto/hash.cpp @@ -12,35 +12,37 @@ extern "C" using namespace std; -void crypto::Sha256Hash::mbedtls_sha256( - initializer_list il, uint8_t* h) +void crypto::Sha256Hash::mbedtls_sha256(const CBuffer& data, uint8_t* h) { mbedtls_sha256_context ctx; mbedtls_sha256_starts_ret(&ctx, 0); - for (auto data : il) - { - mbedtls_sha256_update_ret(&ctx, data.p, data.rawSize()); - } + mbedtls_sha256_update_ret(&ctx, data.p, data.rawSize()); mbedtls_sha256_finish_ret(&ctx, h); mbedtls_sha256_free(&ctx); } -void crypto::Sha256Hash::evercrypt_sha256( - initializer_list il, uint8_t* h) +void crypto::Sha256Hash::evercrypt_sha256(const CBuffer& data, uint8_t* h) { EverCrypt_Hash_state_s* state = EverCrypt_Hash_create(Spec_Hash_Definitions_SHA2_256); EverCrypt_Hash_init(state); - for (auto data : il) - { - EverCrypt_Hash_update_multi( - state, const_cast(data.p), data.rawSize()); - EverCrypt_Hash_update_last( - state, const_cast(data.p), data.rawSize()); - } + constexpr auto block_size = 64u; // No way to ask evercrypt for this + + const auto data_begin = const_cast(data.p); + const auto size = data.rawSize(); + const auto full_blocks = size / block_size; + + const auto full_blocks_size = full_blocks * block_size; + const auto full_blocks_end = data_begin + full_blocks_size; + + // update_multi takes complete blocks + EverCrypt_Hash_update_multi(state, data_begin, full_blocks_size); + + // update_last takes start of last chunk (NOT a full block!), and _total size_ + EverCrypt_Hash_update_last(state, full_blocks_end, size); EverCrypt_Hash_finish(state, h); EverCrypt_Hash_free(state); @@ -48,7 +50,7 @@ void crypto::Sha256Hash::evercrypt_sha256( crypto::Sha256Hash::Sha256Hash() : h{0} {} -crypto::Sha256Hash::Sha256Hash(initializer_list il) : h{0} +crypto::Sha256Hash::Sha256Hash(const CBuffer& data) : h{0} { - evercrypt_sha256(il, h.data()); + evercrypt_sha256(data, h.data()); } \ No newline at end of file diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 78857283693..f7478bacdbe 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -16,12 +16,12 @@ namespace crypto public: static constexpr size_t SIZE = 256 / 8; Sha256Hash(); - Sha256Hash(std::initializer_list il); + Sha256Hash(const CBuffer& data); std::array h; - static void mbedtls_sha256(std::initializer_list il, uint8_t* h); - static void evercrypt_sha256(std::initializer_list il, uint8_t* h); + static void mbedtls_sha256(const CBuffer& data, uint8_t* h); + static void evercrypt_sha256(const CBuffer& data, uint8_t* h); friend std::ostream& operator<<( std::ostream& os, const crypto::Sha256Hash& h) diff --git a/src/crypto/test/crypto.cpp b/src/crypto/test/crypto.cpp index dd0a7149fe8..21ac17ce599 100644 --- a/src/crypto/test/crypto.cpp +++ b/src/crypto/test/crypto.cpp @@ -37,10 +37,10 @@ TEST_CASE("ExtendedIv0") TEST_CASE("SHA256 short consistency test") { - std::vector data = {'a', 'b', 'c', '\n'}; + std::vector data = {'a', 'b', 'c', 'd', '\n'}; crypto::Sha256Hash h1, h2; - crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data()); - crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data()); + crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data()); + crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data()); REQUIRE(h1 == h2); } @@ -48,31 +48,49 @@ TEST_CASE("SHA256 %32 consistency test") { std::vector data(32); for (unsigned i = 0; i < 32; i++) - data[i] = i; + std::iota(data.begin(), data.end(), 0); crypto::Sha256Hash h1, h2; - crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data()); - crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data()); + crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data()); + crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data()); REQUIRE(h1 == h2); } TEST_CASE("SHA256 long consistency test") { std::vector data(512); - for (unsigned i = 0; i < 512; i++) - data[i] = i; + std::iota(data.begin(), data.end(), 0); crypto::Sha256Hash h1, h2; - crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data()); - crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data()); + crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data()); + crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data()); REQUIRE(h1 == h2); } +TEST_CASE("Sha256 interesting size consistency test") +{ + std::vector full_data(8192); + std::iota(full_data.begin(), full_data.end(), 0); + + for (size_t size : {0u, 1u, 4u, 10u, 63u, 64u, 65u, 127u, + 128u, 129u, 150u, 200u, 500u, 1000u, 1023u, 1024u, + 1025u, 2000u, 5000u, 8190u, 8191u, 8192u}) + { + INFO(fmt::format("Hashing {} bytes", size)); + auto data = + std::vector(full_data.begin(), full_data.begin() + size); + crypto::Sha256Hash h1, h2; + crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data()); + crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data()); + CHECK(h1 == h2); + } +} + TEST_CASE("EverCrypt SHA256 no-collision check") { std::vector data1 = {'a', 'b', 'c', '\n'}; std::vector data2 = {'a', 'b', 'd', '\n'}; crypto::Sha256Hash h1, h2; - crypto::Sha256Hash::evercrypt_sha256({data1}, h1.h.data()); - crypto::Sha256Hash::evercrypt_sha256({data2}, h2.h.data()); + crypto::Sha256Hash::evercrypt_sha256(data1, h1.h.data()); + crypto::Sha256Hash::evercrypt_sha256(data2, h2.h.data()); REQUIRE(h1 != h2); } @@ -133,4 +151,4 @@ TEST_CASE("Public key encryption") "MCowBQYDK2VwAyEAiaGfOr3cEe+sS67LGoW+tv0AtD+bDYFKeDzxwBIxHhQ=\n" "-----END PUBLIC KEY-----"); } -} \ No newline at end of file +} diff --git a/src/node/history.h b/src/node/history.h index 0a0e5578b4b..1f26ab0ea6f 100644 --- a/src/node/history.h +++ b/src/node/history.h @@ -456,7 +456,7 @@ namespace ccf void append(const uint8_t* replicated, size_t replicated_size) override { - crypto::Sha256Hash rh({{replicated, replicated_size}}); + crypto::Sha256Hash rh({replicated, replicated_size}); log_hash(rh, APPEND); replicated_state_tree.append(rh); } diff --git a/src/node/signatures.h b/src/node/signatures.h index c0c8a280ebc..a147352ae17 100644 --- a/src/node/signatures.h +++ b/src/node/signatures.h @@ -32,7 +32,7 @@ namespace ccf commit(0) {} - Signature(crypto::Sha256Hash root_) : + Signature(const crypto::Sha256Hash& root_) : node(0), index(0), term(0),