From fc87b03c0053424d19c09145e7ef4be2db845417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Thu, 20 Mar 2025 10:28:52 +0100 Subject: [PATCH 1/2] refactor: add explicit static extent to serialization spans --- src/serialize.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/serialize.h b/src/serialize.h index 98851056bdb7..984bcbda831f 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -53,12 +53,12 @@ constexpr deserialize_type deserialize {}; */ template inline void ser_writedata8(Stream &s, uint8_t obj) { - s.write(std::as_bytes(std::span{&obj, 1})); + s.write(std::as_bytes(std::span{&obj, 1})); } template inline void ser_writedata16(Stream &s, uint16_t obj) { obj = htole16_internal(obj); - s.write(std::as_bytes(std::span{&obj, 1})); + s.write(std::as_bytes(std::span{&obj, 1})); } template inline void ser_writedata16be(Stream &s, uint16_t obj) { @@ -68,28 +68,28 @@ template inline void ser_writedata16be(Stream &s, uint16_t obj) template inline void ser_writedata32(Stream &s, uint32_t obj) { obj = htole32_internal(obj); - s.write(std::as_bytes(std::span{&obj, 1})); + s.write(std::as_bytes(std::span{&obj, 1})); } template inline void ser_writedata32be(Stream &s, uint32_t obj) { obj = htobe32_internal(obj); - s.write(std::as_bytes(std::span{&obj, 1})); + s.write(std::as_bytes(std::span{&obj, 1})); } template inline void ser_writedata64(Stream &s, uint64_t obj) { obj = htole64_internal(obj); - s.write(std::as_bytes(std::span{&obj, 1})); + s.write(std::as_bytes(std::span{&obj, 1})); } template inline uint8_t ser_readdata8(Stream &s) { uint8_t obj; - s.read(std::as_writable_bytes(std::span{&obj, 1})); + s.read(std::as_writable_bytes(std::span{&obj, 1})); return obj; } template inline uint16_t ser_readdata16(Stream &s) { uint16_t obj; - s.read(std::as_writable_bytes(std::span{&obj, 1})); + s.read(std::as_writable_bytes(std::span{&obj, 1})); return le16toh_internal(obj); } template inline uint16_t ser_readdata16be(Stream &s) @@ -101,19 +101,19 @@ template inline uint16_t ser_readdata16be(Stream &s) template inline uint32_t ser_readdata32(Stream &s) { uint32_t obj; - s.read(std::as_writable_bytes(std::span{&obj, 1})); + s.read(std::as_writable_bytes(std::span{&obj, 1})); return le32toh_internal(obj); } template inline uint32_t ser_readdata32be(Stream &s) { uint32_t obj; - s.read(std::as_writable_bytes(std::span{&obj, 1})); + s.read(std::as_writable_bytes(std::span{&obj, 1})); return be32toh_internal(obj); } template inline uint64_t ser_readdata64(Stream &s) { uint64_t obj; - s.read(std::as_writable_bytes(std::span{&obj, 1})); + s.read(std::as_writable_bytes(std::span{&obj, 1})); return le64toh_internal(obj); } @@ -280,7 +280,6 @@ template inline void Unserialize(Stream& s, uint64_t& a) { a = template void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); } template void Unserialize(Stream& s, std::array& a) { s.read(MakeWritableByteSpan(a)); } template void Unserialize(Stream& s, std::span span) { s.read(std::as_writable_bytes(span)); } -template void Unserialize(Stream& s, std::span span) { s.read(std::as_writable_bytes(span)); } template inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); } template inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; } @@ -536,10 +535,10 @@ struct CustomUintFormatter if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range"); if (BigEndian) { uint64_t raw = htobe64_internal(v); - s.write(std::as_bytes(std::span{&raw, 1}).last(Bytes)); + s.write(std::as_bytes(std::span{&raw, 1}).template last()); } else { uint64_t raw = htole64_internal(v); - s.write(std::as_bytes(std::span{&raw, 1}).first(Bytes)); + s.write(std::as_bytes(std::span{&raw, 1}).template first()); } } @@ -549,10 +548,10 @@ struct CustomUintFormatter static_assert(std::numeric_limits::max() >= MAX && std::numeric_limits::min() <= 0, "Assigned type too small"); uint64_t raw = 0; if (BigEndian) { - s.read(std::as_writable_bytes(std::span{&raw, 1}).last(Bytes)); + s.read(std::as_writable_bytes(std::span{&raw, 1}).last()); v = static_cast(be64toh_internal(raw)); } else { - s.read(std::as_writable_bytes(std::span{&raw, 1}).first(Bytes)); + s.read(std::as_writable_bytes(std::span{&raw, 1}).first()); v = static_cast(le64toh_internal(raw)); } } From b099c57146ff5abcb423071717e9a153ad6151af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Thu, 20 Mar 2025 16:17:36 +0100 Subject: [PATCH 2/2] TODO --- src/bip324.cpp | 8 +++----- src/bip324.h | 4 ++-- src/common/pcp.cpp | 24 ++++++++++-------------- src/crypto/chacha20.cpp | 10 ++++------ src/crypto/chacha20.h | 10 +++++----- src/crypto/chacha20poly1305.cpp | 14 ++++++-------- src/crypto/chacha20poly1305.h | 6 +++--- src/crypto/hkdf_sha256_32.h | 2 +- src/crypto/hmac_sha256.h | 2 +- src/crypto/hmac_sha512.h | 2 +- src/crypto/poly1305.h | 6 ++---- src/crypto/ripemd160.h | 2 +- src/crypto/sha1.h | 2 +- src/crypto/sha256.h | 2 +- src/crypto/sha3.cpp | 3 +-- src/crypto/sha3.h | 2 +- src/hash.h | 10 ++++------ src/key.cpp | 6 ++---- src/key.h | 4 ++-- src/net.cpp | 10 +++++----- src/net.h | 2 +- src/netaddress.cpp | 7 ++----- src/netaddress.h | 2 +- src/psbt.h | 10 +++++----- src/pubkey.cpp | 6 ++---- src/pubkey.h | 8 ++++---- src/script/interpreter.cpp | 13 ++++++------- src/script/interpreter.h | 8 ++++---- src/script/sigcache.cpp | 2 +- src/script/sigcache.h | 2 +- src/script/sign.cpp | 2 +- src/span.h | 11 ++++++++++- src/test/bip324_tests.cpp | 4 ++-- src/test/fuzz/miniscript.cpp | 2 +- src/test/fuzz/signature_checker.cpp | 2 +- src/test/key_tests.cpp | 2 +- src/test/miniscript_tests.cpp | 2 +- src/test/net_tests.cpp | 2 +- src/uint256.h | 13 +++++++------ 39 files changed, 108 insertions(+), 121 deletions(-) diff --git a/src/bip324.cpp b/src/bip324.cpp index 73f51a195ee7..d737f5159108 100644 --- a/src/bip324.cpp +++ b/src/bip324.cpp @@ -22,7 +22,7 @@ #include #include -BIP324Cipher::BIP324Cipher(const CKey& key, std::span ent32) noexcept +BIP324Cipher::BIP324Cipher(const CKey& key, std::span ent32) noexcept : m_key(key) { m_our_pubkey = m_key.EllSwiftCreate(ent32); @@ -79,17 +79,15 @@ void BIP324Cipher::Encrypt(std::span contents, std::span> 8) & 0xFF)}; len[2] = std::byte{(uint8_t)((contents.size() >> 16) & 0xFF)}; - m_send_l_cipher->Crypt(len, output.first(LENGTH_LEN)); + m_send_l_cipher->Crypt(len, output.first()); // Encrypt plaintext. std::byte header[HEADER_LEN] = {ignore ? IGNORE_BIT : std::byte{0}}; m_send_p_cipher->Encrypt(header, contents, aad, output.subspan(LENGTH_LEN)); } -uint32_t BIP324Cipher::DecryptLength(std::span input) noexcept +uint32_t BIP324Cipher::DecryptLength(std::span input) noexcept { - assert(input.size() == LENGTH_LEN); - std::byte buf[LENGTH_LEN]; // Decrypt length m_recv_l_cipher->Crypt(input, buf); diff --git a/src/bip324.h b/src/bip324.h index 396a28a44894..4e627e003201 100644 --- a/src/bip324.h +++ b/src/bip324.h @@ -45,7 +45,7 @@ class BIP324Cipher BIP324Cipher() = delete; /** Initialize a BIP324 cipher with specified key and encoding entropy (testing only). */ - BIP324Cipher(const CKey& key, std::span ent32) noexcept; + BIP324Cipher(const CKey& key, std::span ent32) noexcept; /** Initialize a BIP324 cipher with specified key (testing only). */ BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept; @@ -74,7 +74,7 @@ class BIP324Cipher * * It must hold that input.size() == LENGTH_LEN. */ - unsigned DecryptLength(std::span input) noexcept; + unsigned DecryptLength(std::span input) noexcept; /** Decrypt a packet. Only after Initialize(). * diff --git a/src/common/pcp.cpp b/src/common/pcp.cpp index 8ababab32f3c..8c828b4cbbed 100644 --- a/src/common/pcp.cpp +++ b/src/common/pcp.cpp @@ -179,9 +179,8 @@ std::string PCPResultString(uint8_t result_code) } //! Wrap address in IPv6 according to RFC6887. wrapped_addr needs to be able to store 16 bytes. -[[nodiscard]] bool PCPWrapAddress(std::span wrapped_addr, const CNetAddr &addr) +[[nodiscard]] bool PCPWrapAddress(std::span wrapped_addr, const CNetAddr &addr) { - Assume(wrapped_addr.size() == ADDR_IPV6_SIZE); if (addr.IsIPv4()) { struct in_addr addr4; if (!addr.GetInAddr(&addr4)) return false; @@ -434,25 +433,22 @@ std::variant PCPRequestPortMap(const PCPMappingNonc // Make sure there's space for the request header and MAP specific request data. std::vector request(PCP_HDR_SIZE + PCP_MAP_SIZE); // Fill in request header, See RFC6887 Figure 2. - size_t ofs = 0; - request[ofs + PCP_HDR_VERSION_OFS] = PCP_VERSION; - request[ofs + PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP; - WriteBE32(request.data() + ofs + PCP_HDR_LIFETIME_OFS, lifetime); - if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_REQUEST_HDR_IP_OFS, ADDR_IPV6_SIZE), internal)) return MappingError::NETWORK_ERROR; - - ofs += PCP_HDR_SIZE; + request[PCP_HDR_VERSION_OFS] = PCP_VERSION; + request[PCP_HDR_OP_OFS] = PCP_REQUEST | PCP_OP_MAP; + WriteBE32(request.data() + PCP_HDR_LIFETIME_OFS, lifetime); + if (!PCPWrapAddress(std::span(request).subspan(), internal)) return MappingError::NETWORK_ERROR; // Fill in MAP request packet, See RFC6887 Figure 9. // Randomize mapping nonce (this is repeated in the response, to be able to // correlate requests and responses, and used to authenticate changes to the mapping). + constexpr size_t ofs = PCP_HDR_SIZE; std::memcpy(request.data() + ofs + PCP_MAP_NONCE_OFS, nonce.data(), PCP_MAP_NONCE_SIZE); request[ofs + PCP_MAP_PROTOCOL_OFS] = PCP_PROTOCOL_TCP; WriteBE16(request.data() + ofs + PCP_MAP_INTERNAL_PORT_OFS, port); WriteBE16(request.data() + ofs + PCP_MAP_EXTERNAL_PORT_OFS, port); - if (!PCPWrapAddress(std::span(request).subspan(ofs + PCP_MAP_EXTERNAL_IP_OFS, ADDR_IPV6_SIZE), bind)) return MappingError::NETWORK_ERROR; + if (!PCPWrapAddress(std::span(request).subspan(), bind)) return MappingError::NETWORK_ERROR; - ofs += PCP_MAP_SIZE; - Assume(ofs == request.size()); + Assume(ofs + PCP_MAP_SIZE == request.size()); // Receive loop. bool is_natpmp = false; @@ -477,8 +473,8 @@ std::variant PCPRequestPortMap(const PCPMappingNonc LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "pcp: Mapping nonce mismatch\n"); return false; // Wasn't response to what we expected, try receiving next packet. } - uint8_t protocol = response[PCP_HDR_SIZE + 12]; - uint16_t internal_port = ReadBE16(response.data() + PCP_HDR_SIZE + 16); + uint8_t protocol = response[PCP_HDR_SIZE + PCP_MAP_PROTOCOL_OFS]; + uint16_t internal_port = ReadBE16(response.data() + PCP_HDR_SIZE + PCP_MAP_INTERNAL_PORT_OFS); if (protocol != PCP_PROTOCOL_TCP || internal_port != port) { LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "pcp: Response protocol or port doesn't match request\n"); return false; // Wasn't response to what we expected, try receiving next packet. diff --git a/src/crypto/chacha20.cpp b/src/crypto/chacha20.cpp index acb860e9b46c..0093c81d3d8c 100644 --- a/src/crypto/chacha20.cpp +++ b/src/crypto/chacha20.cpp @@ -22,9 +22,8 @@ #define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0) -void ChaCha20Aligned::SetKey(std::span key) noexcept +void ChaCha20Aligned::SetKey(std::span key) noexcept { - assert(key.size() == KEYLEN); input[0] = ReadLE32(key.data() + 0); input[1] = ReadLE32(key.data() + 4); input[2] = ReadLE32(key.data() + 8); @@ -44,7 +43,7 @@ ChaCha20Aligned::~ChaCha20Aligned() memory_cleanse(input, sizeof(input)); } -ChaCha20Aligned::ChaCha20Aligned(std::span key) noexcept +ChaCha20Aligned::ChaCha20Aligned(std::span key) noexcept { SetKey(key); } @@ -334,17 +333,16 @@ ChaCha20::~ChaCha20() memory_cleanse(m_buffer.data(), m_buffer.size()); } -void ChaCha20::SetKey(std::span key) noexcept +void ChaCha20::SetKey(std::span key) noexcept { m_aligned.SetKey(key); m_bufleft = 0; memory_cleanse(m_buffer.data(), m_buffer.size()); } -FSChaCha20::FSChaCha20(std::span key, uint32_t rekey_interval) noexcept : +FSChaCha20::FSChaCha20(std::span key, uint32_t rekey_interval) noexcept : m_chacha20(key), m_rekey_interval(rekey_interval) { - assert(key.size() == KEYLEN); } void FSChaCha20::Crypt(std::span input, std::span output) noexcept diff --git a/src/crypto/chacha20.h b/src/crypto/chacha20.h index 06eb10781c56..4264733dd7ce 100644 --- a/src/crypto/chacha20.h +++ b/src/crypto/chacha20.h @@ -38,13 +38,13 @@ class ChaCha20Aligned ChaCha20Aligned() noexcept = delete; /** Initialize a cipher with specified 32-byte key. */ - ChaCha20Aligned(std::span key) noexcept; + ChaCha20Aligned(std::span key) noexcept; /** Destructor to clean up private memory. */ ~ChaCha20Aligned(); /** Set 32-byte key, and seek to nonce 0 and block position 0. */ - void SetKey(std::span key) noexcept; + void SetKey(std::span key) noexcept; /** Type for 96-bit nonces used by the Set function below. * @@ -89,13 +89,13 @@ class ChaCha20 ChaCha20() noexcept = delete; /** Initialize a cipher with specified 32-byte key. */ - ChaCha20(std::span key) noexcept : m_aligned(key) {} + ChaCha20(std::span key) noexcept : m_aligned(key) {} /** Destructor to clean up private memory. */ ~ChaCha20(); /** Set 32-byte key, and seek to nonce 0 and block position 0. */ - void SetKey(std::span key) noexcept; + void SetKey(std::span key) noexcept; /** 96-bit nonce type. */ using Nonce96 = ChaCha20Aligned::Nonce96; @@ -150,7 +150,7 @@ class FSChaCha20 FSChaCha20& operator=(FSChaCha20&&) = delete; /** Construct an FSChaCha20 cipher that rekeys every rekey_interval Crypt() calls. */ - FSChaCha20(std::span key, uint32_t rekey_interval) noexcept; + FSChaCha20(std::span key, uint32_t rekey_interval) noexcept; /** Encrypt or decrypt a chunk. */ void Crypt(std::span input, std::span output) noexcept; diff --git a/src/crypto/chacha20poly1305.cpp b/src/crypto/chacha20poly1305.cpp index 4c7da07d7ec5..3226bb5e7bab 100644 --- a/src/crypto/chacha20poly1305.cpp +++ b/src/crypto/chacha20poly1305.cpp @@ -13,14 +13,12 @@ #include #include -AEADChaCha20Poly1305::AEADChaCha20Poly1305(std::span key) noexcept : m_chacha20(key) +AEADChaCha20Poly1305::AEADChaCha20Poly1305(std::span key) noexcept : m_chacha20(key) { - assert(key.size() == KEYLEN); } -void AEADChaCha20Poly1305::SetKey(std::span key) noexcept +void AEADChaCha20Poly1305::SetKey(std::span key) noexcept { - assert(key.size() == KEYLEN); m_chacha20.SetKey(key); } @@ -36,7 +34,7 @@ int timingsafe_bcmp_internal(const unsigned char* b1, const unsigned char* b2, s } /** Compute poly1305 tag. chacha20 must be set to the right nonce, block 0. Will be at block 1 after. */ -void ComputeTag(ChaCha20& chacha20, std::span aad, std::span cipher, std::span tag) noexcept +void ComputeTag(ChaCha20& chacha20, std::span aad, std::span cipher, std::span tag) noexcept { static const std::byte PADDING[16] = {{}}; @@ -45,7 +43,7 @@ void ComputeTag(ChaCha20& chacha20, std::span aad, std::span()}; // Compute tag: // - Process the padded AAD with Poly1305. @@ -77,7 +75,7 @@ void AEADChaCha20Poly1305::Encrypt(std::span plain1, std::span< // Seek to block 0, and compute tag using key drawn from there. m_chacha20.Seek(nonce, 0); - ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last(EXPANSION)); + ComputeTag(m_chacha20, aad, cipher.first(cipher.size() - EXPANSION), cipher.last()); } bool AEADChaCha20Poly1305::Decrypt(std::span cipher, std::span aad, Nonce96 nonce, std::span plain1, std::span plain2) noexcept @@ -111,7 +109,7 @@ void FSChaCha20Poly1305::NextPacket() noexcept std::byte one_block[ChaCha20Aligned::BLOCKLEN]; m_aead.Keystream({0xFFFFFFFF, m_rekey_counter}, one_block); // Switch keys. - m_aead.SetKey(std::span{one_block}.first(KEYLEN)); + m_aead.SetKey(std::span{one_block}.first()); // Wipe the generated keystream (a copy remains inside m_aead, which will be cleaned up // once it cycles again, or is destroyed). memory_cleanse(one_block, sizeof(one_block)); diff --git a/src/crypto/chacha20poly1305.h b/src/crypto/chacha20poly1305.h index 75404ca5ffd8..b775296c3cbc 100644 --- a/src/crypto/chacha20poly1305.h +++ b/src/crypto/chacha20poly1305.h @@ -26,10 +26,10 @@ class AEADChaCha20Poly1305 static constexpr unsigned EXPANSION = Poly1305::TAGLEN; /** Initialize an AEAD instance with a specified 32-byte key. */ - AEADChaCha20Poly1305(std::span key) noexcept; + AEADChaCha20Poly1305(std::span key) noexcept; /** Switch to another 32-byte key. */ - void SetKey(std::span key) noexcept; + void SetKey(std::span key) noexcept; /** 96-bit nonce type. */ using Nonce96 = ChaCha20::Nonce96; @@ -111,7 +111,7 @@ class FSChaCha20Poly1305 FSChaCha20Poly1305& operator=(FSChaCha20Poly1305&&) = delete; /** Construct an FSChaCha20Poly1305 cipher that rekeys every rekey_interval operations. */ - FSChaCha20Poly1305(std::span key, uint32_t rekey_interval) noexcept : + FSChaCha20Poly1305(std::span key, uint32_t rekey_interval) noexcept : m_aead(key), m_rekey_interval(rekey_interval) {} /** Encrypt a message with a specified aad. diff --git a/src/crypto/hkdf_sha256_32.h b/src/crypto/hkdf_sha256_32.h index d3735203005f..72b5bff396a5 100644 --- a/src/crypto/hkdf_sha256_32.h +++ b/src/crypto/hkdf_sha256_32.h @@ -15,7 +15,7 @@ class CHKDF_HMAC_SHA256_L32 { private: unsigned char m_prk[32]; - static const size_t OUTPUT_SIZE = 32; + static constexpr size_t OUTPUT_SIZE = 32; public: CHKDF_HMAC_SHA256_L32(const unsigned char* ikm, size_t ikmlen, const std::string& salt); diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h index abd731d1fe54..5a6362b13764 100644 --- a/src/crypto/hmac_sha256.h +++ b/src/crypto/hmac_sha256.h @@ -18,7 +18,7 @@ class CHMAC_SHA256 CSHA256 inner; public: - static const size_t OUTPUT_SIZE = 32; + static constexpr size_t OUTPUT_SIZE = 32; CHMAC_SHA256(const unsigned char* key, size_t keylen); CHMAC_SHA256& Write(const unsigned char* data, size_t len) diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h index 8fa55d28444a..1d34609355fb 100644 --- a/src/crypto/hmac_sha512.h +++ b/src/crypto/hmac_sha512.h @@ -18,7 +18,7 @@ class CHMAC_SHA512 CSHA512 inner; public: - static const size_t OUTPUT_SIZE = 64; + static constexpr size_t OUTPUT_SIZE = 64; CHMAC_SHA512(const unsigned char* key, size_t keylen); CHMAC_SHA512& Write(const unsigned char* data, size_t len) diff --git a/src/crypto/poly1305.h b/src/crypto/poly1305.h index 94ea69be87ec..5cbb1ed597ec 100644 --- a/src/crypto/poly1305.h +++ b/src/crypto/poly1305.h @@ -46,9 +46,8 @@ class Poly1305 static constexpr unsigned KEYLEN{32}; /** Construct a Poly1305 object with a given 32-byte key. */ - Poly1305(std::span key) noexcept + Poly1305(std::span key) noexcept { - assert(key.size() == KEYLEN); poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data())); } @@ -60,9 +59,8 @@ class Poly1305 } /** Write authentication tag to 16-byte out. */ - void Finalize(std::span out) noexcept + void Finalize(std::span out) noexcept { - assert(out.size() == TAGLEN); poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data())); } }; diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index fb631a66d2d0..5290e87d72cd 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -17,7 +17,7 @@ class CRIPEMD160 uint64_t bytes{0}; public: - static const size_t OUTPUT_SIZE = 20; + static constexpr size_t OUTPUT_SIZE = 20; CRIPEMD160(); CRIPEMD160& Write(const unsigned char* data, size_t len); diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index 741cdaad58b5..acdf73f93026 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -17,7 +17,7 @@ class CSHA1 uint64_t bytes{0}; public: - static const size_t OUTPUT_SIZE = 20; + static constexpr size_t OUTPUT_SIZE = 20; CSHA1(); CSHA1& Write(const unsigned char* data, size_t len); diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h index b1348631d32e..45a329c054a0 100644 --- a/src/crypto/sha256.h +++ b/src/crypto/sha256.h @@ -18,7 +18,7 @@ class CSHA256 uint64_t bytes{0}; public: - static const size_t OUTPUT_SIZE = 32; + static constexpr size_t OUTPUT_SIZE = 32; CSHA256(); CSHA256& Write(const unsigned char* data, size_t len); diff --git a/src/crypto/sha3.cpp b/src/crypto/sha3.cpp index 77ea2a8ebfbc..2b78fb864c8e 100644 --- a/src/crypto/sha3.cpp +++ b/src/crypto/sha3.cpp @@ -133,9 +133,8 @@ SHA3_256& SHA3_256::Write(std::span data) return *this; } -SHA3_256& SHA3_256::Finalize(std::span output) +SHA3_256& SHA3_256::Finalize(std::span output) { - assert(output.size() == OUTPUT_SIZE); std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0); m_buffer[m_bufsize] ^= 0x06; m_state[m_pos] ^= ReadLE64(m_buffer); diff --git a/src/crypto/sha3.h b/src/crypto/sha3.h index 685586af63be..3552c0af8d58 100644 --- a/src/crypto/sha3.h +++ b/src/crypto/sha3.h @@ -34,7 +34,7 @@ class SHA3_256 SHA3_256() = default; SHA3_256& Write(std::span data); - SHA3_256& Finalize(std::span output); + SHA3_256& Finalize(std::span output); SHA3_256& Reset(); }; diff --git a/src/hash.h b/src/hash.h index 34486af64a1d..0fc023e42692 100644 --- a/src/hash.h +++ b/src/hash.h @@ -25,10 +25,9 @@ class CHash256 { private: CSHA256 sha; public: - static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; + static constexpr size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE; - void Finalize(std::span output) { - assert(output.size() == OUTPUT_SIZE); + void Finalize(std::span output) { unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); @@ -50,10 +49,9 @@ class CHash160 { private: CSHA256 sha; public: - static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; + static constexpr size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE; - void Finalize(std::span output) { - assert(output.size() == OUTPUT_SIZE); + void Finalize(std::span output) { unsigned char buf[CSHA256::OUTPUT_SIZE]; sha.Finalize(buf); CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); diff --git a/src/key.cpp b/src/key.cpp index 01fa3d270e38..8f679a887aaf 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -308,10 +308,9 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const return ret; } -EllSwiftPubKey CKey::EllSwiftCreate(std::span ent32) const +EllSwiftPubKey CKey::EllSwiftCreate(std::span ent32) const { assert(keydata); - assert(ent32.size() == 32); std::array encoded_pubkey; auto success = secp256k1_ellswift_create(secp256k1_context_sign, @@ -423,9 +422,8 @@ KeyPair::KeyPair(const CKey& key, const uint256* merkle_root) if (!success) ClearKeyPairData(); } -bool KeyPair::SignSchnorr(const uint256& hash, std::span sig, const uint256& aux) const +bool KeyPair::SignSchnorr(const uint256& hash, std::span sig, const uint256& aux) const { - assert(sig.size() == 64); if (!IsValid()) return false; auto keypair = reinterpret_cast(m_keypair->data()); bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), keypair, aux.data()); diff --git a/src/key.h b/src/key.h index 22f96880b7b0..d10675247936 100644 --- a/src/key.h +++ b/src/key.h @@ -192,7 +192,7 @@ class CKey * resulting encoding will be indistinguishable from uniform to any adversary who does not * know the private key (because the private key itself is always used as entropy as well). */ - EllSwiftPubKey EllSwiftCreate(std::span entropy) const; + EllSwiftPubKey EllSwiftCreate(std::span entropy) const; /** Compute a BIP324-style ECDH shared secret. * @@ -286,7 +286,7 @@ class KeyPair KeyPair(const KeyPair& other) { *this = other; } friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const; - [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span sig, const uint256& aux) const; + [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span sig, const uint256& aux) const; //! Check whether this keypair is valid. bool IsValid() const { return !!m_keypair; } diff --git a/src/net.cpp b/src/net.cpp index 0bab3dcd27fc..aef6c5f51b44 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -823,7 +823,7 @@ CNetMessage V1Transport::GetReceivedMessage(const std::chrono::microseconds time if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { LogDebug(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n", SanitizeString(msg.m_type), msg.m_message_size, - HexStr(std::span{hash}.first(CMessageHeader::CHECKSUM_SIZE)), + HexStr(std::span{hash}.first()), HexStr(hdr.pchChecksum), m_node_id); reject_message = true; @@ -997,7 +997,7 @@ void V2Transport::StartSendingHandshake() noexcept // We cannot wipe m_send_garbage as it will still be used as AAD later in the handshake. } -V2Transport::V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span ent32, std::vector garbage) noexcept +V2Transport::V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span ent32, std::vector garbage) noexcept : m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid}, m_v1_fallback{nodeid}, m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1}, @@ -1132,7 +1132,7 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept if (!m_initiating && m_recv_buffer.size() >= OFFSET + MATCH.size()) { if (std::equal(MATCH.begin(), MATCH.end(), m_recv_buffer.begin() + OFFSET)) { LogDebug(BCLog::NET, "V2 transport error: V1 peer with wrong MessageStart %s\n", - HexStr(std::span(m_recv_buffer).first(OFFSET))); + HexStr(std::span(m_recv_buffer).first())); return false; } } @@ -1180,7 +1180,7 @@ bool V2Transport::ProcessReceivedGarbageBytes() noexcept Assume(m_recv_state == RecvState::GARB_GARBTERM); Assume(m_recv_buffer.size() <= MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN); if (m_recv_buffer.size() >= BIP324Cipher::GARBAGE_TERMINATOR_LEN) { - if (std::ranges::equal(MakeByteSpan(m_recv_buffer).last(BIP324Cipher::GARBAGE_TERMINATOR_LEN), m_cipher.GetReceiveGarbageTerminator())) { + if (std::ranges::equal(MakeByteSpan(m_recv_buffer).last(), m_cipher.GetReceiveGarbageTerminator())) { // Garbage terminator received. Store garbage to authenticate it as AAD later. m_recv_aad = std::move(m_recv_buffer); m_recv_aad.resize(m_recv_aad.size() - BIP324Cipher::GARBAGE_TERMINATOR_LEN); @@ -1216,7 +1216,7 @@ bool V2Transport::ProcessReceivedPacketBytes() noexcept if (m_recv_buffer.size() == BIP324Cipher::LENGTH_LEN) { // Length descriptor received. - m_recv_len = m_cipher.DecryptLength(MakeByteSpan(m_recv_buffer)); + m_recv_len = m_cipher.DecryptLength(MakeByteSpan(m_recv_buffer).first()); if (m_recv_len > MAX_CONTENTS_LEN) { LogDebug(BCLog::NET, "V2 transport error: packet too large (%u bytes), peer=%d\n", m_recv_len, m_nodeid); return false; diff --git a/src/net.h b/src/net.h index 9fdec52115eb..fb92a2c8e1fd 100644 --- a/src/net.h +++ b/src/net.h @@ -641,7 +641,7 @@ class V2Transport final : public Transport V2Transport(NodeId nodeid, bool initiating) noexcept; /** Construct a V2 transport with specified keys and garbage (test use only). */ - V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span ent32, std::vector garbage) noexcept; + V2Transport(NodeId nodeid, bool initiating, const CKey& key, std::span ent32, std::vector garbage) noexcept; // Receive side functions. bool ReceivedMessageComplete() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex); diff --git a/src/netaddress.cpp b/src/netaddress.cpp index ca562a96cae0..b44084fa7e4d 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -134,10 +134,8 @@ void CNetAddr::SetIP(const CNetAddr& ipIn) m_addr = ipIn.m_addr; } -void CNetAddr::SetLegacyIPv6(std::span ipv6) +void CNetAddr::SetLegacyIPv6(std::span ipv6) { - assert(ipv6.size() == ADDR_IPV6_SIZE); - size_t skip{0}; if (HasPrefix(ipv6, IPV4_IN_IPV6_PREFIX)) { @@ -515,9 +513,8 @@ static std::string IPv4ToString(std::span a) // Return an IPv6 address text representation with zero compression as described in RFC 5952 // ("A Recommendation for IPv6 Address Text Representation"). -static std::string IPv6ToString(std::span a, uint32_t scope_id) +static std::string IPv6ToString(std::span a, uint32_t scope_id) { - assert(a.size() == ADDR_IPV6_SIZE); const std::array groups{ ReadBE16(&a[0]), ReadBE16(&a[2]), diff --git a/src/netaddress.h b/src/netaddress.h index 7c311e2f3abe..b44a7ee141bc 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -139,7 +139,7 @@ class CNetAddr * (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy * `addr` encoding. */ - void SetLegacyIPv6(std::span ipv6); + void SetLegacyIPv6(std::span ipv6); bool SetInternal(const std::string& name); diff --git a/src/psbt.h b/src/psbt.h index a53767ab54b2..c48a0219e004 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -495,7 +495,7 @@ struct PSBTInput throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage"); } // Read in the hash from key - std::vector hash_vec(key.begin() + 1, key.end()); + std::span hash_vec(key.begin() + 1, key.end()); uint160 hash(hash_vec); if (ripemd160_preimages.count(hash) > 0) { throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided"); @@ -516,7 +516,7 @@ struct PSBTInput throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage"); } // Read in the hash from key - std::vector hash_vec(key.begin() + 1, key.end()); + std::span hash_vec(key.begin() + 1, key.end()); uint256 hash(hash_vec); if (sha256_preimages.count(hash) > 0) { throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided"); @@ -537,7 +537,7 @@ struct PSBTInput throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage"); } // Read in the hash from key - std::vector hash_vec(key.begin() + 1, key.end()); + std::span hash_vec(key.begin() + 1, key.end()); uint160 hash(hash_vec); if (hash160_preimages.count(hash) > 0) { throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided"); @@ -558,7 +558,7 @@ struct PSBTInput throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage"); } // Read in the hash from key - std::vector hash_vec(key.begin() + 1, key.end()); + std::span hash_vec(key.begin() + 1, key.end()); uint256 hash(hash_vec); if (hash256_preimages.count(hash) > 0) { throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided"); @@ -893,7 +893,7 @@ struct PSBTOutput } else if (key.size() != 33) { throw std::ios_base::failure("Output Taproot BIP32 keypath key is not at 33 bytes"); } - XOnlyPubKey xonly(uint256(std::span(key).last(32))); + XOnlyPubKey xonly(std::span(key).last<32>()); std::set leaf_hashes; uint64_t value_len = ReadCompactSize(s); size_t before_hashes = s.size(); diff --git a/src/pubkey.cpp b/src/pubkey.cpp index a4ca9a170a9b..a7ebd9e3c435 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -227,9 +227,8 @@ bool XOnlyPubKey::IsFullyValid() const return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data()); } -bool XOnlyPubKey::VerifySchnorr(const uint256& msg, std::span sigbytes) const +bool XOnlyPubKey::VerifySchnorr(const uint256& msg, std::span sigbytes) const { - assert(sigbytes.size() == 64); secp256k1_xonly_pubkey pubkey; if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data())) return false; return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.begin(), 32, &pubkey); @@ -353,9 +352,8 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi return true; } -EllSwiftPubKey::EllSwiftPubKey(std::span ellswift) noexcept +EllSwiftPubKey::EllSwiftPubKey(std::span ellswift) noexcept { - assert(ellswift.size() == SIZE); std::copy(ellswift.begin(), ellswift.end(), m_pubkey.begin()); } diff --git a/src/pubkey.h b/src/pubkey.h index cbc827dc6068..fe153a2d4e41 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -254,16 +254,16 @@ class XOnlyPubKey bool IsNull() const { return m_keydata.IsNull(); } /** Construct an x-only pubkey from exactly 32 bytes. */ - constexpr explicit XOnlyPubKey(std::span bytes) : m_keydata{bytes} {} + constexpr explicit XOnlyPubKey(std::span bytes) : m_keydata{bytes} {} /** Construct an x-only pubkey from a normal pubkey. */ - explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan(1, 32)) {} + explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(std::span{pubkey}.subspan<1, 32>()) {} /** Verify a Schnorr signature against this public key. * * sigbytes must be exactly 64 bytes. */ - bool VerifySchnorr(const uint256& msg, std::span sigbytes) const; + bool VerifySchnorr(const uint256& msg, std::span sigbytes) const; /** Compute the Taproot tweak as specified in BIP341, with *this as internal * key: @@ -317,7 +317,7 @@ struct EllSwiftPubKey EllSwiftPubKey() noexcept = default; /** Construct a new ellswift public key from a given serialization. */ - EllSwiftPubKey(std::span ellswift) noexcept; + EllSwiftPubKey(std::span ellswift) noexcept; /** Decode to normal compressed CPubKey (for debugging purposes). */ CPubKey Decode() const; diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 61ea7f4503c2..bd5ed8e27a0f 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -13,6 +13,7 @@ #include typedef std::vector valtype; +typedef std::span keytype; namespace { @@ -343,7 +344,7 @@ static bool EvalChecksigPreTapscript(const valtype& vchSig, const valtype& vchPu return true; } -static bool EvalChecksigTapscript(const valtype& sig, const valtype& pubkey, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool& success) +static bool EvalChecksigTapscript(const valtype& sig, const keytype& pubkey, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool& success) { assert(sigversion == SigVersion::TAPSCRIPT); @@ -388,7 +389,7 @@ static bool EvalChecksigTapscript(const valtype& sig, const valtype& pubkey, Scr * A return value of false means the script fails entirely. When true is returned, the * success variable indicates whether the signature check itself succeeded. */ -static bool EvalChecksig(const valtype& sig, const valtype& pubkey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool& success) +static bool EvalChecksig(const valtype& sig, const keytype& pubkey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, ScriptExecutionData& execdata, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool& success) { switch (sigversion) { case SigVersion::BASE: @@ -1090,7 +1091,7 @@ bool EvalScript(std::vector >& stack, const CScript& const valtype& sig = stacktop(-3); const CScriptNum num(stacktop(-2), fRequireMinimal); - const valtype& pubkey = stacktop(-1); + const keytype& pubkey = stacktop(-1); bool success = true; if (!EvalChecksig(sig, pubkey, pbegincodehash, pend, execdata, flags, checker, sigversion, serror, success)) return false; @@ -1639,7 +1640,7 @@ bool GenericTransactionSignatureChecker::VerifyECDSASignature(const std::vect } template -bool GenericTransactionSignatureChecker::VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const +bool GenericTransactionSignatureChecker::VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const { return pubkey.VerifySchnorr(sighash, sig); } @@ -1670,11 +1671,9 @@ bool GenericTransactionSignatureChecker::CheckECDSASignature(const std::vecto } template -bool GenericTransactionSignatureChecker::CheckSchnorrSignature(std::span sig, std::span pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const +bool GenericTransactionSignatureChecker::CheckSchnorrSignature(std::span sig, std::span pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const { assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT); - // Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this. - assert(pubkey_in.size() == 32); // Note that in Tapscript evaluation, empty signatures are treated specially (invalid signature that does not // abort script execution). This is implemented in EvalChecksigTapscript, which won't invoke // CheckSchnorrSignature in that case. In other contexts, they are invalid like every other signature with diff --git a/src/script/interpreter.h b/src/script/interpreter.h index e8c5b09045fd..cd40ddb3c9c2 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -250,7 +250,7 @@ class BaseSignatureChecker return false; } - virtual bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const + virtual bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const { return false; } @@ -292,13 +292,13 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker protected: virtual bool VerifyECDSASignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; - virtual bool VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const; + virtual bool VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const; public: GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {} GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} bool CheckECDSASignature(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override; - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override; bool CheckLockTime(const CScriptNum& nLockTime) const override; bool CheckSequence(const CScriptNum& nSequence) const override; }; @@ -319,7 +319,7 @@ class DeferringSignatureChecker : public BaseSignatureChecker return m_checker.CheckECDSASignature(scriptSig, vchPubKey, scriptCode, sigversion); } - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override { return m_checker.CheckSchnorrSignature(sig, pubkey, sigversion, execdata, serror); } diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 6b308258bcf1..3e1f1eecb70a 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -73,7 +73,7 @@ bool CachingTransactionSignatureChecker::VerifyECDSASignature(const std::vector< return true; } -bool CachingTransactionSignatureChecker::VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const +bool CachingTransactionSignatureChecker::VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const { uint256 entry; m_signature_cache.ComputeEntrySchnorr(entry, sighash, sig, pubkey); diff --git a/src/script/sigcache.h b/src/script/sigcache.h index ca4b44910e65..f9a368e114dd 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -70,7 +70,7 @@ class CachingTransactionSignatureChecker : public TransactionSignatureChecker CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, bool storeIn, SignatureCache& signature_cache, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amountIn, txdataIn, MissingDataBehavior::ASSERT_FAIL), store(storeIn), m_signature_cache(signature_cache) {} bool VerifyECDSASignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override; - bool VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override; + bool VerifySchnorrSignature(std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) const override; }; #endif // BITCOIN_SCRIPT_SIGCACHE_H diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 33cbc38be41d..1a5a484e78d1 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -701,7 +701,7 @@ class DummySignatureChecker final : public BaseSignatureChecker public: DummySignatureChecker() = default; bool CheckECDSASignature(const std::vector& sig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return sig.size() != 0; } - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return sig.size() != 0; } + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return sig.size() != 0; } bool CheckLockTime(const CScriptNum& nLockTime) const override { return true; } bool CheckSequence(const CScriptNum& nSequence) const override { return true; } }; diff --git a/src/span.h b/src/span.h index 5e34cd91909d..ff113d02685e 100644 --- a/src/span.h +++ b/src/span.h @@ -83,7 +83,16 @@ T& SpanPopBack(std::span& span) template auto MakeByteSpan(const V& v) noexcept { - return std::as_bytes(std::span{v}); + if constexpr (std::is_integral_v || std::is_same_v) { + return std::as_bytes(std::span{&v, 1}); + } else if constexpr (requires { + { V::size() } -> std::convertible_to; + { v.data() } -> std::convertible_to; + }) { + return std::as_bytes(std::span{v.data(), V::size()}); + } else { + return std::as_bytes(std::span{v}); + } } template auto MakeWritableByteSpan(V&& v) noexcept diff --git a/src/test/bip324_tests.cpp b/src/test/bip324_tests.cpp index 96392973b444..ecf9791e8b30 100644 --- a/src/test/bip324_tests.cpp +++ b/src/test/bip324_tests.cpp @@ -121,7 +121,7 @@ void TestBIP324PacketVector( for (uint32_t i = 0; i < dec_idx; ++i) { unsigned use_idx = i < in_idx ? i : 0; bool dec_ignore{false}; - dec_cipher.DecryptLength(std::span{dummies[use_idx]}.first(cipher.LENGTH_LEN)); + dec_cipher.DecryptLength(std::span{dummies[use_idx]}.first()); dec_cipher.Decrypt(std::span{dummies[use_idx]}.subspan(cipher.LENGTH_LEN), {}, dec_ignore, {}); } @@ -133,7 +133,7 @@ void TestBIP324PacketVector( } // Decrypt length and resize ciphertext to accommodate. - uint32_t dec_len = dec_cipher.DecryptLength(MakeByteSpan(to_decrypt).first(cipher.LENGTH_LEN)); + uint32_t dec_len = dec_cipher.DecryptLength(MakeByteSpan(to_decrypt).first()); to_decrypt.resize(dec_len + cipher.EXPANSION); // Construct copied (and possibly damaged) copy of aad. diff --git a/src/test/fuzz/miniscript.cpp b/src/test/fuzz/miniscript.cpp index 8984cbe50c01..eb83c918d5fd 100644 --- a/src/test/fuzz/miniscript.cpp +++ b/src/test/fuzz/miniscript.cpp @@ -290,7 +290,7 @@ const struct CheckerContext: BaseSignatureChecker { if (it == TEST_DATA.dummy_sigs.end()) return false; return it->second.first == sig; } - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion, + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion, ScriptExecutionData&, ScriptError*) const override { XOnlyPubKey pk{pubkey}; auto it = TEST_DATA.schnorr_sigs.find(pk); diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp index 9c32b7a822b3..90a41e5206b4 100644 --- a/src/test/fuzz/signature_checker.cpp +++ b/src/test/fuzz/signature_checker.cpp @@ -29,7 +29,7 @@ class FuzzedSignatureChecker : public BaseSignatureChecker return m_fuzzed_data_provider.ConsumeBool(); } - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override { return m_fuzzed_data_provider.ConsumeBool(); } diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 1b60a9c9eba6..0660aacb536c 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(key_ellswift) BOOST_CHECK(key.IsValid()); uint256 ent32 = m_rng.rand256(); - auto ellswift = key.EllSwiftCreate(std::as_bytes(std::span{ent32})); + auto ellswift = key.EllSwiftCreate(MakeByteSpan(ent32)); CPubKey decoded_pubkey = ellswift.Decode(); if (!key.IsCompressed()) { diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp index f253562a2f6c..ac6d3b0c05b7 100644 --- a/src/test/miniscript_tests.cpp +++ b/src/test/miniscript_tests.cpp @@ -272,7 +272,7 @@ class TestSignatureChecker : public BaseSignatureChecker { return sig == it->second; } - bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion, + bool CheckSchnorrSignature(std::span sig, std::span pubkey, SigVersion, ScriptExecutionData&, ScriptError*) const override { XOnlyPubKey pk{pubkey}; auto it = g_testdata->schnorr_signatures.find(pk); diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 0036d94c2fa5..872c16db53ab 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -1209,7 +1209,7 @@ class V2TransportTester // When processing a packet, at least enough bytes for its length descriptor must be received. BOOST_REQUIRE(m_received.size() >= BIP324Cipher::LENGTH_LEN); // Decrypt the content length. - size_t size = m_cipher.DecryptLength(MakeByteSpan(std::span{m_received}.first(BIP324Cipher::LENGTH_LEN))); + size_t size = m_cipher.DecryptLength(MakeByteSpan(std::span{m_received}.first())); // Check that the full packet is in the receive buffer. BOOST_REQUIRE(m_received.size() >= size + BIP324Cipher::EXPANSION); // Decrypt the packet contents. diff --git a/src/uint256.h b/src/uint256.h index 094db613b40a..733285ae940b 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -37,9 +37,8 @@ class base_blob /* constructor for constants between 1 and 255 */ constexpr explicit base_blob(uint8_t v) : m_data{v} {} - constexpr explicit base_blob(std::span vch) + constexpr explicit base_blob(std::span vch) { - assert(vch.size() == WIDTH); std::copy(vch.begin(), vch.end(), m_data.begin()); } @@ -190,7 +189,8 @@ class uint160 : public base_blob<160> { public: static std::optional FromHex(std::string_view str) { return detail::FromHex(str); } constexpr uint160() = default; - constexpr explicit uint160(std::span vch) : base_blob<160>(vch) {} + constexpr explicit uint160(std::span vch) : base_blob(vch) {} + operator std::span() { return std::span(data(), 20); } }; /** 256-bit opaque blob. @@ -203,9 +203,10 @@ class uint256 : public base_blob<256> { static std::optional FromHex(std::string_view str) { return detail::FromHex(str); } static std::optional FromUserHex(std::string_view str) { return detail::FromUserHex(str); } constexpr uint256() = default; - consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} - constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} - constexpr explicit uint256(std::span vch) : base_blob<256>(vch) {} + consteval explicit uint256(std::string_view hex_str) : base_blob(hex_str) {} + constexpr explicit uint256(uint8_t v) : base_blob(v) {} + constexpr explicit uint256(std::span vch) : base_blob(vch) {} + operator std::span() { return std::span(data(), 32); } static const uint256 ZERO; static const uint256 ONE; };