util: move HexStr and HexDigit from util to crypto

Move HexStr and HexDigit functions from util to crypto. The crypto library does
not actually use these functions, but the consensus library does. The consensus
and util libraries not allowed to depend on each other, but are allowed to
depend on the cryto library, so the crypto library is a reasonable put these.

The consensus library uses HexStr and HexDigit in script.cpp, transaction.cpp,
and uint256.cpp.

The util library does not use HexStr but does use HexDigit in strencodings.cpp
to parse integers.
This commit is contained in:
TheCharlatan 2023-10-23 22:31:24 +02:00
parent 6861f954f8
commit 23cc8ddff4
7 changed files with 100 additions and 71 deletions

View file

@ -319,6 +319,7 @@ BITCOIN_CORE_H = \
util/signalinterrupt.h \
util/sock.h \
util/spanparsing.h \
util/strencodings.h \
util/string.h \
util/subprocess.h \
util/syserror.h \
@ -565,6 +566,8 @@ crypto_libbitcoin_crypto_base_la_SOURCES = \
crypto/chacha20poly1305.h \
crypto/chacha20poly1305.cpp \
crypto/common.h \
crypto/hex_base.cpp \
crypto/hex_base.h \
crypto/hkdf_sha256_32.cpp \
crypto/hkdf_sha256_32.h \
crypto/hmac_sha256.cpp \
@ -658,9 +661,7 @@ libbitcoin_consensus_a_SOURCES = \
span.h \
tinyformat.h \
uint256.cpp \
uint256.h \
util/strencodings.cpp \
util/strencodings.h
uint256.h
#
# common #

67
src/crypto/hex_base.cpp Normal file
View file

@ -0,0 +1,67 @@
// Copyright (c) 2009-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 <crypto/hex_base.h>
#include <array>
#include <cstring>
#include <string>
namespace {
using ByteAsHex = std::array<char, 2>;
constexpr std::array<ByteAsHex, 256> CreateByteToHexMap()
{
constexpr char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
std::array<ByteAsHex, 256> byte_to_hex{};
for (size_t i = 0; i < byte_to_hex.size(); ++i) {
byte_to_hex[i][0] = hexmap[i >> 4];
byte_to_hex[i][1] = hexmap[i & 15];
}
return byte_to_hex;
}
} // namespace
std::string HexStr(const Span<const uint8_t> s)
{
std::string rv(s.size() * 2, '\0');
static constexpr auto byte_to_hex = CreateByteToHexMap();
static_assert(sizeof(byte_to_hex) == 512);
char* it = rv.data();
for (uint8_t v : s) {
std::memcpy(it, byte_to_hex[v].data(), 2);
it += 2;
}
assert(it == rv.data() + rv.size());
return rv;
}
const signed char p_util_hexdigit[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
signed char HexDigit(char c)
{
return p_util_hexdigit[(unsigned char)c];
}

23
src/crypto/hex_base.h Normal file
View file

@ -0,0 +1,23 @@
// Copyright (c) 2009-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.
#ifndef BITCOIN_CRYPTO_HEX_BASE_H
#define BITCOIN_CRYPTO_HEX_BASE_H
#include <span.h>
#include <cstddef>
#include <cstdint>
#include <string>
/**
* Convert a span of bytes to a lower-case hexadecimal string.
*/
std::string HexStr(const Span<const uint8_t> s);
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
signed char HexDigit(char c);
#endif // BITCOIN_CRYPTO_HEX_BASE_H

View file

@ -6,12 +6,12 @@
#include <primitives/transaction.h>
#include <consensus/amount.h>
#include <crypto/hex_base.h>
#include <hash.h>
#include <script/script.h>
#include <serialize.h>
#include <tinyformat.h>
#include <uint256.h>
#include <util/strencodings.h>
#include <util/transaction_identifier.h>
#include <algorithm>

View file

@ -6,10 +6,10 @@
#include <script/script.h>
#include <crypto/common.h>
#include <crypto/hex_base.h>
#include <hash.h>
#include <uint256.h>
#include <util/hash_type.h>
#include <util/strencodings.h>
#include <string>

View file

@ -3,9 +3,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <span.h>
#include <util/strencodings.h>
#include <crypto/hex_base.h>
#include <span.h>
#include <array>
#include <cassert>
#include <cstring>
@ -36,29 +38,6 @@ std::string SanitizeString(std::string_view str, int rule)
return result;
}
const signed char p_util_hexdigit[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
signed char HexDigit(char c)
{
return p_util_hexdigit[(unsigned char)c];
}
bool IsHex(std::string_view str)
{
for (char c : str) {
@ -466,40 +445,6 @@ std::string Capitalize(std::string str)
return str;
}
namespace {
using ByteAsHex = std::array<char, 2>;
constexpr std::array<ByteAsHex, 256> CreateByteToHexMap()
{
constexpr char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
std::array<ByteAsHex, 256> byte_to_hex{};
for (size_t i = 0; i < byte_to_hex.size(); ++i) {
byte_to_hex[i][0] = hexmap[i >> 4];
byte_to_hex[i][1] = hexmap[i & 15];
}
return byte_to_hex;
}
} // namespace
std::string HexStr(const Span<const uint8_t> s)
{
std::string rv(s.size() * 2, '\0');
static constexpr auto byte_to_hex = CreateByteToHexMap();
static_assert(sizeof(byte_to_hex) == 512);
char* it = rv.data();
for (uint8_t v : s) {
std::memcpy(it, byte_to_hex[v].data(), 2);
it += 2;
}
assert(it == rv.data() + rv.size());
return rv;
}
std::optional<uint64_t> ParseByteUnits(std::string_view str, ByteUnit default_multiplier)
{
if (str.empty()) {

View file

@ -9,6 +9,7 @@
#ifndef BITCOIN_UTIL_STRENCODINGS_H
#define BITCOIN_UTIL_STRENCODINGS_H
#include <crypto/hex_base.h> // IWYU pragma: export
#include <span.h>
#include <util/string.h>
@ -66,7 +67,6 @@ std::vector<Byte> ParseHex(std::string_view hex_str)
{
return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{});
}
signed char HexDigit(char c);
/* Returns true if each character in str is a hex character, and has an even
* number of hex digits.*/
bool IsHex(std::string_view str);
@ -231,13 +231,6 @@ std::optional<T> ToIntegral(std::string_view str)
*/
[[nodiscard]] bool ParseUInt64(std::string_view str, uint64_t *out);
/**
* Convert a span of bytes to a lower-case hexadecimal string.
*/
std::string HexStr(const Span<const uint8_t> s);
inline std::string HexStr(const Span<const char> s) { return HexStr(MakeUCharSpan(s)); }
inline std::string HexStr(const Span<const std::byte> s) { return HexStr(MakeUCharSpan(s)); }
/**
* Format a paragraph of text to a fixed width, adding spaces for
* indentation to any added line.