/
githubmirror
/
bitcoin
Обзор
Документация
Войти
/
githubmirror
/
bitcoin
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/test/fuzz/integer.cpp
295 строк
10 KB
Pieter Wuille
test: add SipHash-1-3-UJ coverage
18 июл 2026, 08:55
Не верифицирован
18 июл 2026, 08:55
3aea854
Код
Авторство
О чём код?
// Copyright (c) 2019-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <arith_uint256.h> #include <common/args.h> #include <common/system.h> #include <compressor.h> #include <consensus/amount.h> #include <consensus/merkle.h> #include <core_io.h> #include <crypto/common.h> #include <crypto/siphash.h> #include <key_io.h> #include <memusage.h> #include <netbase.h> #include <policy/policy.h> #include <policy/settings.h> #include <pow.h> #include <protocol.h> #include <pubkey.h> #include <script/script.h> #include <serialize.h> #include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> #include <test/fuzz/util.h> #include <uint256.h> #include <univalue.h> #include <util/chaintype.h> #include <util/check.h> #include <util/moneystr.h> #include <util/overflow.h> #include <util/strencodings.h> #include <util/string.h> #include <cassert> #include <chrono> #include <limits> #include <set> #include <vector> using util::ToString; void initialize_integer() { SelectParams(ChainType::REGTEST); } FUZZ_TARGET(integer, .init = initialize_integer) { if (buffer.size() < sizeof(uint256) + sizeof(uint160)) { return; } FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const uint256 u256(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256))); const uint160 u160(fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint160))); const uint64_t u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>(); const int64_t i64 = fuzzed_data_provider.ConsumeIntegral<int64_t>(); const uint32_t u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); const int32_t i32 = fuzzed_data_provider.ConsumeIntegral<int32_t>(); const uint16_t u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>(); const int16_t i16 = fuzzed_data_provider.ConsumeIntegral<int16_t>(); const uint8_t u8 = fuzzed_data_provider.ConsumeIntegral<uint8_t>(); const int8_t i8 = fuzzed_data_provider.ConsumeIntegral<int8_t>(); // We cannot assume a specific value of std::is_signed_v<char>: // ConsumeIntegral<char>() instead of casting from {u,}int8_t. const char ch = fuzzed_data_provider.ConsumeIntegral<char>(); const bool b = fuzzed_data_provider.ConsumeBool(); const uint64_t u64_2{fuzzed_data_provider.ConsumeIntegral<uint64_t>()}; const Consensus::Params& consensus_params = Params().GetConsensus(); (void)CheckProofOfWorkImpl(u256, u32, consensus_params); if (u64 <= MAX_MONEY) { const uint64_t compressed_money_amount = CompressAmount(u64); assert(u64 == DecompressAmount(compressed_money_amount)); static const uint64_t compressed_money_amount_max = CompressAmount(MAX_MONEY - 1); assert(compressed_money_amount <= compressed_money_amount_max); } else { (void)CompressAmount(u64); } constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"}; constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}; std::vector v256{u256, u256_min, u256_max}; (void)ComputeMerkleRoot(std::move(v256)); (void)DecompressAmount(u64); { if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) { assert(parsed.value() == i64); } } (void)GetSizeOfCompactSize(u64); (void)GetSpecialScriptSize(u32); if (!MultiplicationOverflow(i64, static_cast<int64_t>(u32)) && !AdditionOverflow(i64, static_cast<int64_t>(4)) && !AdditionOverflow(i64 * u32, static_cast<int64_t>(4))) { (void)GetVirtualTransactionSize(i64, i64, u32); } (void)HexDigit(ch); (void)MoneyRange(i64); (void)ToString(i64); (void)IsDigit(ch); (void)IsSpace(ch); (void)IsSwitchChar(ch); (void)memusage::DynamicUsage(ch); (void)memusage::DynamicUsage(i16); (void)memusage::DynamicUsage(i32); (void)memusage::DynamicUsage(i64); (void)memusage::DynamicUsage(i8); (void)memusage::DynamicUsage(u16); (void)memusage::DynamicUsage(u32); (void)memusage::DynamicUsage(u64); (void)memusage::DynamicUsage(u8); const unsigned char uch = static_cast<unsigned char>(u8); (void)memusage::DynamicUsage(uch); { const std::set<int64_t> i64s{i64, static_cast<int64_t>(u64)}; const size_t dynamic_usage = memusage::DynamicUsage(i64s); const size_t incremental_dynamic_usage = memusage::IncrementalDynamicUsage(i64s); assert(dynamic_usage == incremental_dynamic_usage * i64s.size()); } (void)MillisToTimeval(i64); (void)SighashToStr(uch); { CSipHasher hasher{u64, u64_2}; const PresaltedSipHasher presalted_hasher{u64, u64_2}; hasher.Write(u256); assert(presalted_hasher(u256) == hasher.Finalize()); uint8_t extra[4]{}; WriteLE32(extra, u32); hasher.Write(extra); assert(presalted_hasher(u256, u32) == hasher.Finalize()); } { const uint64_t data0{u160.GetUint64(0)}, data1{u160.GetUint64(1)}; SipHasher13UJ hasher{u64, u64_2}; const SipHasher13UJ fixed_hasher{u64, u64_2}; hasher.WriteJumbo(u256); assert(fixed_hasher.Hash(u256) == hasher.Finalize()); hasher.Write(data0); assert(fixed_hasher.Hash(u256, data0) == hasher.Finalize()); SipHasher13UJ reference{u64, u64_2}; SipHasher13UJ mixed{u64, u64_2}; reference.WriteJumbo(u256); mixed.WriteJumbo(u256); const auto write_normal{[](SipHasher13UJ& hasher, uint64_t data, bool as_jumbo) { if (as_jumbo) { uint256 data256{}; WriteLE64(data256.data(), data); hasher.WriteJumbo(data256); } else { hasher.Write(data); } }}; reference.Write(data0).Write(data1); write_normal(mixed, data0, b); write_normal(mixed, data1, u8 & 1); assert(mixed.Finalize() == reference.Finalize()); reference.WriteJumbo(u256).Write(data0); assert(mixed.Hash(u256, data0) == reference.Finalize()); } (void)ToLower(ch); (void)ToUpper(ch); { if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) { assert(parsed.value() == i64); } } if (i32 >= 0 && i32 <= 16) { assert(i32 == CScript::DecodeOP_N(CScript::EncodeOP_N(i32))); } const std::chrono::seconds seconds{i64}; assert(count_seconds(seconds) == i64); const CScriptNum script_num{i64}; (void)script_num.getint(); (void)script_num.getvch(); const arith_uint256 au256 = UintToArith256(u256); assert(ArithToUint256(au256) == u256); assert(uint256::FromHex(au256.GetHex()).value() == u256); (void)au256.bits(); (void)au256.GetCompact(/* fNegative= */ false); (void)au256.GetCompact(/* fNegative= */ true); (void)au256.getdouble(); (void)au256.GetHex(); (void)au256.GetLow64(); (void)au256.size(); (void)au256.ToString(); const CKeyID key_id{u160}; const CScriptID script_id{u160}; { DataStream stream{}; uint256 deserialized_u256; stream << u256; stream >> deserialized_u256; assert(u256 == deserialized_u256 && stream.empty()); uint160 deserialized_u160; stream << u160; stream >> deserialized_u160; assert(u160 == deserialized_u160 && stream.empty()); uint64_t deserialized_u64; stream << u64; stream >> deserialized_u64; assert(u64 == deserialized_u64 && stream.empty()); int64_t deserialized_i64; stream << i64; stream >> deserialized_i64; assert(i64 == deserialized_i64 && stream.empty()); uint32_t deserialized_u32; stream << u32; stream >> deserialized_u32; assert(u32 == deserialized_u32 && stream.empty()); int32_t deserialized_i32; stream << i32; stream >> deserialized_i32; assert(i32 == deserialized_i32 && stream.empty()); uint16_t deserialized_u16; stream << u16; stream >> deserialized_u16; assert(u16 == deserialized_u16 && stream.empty()); int16_t deserialized_i16; stream << i16; stream >> deserialized_i16; assert(i16 == deserialized_i16 && stream.empty()); uint8_t deserialized_u8; stream << u8; stream >> deserialized_u8; assert(u8 == deserialized_u8 && stream.empty()); int8_t deserialized_i8; stream << i8; stream >> deserialized_i8; assert(i8 == deserialized_i8 && stream.empty()); bool deserialized_b; stream << b; stream >> deserialized_b; assert(b == deserialized_b && stream.empty()); } { const ServiceFlags service_flags = (ServiceFlags)u64; (void)MayHaveUsefulAddressDB(service_flags); } { DataStream stream{}; ser_writedata64(stream, u64); const uint64_t deserialized_u64 = ser_readdata64(stream); assert(u64 == deserialized_u64 && stream.empty()); ser_writedata32(stream, u32); const uint32_t deserialized_u32 = ser_readdata32(stream); assert(u32 == deserialized_u32 && stream.empty()); ser_writedata32be(stream, u32); const uint32_t deserialized_u32be = ser_readdata32be(stream); assert(u32 == deserialized_u32be && stream.empty()); ser_writedata16(stream, u16); const uint16_t deserialized_u16 = ser_readdata16(stream); assert(u16 == deserialized_u16 && stream.empty()); ser_writedata8(stream, u8); const uint8_t deserialized_u8 = ser_readdata8(stream); assert(u8 == deserialized_u8 && stream.empty()); } { DataStream stream{}; WriteCompactSize(stream, u64); try { const uint64_t deserialized_u64 = ReadCompactSize(stream); assert(u64 == deserialized_u64 && stream.empty()); } catch (const std::ios_base::failure&) { } } }