crypto: replace CountBits with std::bit_width

bit_width is a drop-in replacement with an exact meaning in c++, so there is
no need to continue testing/fuzzing/benchmarking.
This commit is contained in:
Cory Fields 2023-12-12 18:44:49 +00:00
parent 52f9bba889
commit 297367b3bb
5 changed files with 5 additions and 34 deletions

View File

@ -7,7 +7,6 @@
#include <compat/endian.h>
#include <bit>
#include <cstdint>
#include <cstring>
@ -83,10 +82,4 @@ void static inline WriteBE64(unsigned char* ptr, uint64_t x)
memcpy(ptr, &v, 8);
}
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */
uint64_t static inline CountBits(uint64_t x)
{
return std::bit_width(x);
}
#endif // BITCOIN_CRYPTO_COMMON_H

View File

@ -11,6 +11,7 @@
#include <span.h>
#include <uint256.h>
#include <bit>
#include <cassert>
#include <chrono>
#include <cstdint>
@ -203,7 +204,7 @@ public:
{
assert(range);
--range;
int bits = CountBits(range);
int bits = std::bit_width(range);
while (true) {
uint64_t ret = randbits(bits);
if (ret <= range) return ret;

View File

@ -1060,28 +1060,6 @@ BOOST_AUTO_TEST_CASE(hkdf_hmac_sha256_l32_tests)
"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d");
}
BOOST_AUTO_TEST_CASE(countbits_tests)
{
FastRandomContext ctx;
for (unsigned int i = 0; i <= 64; ++i) {
if (i == 0) {
// Check handling of zero.
BOOST_CHECK_EQUAL(CountBits(0), 0U);
} else if (i < 10) {
for (uint64_t j = uint64_t{1} << (i - 1); (j >> i) == 0; ++j) {
// Exhaustively test up to 10 bits
BOOST_CHECK_EQUAL(CountBits(j), i);
}
} else {
for (int k = 0; k < 1000; k++) {
// Randomly test 1000 samples of each length above 10 bits.
uint64_t j = (uint64_t{1}) << (i - 1) | ctx.randbits(i - 1);
BOOST_CHECK_EQUAL(CountBits(j), i);
}
}
}
}
BOOST_AUTO_TEST_CASE(sha256d64)
{
for (int i = 0; i <= 32; ++i) {

View File

@ -80,7 +80,6 @@ FUZZ_TARGET(integer, .init = initialize_integer)
static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
const std::vector<uint256> v256{u256, u256_min, u256_max};
(void)ComputeMerkleRoot(v256);
(void)CountBits(u64);
(void)DecompressAmount(u64);
{
if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {

View File

@ -5,13 +5,13 @@
#include <util/asmap.h>
#include <clientversion.h>
#include <crypto/common.h>
#include <logging.h>
#include <serialize.h>
#include <streams.h>
#include <util/fs.h>
#include <algorithm>
#include <bit>
#include <cassert>
#include <cstdio>
#include <utility>
@ -111,7 +111,7 @@ uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip)
} else if (opcode == Instruction::MATCH) {
match = DecodeMatch(pos, endpos);
if (match == INVALID) break; // Match bits straddle EOF
matchlen = CountBits(match) - 1;
matchlen = std::bit_width(match) - 1;
if (bits < matchlen) break; // Not enough input bits
for (uint32_t bit = 0; bit < matchlen; bit++) {
if ((ip[ip.size() - bits]) != ((match >> (matchlen - 1 - bit)) & 1)) {
@ -175,7 +175,7 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits)
} else if (opcode == Instruction::MATCH) {
uint32_t match = DecodeMatch(pos, endpos);
if (match == INVALID) return false; // Match bits straddle EOF
int matchlen = CountBits(match) - 1;
int matchlen = std::bit_width(match) - 1;
if (prevopcode != Instruction::MATCH) had_incomplete_match = false;
if (matchlen < 8 && had_incomplete_match) return false; // Within a sequence of matches only at most one should be incomplete
had_incomplete_match = (matchlen < 8);