diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/key.cpp | 80 | ||||
-rw-r--r-- | src/test/fuzz/p2p_transport_serialization.cpp | 2 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 13 | ||||
-rw-r--r-- | src/test/key_tests.cpp | 20 | ||||
-rw-r--r-- | src/test/serialize_tests.cpp | 23 | ||||
-rw-r--r-- | src/test/settings_tests.cpp | 2 |
6 files changed, 128 insertions, 12 deletions
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp index 3eab2e20c0..25ea547435 100644 --- a/src/test/fuzz/key.cpp +++ b/src/test/fuzz/key.cpp @@ -15,13 +15,17 @@ #include <script/signingprovider.h> #include <script/standard.h> #include <streams.h> +#include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <util/chaintype.h> #include <util/strencodings.h> +#include <array> #include <cassert> +#include <cstddef> #include <cstdint> #include <numeric> +#include <optional> #include <string> #include <vector> @@ -303,3 +307,79 @@ FUZZ_TARGET_INIT(key, initialize_key) } } } + +FUZZ_TARGET_INIT(ellswift_roundtrip, initialize_key) +{ + FuzzedDataProvider fdp{buffer.data(), buffer.size()}; + + auto key_bytes = fdp.ConsumeBytes<uint8_t>(32); + key_bytes.resize(32); + CKey key; + key.Set(key_bytes.begin(), key_bytes.end(), true); + if (!key.IsValid()) return; + + auto ent32 = fdp.ConsumeBytes<std::byte>(32); + ent32.resize(32); + + auto encoded_ellswift = key.EllSwiftCreate(ent32); + auto decoded_pubkey = encoded_ellswift.Decode(); + + assert(key.VerifyPubKey(decoded_pubkey)); +} + +FUZZ_TARGET_INIT(bip324_ecdh, initialize_key) +{ + FuzzedDataProvider fdp{buffer.data(), buffer.size()}; + + // We generate private key, k1. + auto rnd32 = fdp.ConsumeBytes<uint8_t>(32); + rnd32.resize(32); + CKey k1; + k1.Set(rnd32.begin(), rnd32.end(), true); + if (!k1.IsValid()) return; + + // They generate private key, k2. + rnd32 = fdp.ConsumeBytes<uint8_t>(32); + rnd32.resize(32); + CKey k2; + k2.Set(rnd32.begin(), rnd32.end(), true); + if (!k2.IsValid()) return; + + // We construct an ellswift encoding for our key, k1_ellswift. + auto ent32_1 = fdp.ConsumeBytes<std::byte>(32); + ent32_1.resize(32); + auto k1_ellswift = k1.EllSwiftCreate(ent32_1); + + // They construct an ellswift encoding for their key, k2_ellswift. + auto ent32_2 = fdp.ConsumeBytes<std::byte>(32); + ent32_2.resize(32); + auto k2_ellswift = k2.EllSwiftCreate(ent32_2); + + // They construct another (possibly distinct) ellswift encoding for their key, k2_ellswift_bad. + auto ent32_2_bad = fdp.ConsumeBytes<std::byte>(32); + ent32_2_bad.resize(32); + auto k2_ellswift_bad = k2.EllSwiftCreate(ent32_2_bad); + assert((ent32_2_bad == ent32_2) == (k2_ellswift_bad == k2_ellswift)); + + // Determine who is who. + bool initiating = fdp.ConsumeBool(); + + // We compute our shared secret using our key and their public key. + auto ecdh_secret_1 = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, initiating); + // They compute their shared secret using their key and our public key. + auto ecdh_secret_2 = k2.ComputeBIP324ECDHSecret(k1_ellswift, k2_ellswift, !initiating); + // Those must match, as everyone is behaving correctly. + assert(ecdh_secret_1 == ecdh_secret_2); + + if (k1_ellswift != k2_ellswift) { + // Unless the two keys are exactly identical, acting as the wrong party breaks things. + auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift, k1_ellswift, !initiating); + assert(ecdh_secret_bad != ecdh_secret_1); + } + + if (k2_ellswift_bad != k2_ellswift) { + // Unless both encodings created by them are identical, using the second one breaks things. + auto ecdh_secret_bad = k1.ComputeBIP324ECDHSecret(k2_ellswift_bad, k1_ellswift, initiating); + assert(ecdh_secret_bad != ecdh_secret_1); + } +} diff --git a/src/test/fuzz/p2p_transport_serialization.cpp b/src/test/fuzz/p2p_transport_serialization.cpp index ec3cdbff5a..a6fe3037e6 100644 --- a/src/test/fuzz/p2p_transport_serialization.cpp +++ b/src/test/fuzz/p2p_transport_serialization.cpp @@ -77,7 +77,7 @@ FUZZ_TARGET_INIT(p2p_transport_serialization, initialize_p2p_transport_serializa assert(msg.m_time == m_time); std::vector<unsigned char> header; - auto msg2 = CNetMsgMaker{msg.m_recv.GetVersion()}.Make(msg.m_type, MakeUCharSpan(msg.m_recv)); + auto msg2 = CNetMsgMaker{msg.m_recv.GetVersion()}.Make(msg.m_type, Span{msg.m_recv}); serializer.prepareForTransport(msg2, header); } } diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 7035c53d13..c561675d1a 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -101,7 +101,14 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) (void)AreInputsStandard(tx, coins_view_cache); (void)IsWitnessStandard(tx, coins_view_cache); - UniValue u(UniValue::VOBJ); - TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u); - TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u); + if (tx.GetTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding + { + UniValue u{UniValue::VOBJ}; + TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u); + } + { + UniValue u{UniValue::VOBJ}; + TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u); + } + } } diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 8f11bf5db2..86a8d17a76 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -344,4 +344,24 @@ BOOST_AUTO_TEST_CASE(bip340_test_vectors) } } +BOOST_AUTO_TEST_CASE(key_ellswift) +{ + for (const auto& secret : {strSecret1, strSecret2, strSecret1C, strSecret2C}) { + CKey key = DecodeSecret(secret); + BOOST_CHECK(key.IsValid()); + + uint256 ent32 = InsecureRand256(); + auto ellswift = key.EllSwiftCreate(AsBytes(Span{ent32})); + + CPubKey decoded_pubkey = ellswift.Decode(); + if (!key.IsCompressed()) { + // The decoding constructor returns a compressed pubkey. If the + // original was uncompressed, we must decompress the decoded one + // to compare. + decoded_pubkey.Decompress(); + } + BOOST_CHECK(key.GetPubKey() == decoded_pubkey); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 09f77d2b61..b445ff8ffc 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -186,32 +186,32 @@ BOOST_AUTO_TEST_CASE(noncanonical) std::vector<char>::size_type n; // zero encoded with three bytes: - ss.write(MakeByteSpan("\xfd\x00\x00").first(3)); + ss << Span{"\xfd\x00\x00"}.first(3); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xfc encoded with three bytes: - ss.write(MakeByteSpan("\xfd\xfc\x00").first(3)); + ss << Span{"\xfd\xfc\x00"}.first(3); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xfd encoded with three bytes is OK: - ss.write(MakeByteSpan("\xfd\xfd\x00").first(3)); + ss << Span{"\xfd\xfd\x00"}.first(3); n = ReadCompactSize(ss); BOOST_CHECK(n == 0xfd); // zero encoded with five bytes: - ss.write(MakeByteSpan("\xfe\x00\x00\x00\x00").first(5)); + ss << Span{"\xfe\x00\x00\x00\x00"}.first(5); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0xffff encoded with five bytes: - ss.write(MakeByteSpan("\xfe\xff\xff\x00\x00").first(5)); + ss << Span{"\xfe\xff\xff\x00\x00"}.first(5); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // zero encoded with nine bytes: - ss.write(MakeByteSpan("\xff\x00\x00\x00\x00\x00\x00\x00\x00").first(9)); + ss << Span{"\xff\x00\x00\x00\x00\x00\x00\x00\x00"}.first(9); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); // 0x01ffffff encoded with nine bytes: - ss.write(MakeByteSpan("\xff\xff\xff\xff\x01\x00\x00\x00\x00").first(9)); + ss << Span{"\xff\xff\xff\xff\x01\x00\x00\x00\x00"}.first(9); BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); } @@ -241,6 +241,15 @@ BOOST_AUTO_TEST_CASE(class_methods) ss2 << intval << boolval << stringval << charstrval << txval; ss2 >> methodtest3; BOOST_CHECK(methodtest3 == methodtest4); + { + DataStream ds; + const std::string in{"ab"}; + ds << Span{in}; + std::array<std::byte, 2> out; + ds >> Span{out}; + BOOST_CHECK_EQUAL(out.at(0), std::byte{'a'}); + BOOST_CHECK_EQUAL(out.at(1), std::byte{'b'}); + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index c24921bf9b..eb11df0497 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -35,7 +35,7 @@ inline std::ostream& operator<<(std::ostream& os, const common::SettingsValue& v inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, common::SettingsValue>& kv) { common::SettingsValue out(common::SettingsValue::VOBJ); - out.__pushKV(kv.first, kv.second); + out.pushKVEnd(kv.first, kv.second); os << out.write(); return os; } |