From a3780d3e216287d64c7969560de909ab3144b0ec Mon Sep 17 00:00:00 2001 From: Karl-Johan Alm Date: Wed, 10 May 2023 15:54:49 +0900 Subject: [PATCH] rebase onto bitcoin core 24.0.1 --- Makefile.am | 9 +- arith_uint256.cpp | 33 +- arith_uint256.h | 9 +- base58.cpp | 9 +- base58.h | 1 - bech32.cpp | 389 +- bech32.h | 4 + btcdeb.cpp | 6 +- compat/byteswap.h | 2 +- compat/cpuid.h | 2 + compat/endian.h | 2 +- configure.ac | 23 +- amount.h => consensus/amount.h | 15 +- merkle.cpp => consensus/merkle.cpp | 9 +- merkle.h => consensus/merkle.h | 4 +- crypto/sha256.cpp | 84 +- debugger/interpreter.cpp | 10 +- debugger/interpreter.h | 10 +- debugger/see.h | 104 + ...-Bitcoin-Core-0.20.99-current-master.patch | 10 +- doc/patch-bitcoin-core-0.19.diff | 10 +- functions.cpp | 8 +- hash.cpp | 16 +- hash.h | 54 +- instance.cpp | 4 +- kerl/kerl.c | 20 +- policy/policy.h | 11 +- prevector.h | 18 +- primitives/transaction.cpp | 10 +- primitives/transaction.h | 61 +- pubkey.cpp | 51 +- pubkey.h | 53 +- script/interpreter.cpp | 139 +- script/interpreter.h | 135 +- script/script.cpp | 25 + script/script.h | 48 +- secp256k1/.cirrus.yml | 228 +- secp256k1/.gitignore | 27 +- secp256k1/Makefile.am | 136 +- secp256k1/README.md | 36 +- secp256k1/SECURITY.md | 4 +- .../build-aux/m4/ax_prog_cc_for_build.m4 | 125 - secp256k1/build-aux/m4/bitcoin_secp.m4 | 105 +- secp256k1/ci/cirrus.sh | 64 +- secp256k1/ci/linux-debian.Dockerfile | 19 +- secp256k1/configure.ac | 376 +- secp256k1/contrib/lax_der_parsing.c | 5 +- secp256k1/contrib/lax_der_parsing.h | 6 + .../contrib/lax_der_privatekey_parsing.c | 3 +- .../contrib/lax_der_privatekey_parsing.h | 6 + secp256k1/doc/safegcd_implementation.md | 765 - secp256k1/include/secp256k1.h | 185 +- secp256k1/include/secp256k1_ecdh.h | 15 +- secp256k1/include/secp256k1_extrakeys.h | 112 +- secp256k1/include/secp256k1_preallocated.h | 12 +- secp256k1/include/secp256k1_recovery.h | 35 +- secp256k1/include/secp256k1_schnorrsig.h | 139 +- secp256k1/obj/.gitignore | 0 secp256k1/sage/group_prover.sage | 64 +- .../sage/prove_group_implementations.sage | 141 +- secp256k1/sage/secp256k1_params.sage | 3 + secp256k1/sage/weierstrass_prover.sage | 13 +- secp256k1/src/bench.c | 234 + secp256k1/src/bench.h | 63 +- secp256k1/src/bench_ecmult.c | 231 +- secp256k1/src/bench_internal.c | 88 +- secp256k1/src/bench_sign.c | 58 - secp256k1/src/bench_verify.c | 115 - secp256k1/src/ecdsa.h | 2 +- secp256k1/src/ecdsa_impl.h | 12 +- secp256k1/src/eckey.h | 4 +- secp256k1/src/eckey_impl.h | 8 +- secp256k1/src/ecmult.h | 33 +- secp256k1/src/ecmult_compute_table.h | 16 + secp256k1/src/ecmult_compute_table_impl.h | 49 + secp256k1/src/ecmult_const.h | 1 + secp256k1/src/ecmult_const_impl.h | 87 +- secp256k1/src/ecmult_gen.h | 32 +- secp256k1/src/ecmult_gen_compute_table.h | 14 + secp256k1/src/ecmult_gen_compute_table_impl.h | 81 + secp256k1/src/ecmult_gen_impl.h | 134 +- secp256k1/src/ecmult_impl.h | 496 +- secp256k1/src/field.h | 23 +- secp256k1/src/field_10x26_impl.h | 113 +- secp256k1/src/field_5x52_impl.h | 104 +- secp256k1/src/field_5x52_int128_impl.h | 45 +- secp256k1/src/field_impl.h | 2 - secp256k1/src/gen_context.c | 89 - secp256k1/src/group.h | 36 +- secp256k1/src/group_impl.h | 282 +- secp256k1/src/hash.h | 4 +- secp256k1/src/hash_impl.h | 61 +- .../src/modules/ecdh/Makefile.am.include | 6 +- .../ecdh/bench_impl.h} | 18 +- secp256k1/src/modules/ecdh/main_impl.h | 4 +- secp256k1/src/modules/ecdh/tests_impl.h | 35 +- secp256k1/src/modules/extrakeys/main_impl.h | 39 +- .../modules/extrakeys/tests_exhaustive_impl.h | 2 +- secp256k1/src/modules/extrakeys/tests_impl.h | 106 +- .../src/modules/recovery/Makefile.am.include | 6 +- .../recovery/bench_impl.h} | 18 +- secp256k1/src/modules/recovery/main_impl.h | 15 +- .../modules/recovery/tests_exhaustive_impl.h | 2 +- secp256k1/src/modules/recovery/tests_impl.h | 46 +- .../modules/schnorrsig/Makefile.am.include | 6 +- .../schnorrsig/bench_impl.h} | 34 +- secp256k1/src/modules/schnorrsig/main_impl.h | 96 +- .../schnorrsig/tests_exhaustive_impl.h | 26 +- secp256k1/src/modules/schnorrsig/tests_impl.h | 265 +- secp256k1/src/precompute_ecmult.c | 96 + secp256k1/src/precompute_ecmult_gen.c | 80 + secp256k1/src/precomputed_ecmult.c | 16460 ++++++++++++++++ secp256k1/src/precomputed_ecmult.h | 35 + secp256k1/src/precomputed_ecmult_gen.c | 9750 +++++++++ secp256k1/src/precomputed_ecmult_gen.h | 26 + secp256k1/src/scalar_impl.h | 2 +- secp256k1/src/secp256k1.c | 140 +- secp256k1/src/testrand.h | 7 +- secp256k1/src/testrand_impl.h | 75 +- secp256k1/src/tests.c | 1226 +- secp256k1/src/tests_exhaustive.c | 25 +- secp256k1/src/util.h | 98 +- secp256k1/src/valgrind_ctime_test.c | 12 +- serialize.h | 115 +- span.h | 62 +- streams.h | 355 +- support/allocators/secure.h | 27 +- support/allocators/zeroafterfree.h | 20 +- support/lockedpool.cpp | 19 +- tap.cpp | 12 +- test/value.cpp | 4 +- uint256.h | 19 +- util/overflow.h | 50 + util/spanparsing.cpp | 21 +- util/spanparsing.h | 31 +- util/strencodings.cpp | 419 +- util/strencodings.h | 187 +- util/string.cpp | 14 + util/string.h | 128 + util/vector.h | 1 + value.cpp | 41 +- value.h | 7 +- 142 files changed, 32319 insertions(+), 4508 deletions(-) rename amount.h => consensus/amount.h (73%) rename merkle.cpp => consensus/merkle.cpp (96%) rename merkle.h => consensus/merkle.h (88%) create mode 100644 debugger/see.h delete mode 100644 secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 delete mode 100644 secp256k1/doc/safegcd_implementation.md delete mode 100644 secp256k1/obj/.gitignore create mode 100644 secp256k1/src/bench.c delete mode 100644 secp256k1/src/bench_sign.c delete mode 100644 secp256k1/src/bench_verify.c create mode 100644 secp256k1/src/ecmult_compute_table.h create mode 100644 secp256k1/src/ecmult_compute_table_impl.h create mode 100644 secp256k1/src/ecmult_gen_compute_table.h create mode 100644 secp256k1/src/ecmult_gen_compute_table_impl.h delete mode 100644 secp256k1/src/gen_context.c rename secp256k1/src/{bench_ecdh.c => modules/ecdh/bench_impl.h} (80%) rename secp256k1/src/{bench_recover.c => modules/recovery/bench_impl.h} (79%) rename secp256k1/src/{bench_schnorrsig.c => modules/schnorrsig/bench_impl.h} (71%) create mode 100644 secp256k1/src/precompute_ecmult.c create mode 100644 secp256k1/src/precompute_ecmult_gen.c create mode 100644 secp256k1/src/precomputed_ecmult.c create mode 100644 secp256k1/src/precomputed_ecmult.h create mode 100644 secp256k1/src/precomputed_ecmult_gen.c create mode 100644 secp256k1/src/precomputed_ecmult_gen.h create mode 100644 util/overflow.h create mode 100644 util/string.cpp create mode 100644 util/string.h diff --git a/Makefile.am b/Makefile.am index fe0144db..ba7d365f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,7 +36,6 @@ LIBBITCOIN_DEB_H = \ # bitcoin core # BITCOIN_CORE_H = \ $(LIBBITCOIN_DEB_H) \ - amount.h \ arith_uint256.h \ attributes.h \ base58.h \ @@ -45,6 +44,8 @@ BITCOIN_CORE_H = \ compat/byteswap.h \ compat/cpuid.h \ compat/endian.h \ + consensus/amount.h \ + consensus/merkle.h \ crypto/common.h \ crypto/hmac_sha512.h \ crypto/ripemd160.h \ @@ -52,7 +53,6 @@ BITCOIN_CORE_H = \ crypto/sha256.h \ crypto/sha512.h \ hash.h \ - merkle.h \ policy/policy.h \ prevector.h \ primitives/transaction.h \ @@ -69,6 +69,7 @@ BITCOIN_CORE_H = \ support/lockedpool.h \ tinyformat.h \ uint256.h \ + util/overflow.h \ util/spanparsing.h \ util/strencodings.h \ util/vector.h \ @@ -86,20 +87,20 @@ libbitcoin_deb_a_SOURCES = \ $(BITCOIN_CORE_H) # bitcoin: shared between all the tools -libbitcoin_a_LIBADD = $(LIBSECP256K1) +# libbitcoin_a_LIBADD = $(LIBSECP256K1) libbitcoin_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_a_CXXFLAGS = $(AM_CXXFLAGS) libbitcoin_a_SOURCES = \ arith_uint256.cpp \ base58.cpp \ bech32.cpp \ + consensus/merkle.cpp \ crypto/hmac_sha512.cpp \ crypto/ripemd160.cpp \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ hash.cpp \ - merkle.cpp \ primitives/transaction.cpp \ pubkey.cpp \ script/interpreter.cpp \ diff --git a/arith_uint256.cpp b/arith_uint256.cpp index 0bebb0cf..e614102d 100644 --- a/arith_uint256.cpp +++ b/arith_uint256.cpp @@ -96,7 +96,7 @@ base_uint& base_uint::operator/=(const base_uint& b) while (shift >= 0) { if (num >= div) { num -= div; - pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. + pn[shift / 32] |= (1U << (shift & 31)); // set a bit of the result. } div >>= 1; // shift back. shift--; @@ -146,13 +146,21 @@ double base_uint::getdouble() const template std::string base_uint::GetHex() const { - return ArithToUint256(*this).GetHex(); + base_blob b; + for (int x = 0; x < this->WIDTH; ++x) { + WriteLE32(b.begin() + x*4, this->pn[x]); + } + return b.GetHex(); } template void base_uint::SetHex(const char* psz) { - *this = UintToArith256(uint256S(psz)); + base_blob b; + b.SetHex(psz); + for (int x = 0; x < this->WIDTH; ++x) { + this->pn[x] = ReadLE32(b.begin() + x*4); + } } template @@ -164,7 +172,7 @@ void base_uint::SetHex(const std::string& str) template std::string base_uint::ToString() const { - return (GetHex()); + return GetHex(); } template @@ -183,20 +191,7 @@ unsigned int base_uint::bits() const } // Explicit instantiations for base_uint<256> -template base_uint<256>::base_uint(const std::string&); -template base_uint<256>& base_uint<256>::operator<<=(unsigned int); -template base_uint<256>& base_uint<256>::operator>>=(unsigned int); -template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); -template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); -template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); -template int base_uint<256>::CompareTo(const base_uint<256>&) const; -template bool base_uint<256>::EqualTo(uint64_t) const; -template double base_uint<256>::getdouble() const; -template std::string base_uint<256>::GetHex() const; -template std::string base_uint<256>::ToString() const; -template void base_uint<256>::SetHex(const char*); -template void base_uint<256>::SetHex(const std::string&); -template unsigned int base_uint<256>::bits() const; +template class base_uint<256>; // This implementation directly uses shifts instead of going // through an intermediate MPI representation. @@ -236,7 +231,7 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const nCompact >>= 8; nSize++; } - assert((nCompact & ~0x007fffff) == 0); + assert((nCompact & ~0x007fffffU) == 0); assert(nSize < 256); nCompact |= nSize << 24; nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); diff --git a/arith_uint256.h b/arith_uint256.h index 24b154cc..21dfc64c 100644 --- a/arith_uint256.h +++ b/arith_uint256.h @@ -24,22 +24,19 @@ template class base_uint { protected: + static_assert(BITS / 32 > 0 && BITS % 32 == 0, "Template parameter BITS must be a positive multiple of 32."); static constexpr int WIDTH = BITS / 32; uint32_t pn[WIDTH]; public: base_uint() { - static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); - for (int i = 0; i < WIDTH; i++) pn[i] = 0; } base_uint(const base_uint& b) { - static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); - for (int i = 0; i < WIDTH; i++) pn[i] = b.pn[i]; } @@ -53,8 +50,6 @@ class base_uint base_uint(uint64_t b) { - static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32."); - pn[0] = (unsigned int)b; pn[1] = (unsigned int)(b >> 32); for (int i = 2; i < WIDTH; i++) @@ -288,4 +283,6 @@ class arith_uint256 : public base_uint<256> { uint256 ArithToUint256(const arith_uint256 &); arith_uint256 UintToArith256(const uint256 &); +extern template class base_uint<256>; + #endif // BITCOIN_ARITH_UINT256_H diff --git a/base58.cpp b/base58.cpp index b020ba86..11c1ce73 100644 --- a/base58.cpp +++ b/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2020 The Bitcoin Core developers +// Copyright (c) 2014-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -125,7 +126,7 @@ std::string EncodeBase58(Span input) bool DecodeBase58(const std::string& str, std::vector& vchRet, int max_ret_len) { - if (!ValidAsCString(str)) { + if (!ContainsNoNUL(str)) { return false; } return DecodeBase58(str.c_str(), vchRet, max_ret_len); @@ -148,7 +149,7 @@ std::string EncodeBase58Check(Span input) return false; } // re-calculate the checksum, ensure it matches the included 4-byte checksum - uint256 hash = Hash(MakeSpan(vchRet).first(vchRet.size() - 4)); + uint256 hash = Hash(Span{vchRet}.first(vchRet.size() - 4)); if (memcmp(&hash, &vchRet[vchRet.size() - 4], 4) != 0) { vchRet.clear(); return false; @@ -159,7 +160,7 @@ std::string EncodeBase58Check(Span input) bool DecodeBase58Check(const std::string& str, std::vector& vchRet, int max_ret) { - if (!ValidAsCString(str)) { + if (!ContainsNoNUL(str)) { return false; } return DecodeBase58Check(str.c_str(), vchRet, max_ret); diff --git a/base58.h b/base58.h index 9ba5af73..d2a8d5e3 100644 --- a/base58.h +++ b/base58.h @@ -14,7 +14,6 @@ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H -#include #include #include diff --git a/bech32.cpp b/bech32.cpp index 288b14e0..dce9b2e4 100644 --- a/bech32.cpp +++ b/bech32.cpp @@ -1,11 +1,15 @@ // Copyright (c) 2017, 2021 Pieter Wuille +// Copyright (c) 2021 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 #include +#include #include +#include +#include namespace bech32 { @@ -30,6 +34,90 @@ const int8_t CHARSET_REV[128] = { 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 }; +/** We work with the finite field GF(1024) defined as a degree 2 extension of the base field GF(32) + * The defining polynomial of the extension is x^2 + 9x + 23. + * Let (e) be a root of this defining polynomial. Then (e) is a primitive element of GF(1024), + * that is, a generator of the field. Every non-zero element of the field can then be represented + * as (e)^k for some power k. + * The array GF1024_EXP contains all these powers of (e) - GF1024_EXP[k] = (e)^k in GF(1024). + * Conversely, GF1024_LOG contains the discrete logarithms of these powers, so + * GF1024_LOG[GF1024_EXP[k]] == k. + * The following function generates the two tables GF1024_EXP and GF1024_LOG as constexprs. */ +constexpr std::pair, std::array> GenerateGFTables() +{ + // Build table for GF(32). + // We use these tables to perform arithmetic in GF(32) below, when constructing the + // tables for GF(1024). + std::array GF32_EXP{}; + std::array GF32_LOG{}; + + // fmod encodes the defining polynomial of GF(32) over GF(2), x^5 + x^3 + 1. + // Because coefficients in GF(2) are binary digits, the coefficients are packed as 101001. + const int fmod = 41; + + // Elements of GF(32) are encoded as vectors of length 5 over GF(2), that is, + // 5 binary digits. Each element (b_4, b_3, b_2, b_1, b_0) encodes a polynomial + // b_4*x^4 + b_3*x^3 + b_2*x^2 + b_1*x^1 + b_0 (modulo fmod). + // For example, 00001 = 1 is the multiplicative identity. + GF32_EXP[0] = 1; + GF32_LOG[0] = -1; + GF32_LOG[1] = 0; + int v = 1; + for (int i = 1; i < 31; ++i) { + // Multiplication by x is the same as shifting left by 1, as + // every coefficient of the polynomial is moved up one place. + v = v << 1; + // If the polynomial now has an x^5 term, we subtract fmod from it + // to remain working modulo fmod. Subtraction is the same as XOR in characteristic + // 2 fields. + if (v & 32) v ^= fmod; + GF32_EXP[i] = v; + GF32_LOG[v] = i; + } + + // Build table for GF(1024) + std::array GF1024_EXP{}; + std::array GF1024_LOG{}; + + GF1024_EXP[0] = 1; + GF1024_LOG[0] = -1; + GF1024_LOG[1] = 0; + + // Each element v of GF(1024) is encoded as a 10 bit integer in the following way: + // v = v1 || v0 where v0, v1 are 5-bit integers (elements of GF(32)). + // The element (e) is encoded as 1 || 0, to represent 1*(e) + 0. Every other element + // a*(e) + b is represented as a || b (a and b are both GF(32) elements). Given (v), + // we compute (e)*(v) by multiplying in the following way: + // + // v0' = 23*v1 + // v1' = 9*v1 + v0 + // e*v = v1' || v0' + // + // Where 23, 9 are GF(32) elements encoded as described above. Multiplication in GF(32) + // is done using the log/exp tables: + // e^x * e^y = e^(x + y) so a * b = EXP[ LOG[a] + LOG [b] ] + // for non-zero a and b. + + v = 1; + for (int i = 1; i < 1023; ++i) { + int v0 = v & 31; + int v1 = v >> 5; + + int v0n = v1 ? GF32_EXP.at((GF32_LOG.at(v1) + GF32_LOG.at(23)) % 31) : 0; + int v1n = (v1 ? GF32_EXP.at((GF32_LOG.at(v1) + GF32_LOG.at(9)) % 31) : 0) ^ v0; + + v = v1n << 5 | v0n; + GF1024_EXP[i] = v; + GF1024_LOG[v] = i; + } + + return std::make_pair(GF1024_EXP, GF1024_LOG); +} + +constexpr auto tables = GenerateGFTables(); +constexpr const std::array& GF1024_EXP = tables.first; +constexpr const std::array& GF1024_LOG = tables.second; + /* Determine the final constant to use for the specified encoding. */ uint32_t EncodingConstant(Encoding encoding) { assert(encoding == Encoding::BECH32 || encoding == Encoding::BECH32M); @@ -66,6 +154,26 @@ uint32_t PolyMod(const data& v) // the above example, `c` initially corresponds to 1 mod g(x), and after processing 2 inputs of // v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value // for `c`. + + // The following Sage code constructs the generator used: + // + // B = GF(2) # Binary field + // BP. = B[] # Polynomials over the binary field + // F_mod = b**5 + b**3 + 1 + // F. = GF(32, modulus=F_mod, repr='int') # GF(32) definition + // FP. = F[] # Polynomials over GF(32) + // E_mod = x**2 + F.fetch_int(9)*x + F.fetch_int(23) + // E. = F.extension(E_mod) # GF(1024) extension field definition + // for p in divisors(E.order() - 1): # Verify e has order 1023. + // assert((e**p == 1) == (p % 1023 == 0)) + // G = lcm([(e**i).minpoly() for i in range(997,1000)]) + // print(G) # Print out the generator + // + // It demonstrates that g(x) is the least common multiple of the minimal polynomials + // of 3 consecutive powers (997,998,999) of a primitive element (e) of GF(1024). + // That guarantees it is, in fact, the generator of a primitive BCH code with cycle + // length 1023 and distance 4. See https://en.wikipedia.org/wiki/BCH_code for more details. + uint32_t c = 1; for (const auto v_i : v) { // We want to update `c` to correspond to a polynomial with one extra term. If the initial @@ -88,22 +196,118 @@ uint32_t PolyMod(const data& v) // Then compute c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i: c = ((c & 0x1ffffff) << 5) ^ v_i; - // Finally, for each set bit n in c0, conditionally add {2^n}k(x): + // Finally, for each set bit n in c0, conditionally add {2^n}k(x). These constants can be + // computed using the following Sage code (continuing the code above): + // + // for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(g(x) mod x^6), packed in hex integers. + // v = 0 + // for coef in reversed((F.fetch_int(i)*(G % x**6)).coefficients(sparse=True)): + // v = v*32 + coef.integer_representation() + // print("0x%x" % v) + // if (c0 & 1) c ^= 0x3b6a57b2; // k(x) = {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18} if (c0 & 2) c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13} if (c0 & 4) c ^= 0x1ea119fa; // {4}k(x) = {15}x^5 + {10}x^4 + {2}x^3 + {6}x^2 + {15}x + {26} if (c0 & 8) c ^= 0x3d4233dd; // {8}k(x) = {30}x^5 + {20}x^4 + {4}x^3 + {12}x^2 + {30}x + {29} if (c0 & 16) c ^= 0x2a1462b3; // {16}k(x) = {21}x^5 + x^4 + {8}x^3 + {24}x^2 + {21}x + {19} + } return c; } +/** Syndrome computes the values s_j = R(e^j) for j in [997, 998, 999]. As described above, the + * generator polynomial G is the LCM of the minimal polynomials of (e)^997, (e)^998, and (e)^999. + * + * Consider a codeword with errors, of the form R(x) = C(x) + E(x). The residue is the bit-packed + * result of computing R(x) mod G(X), where G is the generator of the code. Because C(x) is a valid + * codeword, it is a multiple of G(X), so the residue is in fact just E(x) mod G(x). Note that all + * of the (e)^j are roots of G(x) by definition, so R((e)^j) = E((e)^j). + * + * Let R(x) = r1*x^5 + r2*x^4 + r3*x^3 + r4*x^2 + r5*x + r6 + * + * To compute R((e)^j), we are really computing: + * r1*(e)^(j*5) + r2*(e)^(j*4) + r3*(e)^(j*3) + r4*(e)^(j*2) + r5*(e)^j + r6 + * + * Now note that all of the (e)^(j*i) for i in [5..0] are constants and can be precomputed. + * But even more than that, we can consider each coefficient as a bit-string. + * For example, take r5 = (b_5, b_4, b_3, b_2, b_1) written out as 5 bits. Then: + * r5*(e)^j = b_1*(e)^j + b_2*(2*(e)^j) + b_3*(4*(e)^j) + b_4*(8*(e)^j) + b_5*(16*(e)^j) + * where all the (2^i*(e)^j) are constants and can be precomputed. + * + * Then we just add each of these corresponding constants to our final value based on the + * bit values b_i. This is exactly what is done in the Syndrome function below. + */ +constexpr std::array GenerateSyndromeConstants() { + std::array SYNDROME_CONSTS{}; + for (int k = 1; k < 6; ++k) { + for (int shift = 0; shift < 5; ++shift) { + int16_t b = GF1024_LOG.at(1 << shift); + int16_t c0 = GF1024_EXP.at((997*k + b) % 1023); + int16_t c1 = GF1024_EXP.at((998*k + b) % 1023); + int16_t c2 = GF1024_EXP.at((999*k + b) % 1023); + uint32_t c = c2 << 20 | c1 << 10 | c0; + int ind = 5*(k-1) + shift; + SYNDROME_CONSTS[ind] = c; + } + } + return SYNDROME_CONSTS; +} +constexpr std::array SYNDROME_CONSTS = GenerateSyndromeConstants(); + +/** + * Syndrome returns the three values s_997, s_998, and s_999 described above, + * packed into a 30-bit integer, where each group of 10 bits encodes one value. + */ +uint32_t Syndrome(const uint32_t residue) { + // low is the first 5 bits, corresponding to the r6 in the residue + // (the constant term of the polynomial). + uint32_t low = residue & 0x1f; + + // We begin by setting s_j = low = r6 for all three values of j, because these are unconditional. + uint32_t result = low ^ (low << 10) ^ (low << 20); + + // Then for each following bit, we add the corresponding precomputed constant if the bit is 1. + // For example, 0x31edd3c4 is 1100011110 1101110100 1111000100 when unpacked in groups of 10 + // bits, corresponding exactly to a^999 || a^998 || a^997 (matching the corresponding values in + // GF1024_EXP above). In this way, we compute all three values of s_j for j in (997, 998, 999) + // simultaneously. Recall that XOR corresponds to addition in a characteristic 2 field. + for (int i = 0; i < 25; ++i) { + result ^= ((residue >> (5+i)) & 1 ? SYNDROME_CONSTS.at(i) : 0); + } + return result; +} + /** Convert to lower case. */ inline unsigned char LowerCase(unsigned char c) { return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c; } +/** Return indices of invalid characters in a Bech32 string. */ +bool CheckCharacters(const std::string& str, std::vector& errors) +{ + bool lower = false, upper = false; + for (size_t i = 0; i < str.size(); ++i) { + unsigned char c{(unsigned char)(str[i])}; + if (c >= 'a' && c <= 'z') { + if (upper) { + errors.push_back(i); + } else { + lower = true; + } + } else if (c >= 'A' && c <= 'Z') { + if (lower) { + errors.push_back(i); + } else { + upper = true; + } + } else if (c < 33 || c > 126) { + errors.push_back(i); + } + } + return errors.empty(); +} + /** Expand a HRP for use in checksum computation. */ data ExpandHRP(const std::string& hrp) { @@ -125,7 +329,8 @@ Encoding VerifyChecksum(const std::string& hrp, const data& values) // PolyMod computes what value to xor into the final values to make the checksum 0. However, // if we required that the checksum was 0, it would be the case that appending a 0 to a valid // list of values would result in a new valid list. For that reason, Bech32 requires the - // resulting checksum to be 1 instead. In Bech32m, this constant was amended. + // resulting checksum to be 1 instead. In Bech32m, this constant was amended. See + // https://gist.github.com/sipa/14c248c288c3880a3b191f978a34508e for details. const uint32_t check = PolyMod(Cat(ExpandHRP(hrp), values)); if (check == EncodingConstant(Encoding::BECH32)) return Encoding::BECH32; if (check == EncodingConstant(Encoding::BECH32M)) return Encoding::BECH32M; @@ -166,14 +371,8 @@ std::string Encode(Encoding encoding, const std::string& hrp, const data& values /** Decode a Bech32 or Bech32m string. */ DecodeResult Decode(const std::string& str) { - bool lower = false, upper = false; - for (size_t i = 0; i < str.size(); ++i) { - unsigned char c = str[i]; - if (c >= 'a' && c <= 'z') lower = true; - else if (c >= 'A' && c <= 'Z') upper = true; - else if (c < 33 || c > 126) return {}; - } - if (lower && upper) return {}; + std::vector errors; + if (!CheckCharacters(str, errors)) return {}; size_t pos = str.rfind('1'); if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) { return {}; @@ -197,4 +396,174 @@ DecodeResult Decode(const std::string& str) { return {result, std::move(hrp), data(values.begin(), values.end() - 6)}; } +/** Find index of an incorrect character in a Bech32 string. */ +std::pair> LocateErrors(const std::string& str) { + std::vector error_locations{}; + + if (str.size() > 90) { + error_locations.resize(str.size() - 90); + std::iota(error_locations.begin(), error_locations.end(), 90); + return std::make_pair("Bech32 string too long", std::move(error_locations)); + } + + if (!CheckCharacters(str, error_locations)){ + return std::make_pair("Invalid character or mixed case", std::move(error_locations)); + } + + size_t pos = str.rfind('1'); + if (pos == str.npos) { + return std::make_pair("Missing separator", std::vector{}); + } + if (pos == 0 || pos + 7 > str.size()) { + error_locations.push_back(pos); + return std::make_pair("Invalid separator position", std::move(error_locations)); + } + + std::string hrp; + for (size_t i = 0; i < pos; ++i) { + hrp += LowerCase(str[i]); + } + + size_t length = str.size() - 1 - pos; // length of data part + data values(length); + for (size_t i = pos + 1; i < str.size(); ++i) { + unsigned char c = str[i]; + int8_t rev = CHARSET_REV[c]; + if (rev == -1) { + error_locations.push_back(i); + return std::make_pair("Invalid Base 32 character", std::move(error_locations)); + } + values[i - pos - 1] = rev; + } + + // We attempt error detection with both bech32 and bech32m, and choose the one with the fewest errors + // We can't simply use the segwit version, because that may be one of the errors + std::optional error_encoding; + for (Encoding encoding : {Encoding::BECH32, Encoding::BECH32M}) { + std::vector possible_errors; + // Recall that (ExpandHRP(hrp) ++ values) is interpreted as a list of coefficients of a polynomial + // over GF(32). PolyMod computes the "remainder" of this polynomial modulo the generator G(x). + uint32_t residue = PolyMod(Cat(ExpandHRP(hrp), values)) ^ EncodingConstant(encoding); + + // All valid codewords should be multiples of G(x), so this remainder (after XORing with the encoding + // constant) should be 0 - hence 0 indicates there are no errors present. + if (residue != 0) { + // If errors are present, our polynomial must be of the form C(x) + E(x) where C is the valid + // codeword (a multiple of G(x)), and E encodes the errors. + uint32_t syn = Syndrome(residue); + + // Unpack the three 10-bit syndrome values + int s0 = syn & 0x3FF; + int s1 = (syn >> 10) & 0x3FF; + int s2 = syn >> 20; + + // Get the discrete logs of these values in GF1024 for more efficient computation + int l_s0 = GF1024_LOG.at(s0); + int l_s1 = GF1024_LOG.at(s1); + int l_s2 = GF1024_LOG.at(s2); + + // First, suppose there is only a single error. Then E(x) = e1*x^p1 for some position p1 + // Then s0 = E((e)^997) = e1*(e)^(997*p1) and s1 = E((e)^998) = e1*(e)^(998*p1) + // Therefore s1/s0 = (e)^p1, and by the same logic, s2/s1 = (e)^p1 too. + // Hence, s1^2 == s0*s2, which is exactly the condition we check first: + if (l_s0 != -1 && l_s1 != -1 && l_s2 != -1 && (2 * l_s1 - l_s2 - l_s0 + 2046) % 1023 == 0) { + // Compute the error position p1 as l_s1 - l_s0 = p1 (mod 1023) + size_t p1 = (l_s1 - l_s0 + 1023) % 1023; // the +1023 ensures it is positive + // Now because s0 = e1*(e)^(997*p1), we get e1 = s0/((e)^(997*p1)). Remember that (e)^1023 = 1, + // so 1/((e)^997) = (e)^(1023-997). + int l_e1 = l_s0 + (1023 - 997) * p1; + // Finally, some sanity checks on the result: + // - The error position should be within the length of the data + // - e1 should be in GF(32), which implies that e1 = (e)^(33k) for some k (the 31 non-zero elements + // of GF(32) form an index 33 subgroup of the 1023 non-zero elements of GF(1024)). + if (p1 < length && !(l_e1 % 33)) { + // Polynomials run from highest power to lowest, so the index p1 is from the right. + // We don't return e1 because it is dangerous to suggest corrections to the user, + // the user should check the address themselves. + possible_errors.push_back(str.size() - p1 - 1); + } + // Otherwise, suppose there are two errors. Then E(x) = e1*x^p1 + e2*x^p2. + } else { + // For all possible first error positions p1 + for (size_t p1 = 0; p1 < length; ++p1) { + // We have guessed p1, and want to solve for p2. Recall that E(x) = e1*x^p1 + e2*x^p2, so + // s0 = E((e)^997) = e1*(e)^(997^p1) + e2*(e)^(997*p2), and similar for s1 and s2. + // + // Consider s2 + s1*(e)^p1 + // = 2e1*(e)^(999^p1) + e2*(e)^(999*p2) + e2*(e)^(998*p2)*(e)^p1 + // = e2*(e)^(999*p2) + e2*(e)^(998*p2)*(e)^p1 + // (Because we are working in characteristic 2.) + // = e2*(e)^(998*p2) ((e)^p2 + (e)^p1) + // + int s2_s1p1 = s2 ^ (s1 == 0 ? 0 : GF1024_EXP.at((l_s1 + p1) % 1023)); + if (s2_s1p1 == 0) continue; + int l_s2_s1p1 = GF1024_LOG.at(s2_s1p1); + + // Similarly, s1 + s0*(e)^p1 + // = e2*(e)^(997*p2) ((e)^p2 + (e)^p1) + int s1_s0p1 = s1 ^ (s0 == 0 ? 0 : GF1024_EXP.at((l_s0 + p1) % 1023)); + if (s1_s0p1 == 0) continue; + int l_s1_s0p1 = GF1024_LOG.at(s1_s0p1); + + // So, putting these together, we can compute the second error position as + // (e)^p2 = (s2 + s1^p1)/(s1 + s0^p1) + // p2 = log((e)^p2) + size_t p2 = (l_s2_s1p1 - l_s1_s0p1 + 1023) % 1023; + + // Sanity checks that p2 is a valid position and not the same as p1 + if (p2 >= length || p1 == p2) continue; + + // Now we want to compute the error values e1 and e2. + // Similar to above, we compute s1 + s0*(e)^p2 + // = e1*(e)^(997*p1) ((e)^p1 + (e)^p2) + int s1_s0p2 = s1 ^ (s0 == 0 ? 0 : GF1024_EXP.at((l_s0 + p2) % 1023)); + if (s1_s0p2 == 0) continue; + int l_s1_s0p2 = GF1024_LOG.at(s1_s0p2); + + // And compute (the log of) 1/((e)^p1 + (e)^p2)) + int inv_p1_p2 = 1023 - GF1024_LOG.at(GF1024_EXP.at(p1) ^ GF1024_EXP.at(p2)); + + // Then (s1 + s0*(e)^p1) * (1/((e)^p1 + (e)^p2))) + // = e2*(e)^(997*p2) + // Then recover e2 by dividing by (e)^(997*p2) + int l_e2 = l_s1_s0p1 + inv_p1_p2 + (1023 - 997) * p2; + // Check that e2 is in GF(32) + if (l_e2 % 33) continue; + + // In the same way, (s1 + s0*(e)^p2) * (1/((e)^p1 + (e)^p2))) + // = e1*(e)^(997*p1) + // So recover e1 by dividing by (e)^(997*p1) + int l_e1 = l_s1_s0p2 + inv_p1_p2 + (1023 - 997) * p1; + // Check that e1 is in GF(32) + if (l_e1 % 33) continue; + + // Again, we do not return e1 or e2 for safety. + // Order the error positions from the left of the string and return them + if (p1 > p2) { + possible_errors.push_back(str.size() - p1 - 1); + possible_errors.push_back(str.size() - p2 - 1); + } else { + possible_errors.push_back(str.size() - p2 - 1); + possible_errors.push_back(str.size() - p1 - 1); + } + break; + } + } + } else { + // No errors + return std::make_pair("", std::vector{}); + } + + if (error_locations.empty() || (!possible_errors.empty() && possible_errors.size() < error_locations.size())) { + error_locations = std::move(possible_errors); + if (!error_locations.empty()) error_encoding = encoding; + } + } + std::string error_message = error_encoding == Encoding::BECH32M ? "Invalid Bech32m checksum" + : error_encoding == Encoding::BECH32 ? "Invalid Bech32 checksum" + : "Invalid checksum"; + + return std::make_pair(error_message, std::move(error_locations)); +} + } // namespace bech32 diff --git a/bech32.h b/bech32.h index e9450ccc..5e89e6ef 100644 --- a/bech32.h +++ b/bech32.h @@ -1,4 +1,5 @@ // Copyright (c) 2017, 2021 Pieter Wuille +// Copyright (c) 2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,6 +45,9 @@ struct DecodeResult /** Decode a Bech32 or Bech32m string. */ DecodeResult Decode(const std::string& str); +/** Return the positions of errors in a Bech32 string. */ +std::pair> LocateErrors(const std::string& str); + } // namespace bech32 #endif // BITCOIN_BECH32_H diff --git a/btcdeb.cpp b/btcdeb.cpp index 9713368f..8f3fb71b 100644 --- a/btcdeb.cpp +++ b/btcdeb.cpp @@ -323,11 +323,11 @@ int main(int argc, char* const* argv) it = script->begin(); while (script->GetOp(it, opcode, vchPushValue)) { char* pbuf = buf; - pbuf += sprintf(pbuf, "#%04d ", i); + pbuf += snprintf(pbuf, 1024, "#%04d ", i); if (vchPushValue.size() > 0) { - sprintf(pbuf, "%s", HexStr(std::vector(vchPushValue.begin(), vchPushValue.end())).c_str()); + snprintf(pbuf, 1024 + pbuf - buf, "%s", HexStr(std::vector(vchPushValue.begin(), vchPushValue.end())).c_str()); } else { - sprintf(pbuf, "%s", GetOpName(opcode).c_str()); + snprintf(pbuf, 1024 + pbuf - buf, "%s", GetOpName(opcode).c_str()); } script_lines[i++] = strdup(buf); } diff --git a/compat/byteswap.h b/compat/byteswap.h index 27ef1a18..2f4232fa 100644 --- a/compat/byteswap.h +++ b/compat/byteswap.h @@ -9,7 +9,7 @@ #include #endif -#include +#include #if defined(HAVE_BYTESWAP_H) #include diff --git a/compat/cpuid.h b/compat/cpuid.h index 0877ad47..e78c1ce6 100644 --- a/compat/cpuid.h +++ b/compat/cpuid.h @@ -10,6 +10,8 @@ #include +#include + // We can't use cpuid.h's __get_cpuid as it does not support subleafs. void static inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d) { diff --git a/compat/endian.h b/compat/endian.h index c5cf7a46..bdd8b84c 100644 --- a/compat/endian.h +++ b/compat/endian.h @@ -11,7 +11,7 @@ #include -#include +#include #if defined(HAVE_ENDIAN_H) #include diff --git a/configure.ac b/configure.ac index c24d3ab2..6562f55b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) -define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 4) -define(_CLIENT_VERSION_REVISION, 22) +define(_CLIENT_VERSION_MAJOR, 5) +define(_CLIENT_VERSION_MINOR, 0) +define(_CLIENT_VERSION_REVISION, 24) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) -define(_COPYRIGHT_YEAR, 2021) +define(_COPYRIGHT_YEAR, 2023) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[Bitcoin Core]]) AC_INIT([Bitcoin Debugger],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin-core/btcdeb/issues],[btcdeb],[https://twitter.com/kallewoof]) @@ -407,6 +407,21 @@ AC_SUBST(SSE42_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_CONFIG_FILES([Makefile]) +dnl boost's m4 checks do something really nasty: they export these vars. As a +dnl result, they leak into secp256k1's configure and crazy things happen. +dnl Until this is fixed upstream and we've synced, we'll just un-export them. +CPPFLAGS_TEMP="$CPPFLAGS" +unset CPPFLAGS +CPPFLAGS="$CPPFLAGS_TEMP" + +LDFLAGS_TEMP="$LDFLAGS" +unset LDFLAGS +LDFLAGS="$LDFLAGS_TEMP" + +LIBS_TEMP="$LIBS" +unset LIBS +LIBS="$LIBS_TEMP" + ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery --enable-module-schnorrsig --enable-experimental" AC_CONFIG_SUBDIRS([secp256k1]) diff --git a/amount.h b/consensus/amount.h similarity index 73% rename from amount.h rename to consensus/amount.h index 47968e80..f0eb4e07 100644 --- a/amount.h +++ b/consensus/amount.h @@ -1,17 +1,18 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2018 The Bitcoin Core developers +// Copyright (c) 2009-2021 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_AMOUNT_H -#define BITCOIN_AMOUNT_H +#ifndef BITCOIN_CONSENSUS_AMOUNT_H +#define BITCOIN_CONSENSUS_AMOUNT_H -#include +#include /** Amount in satoshis (Can be negative) */ typedef int64_t CAmount; -static const CAmount COIN = 100000000; +/** The amount of satoshis in one BTC. */ +static constexpr CAmount COIN = 100000000; /** No amount larger than this (in satoshi) is valid. * @@ -22,7 +23,7 @@ static const CAmount COIN = 100000000; * critical; in unusual circumstances like a(nother) overflow bug that allowed * for the creation of coins out of thin air modification could lead to a fork. * */ -static const CAmount MAX_MONEY = 21000000 * COIN; +static constexpr CAmount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } -#endif // BITCOIN_AMOUNT_H +#endif // BITCOIN_CONSENSUS_AMOUNT_H diff --git a/merkle.cpp b/consensus/merkle.cpp similarity index 96% rename from merkle.cpp rename to consensus/merkle.cpp index 0afc9252..9bdce258 100644 --- a/merkle.cpp +++ b/consensus/merkle.cpp @@ -1,17 +1,16 @@ -// Copyright (c) 2015-2017 The Bitcoin Core developers +// Copyright (c) 2015-2020 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 +#include #include -#include /* WARNING! If you're reading this because you're learning about crypto and/or designing a new system that will use merkle trees, keep in mind that the following merkle tree algorithm has a serious flaw related to duplicate txids, resulting in a vulnerability (CVE-2012-2459). - The reason is that if the number of hashes in the list at a given time + The reason is that if the number of hashes in the list at a given level is odd, the last one is duplicated before computing the next level (which is unusual in Merkle trees). This results in certain sequences of transactions leading to the same merkle root. For example, these two @@ -72,7 +71,7 @@ uint256 ComputeMerkleRoot(std::vector hashes, bool* mutated) { // } // return ComputeMerkleRoot(std::move(leaves), mutated); // } -// + // uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) // { // std::vector leaves; diff --git a/merkle.h b/consensus/merkle.h similarity index 88% rename from merkle.h rename to consensus/merkle.h index 81044762..84846b41 100644 --- a/merkle.h +++ b/consensus/merkle.h @@ -1,14 +1,12 @@ -// Copyright (c) 2015-2017 The Bitcoin Core developers +// Copyright (c) 2015-2019 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_CONSENSUS_MERKLE_H #define BITCOIN_CONSENSUS_MERKLE_H -#include #include -#include // #include #include diff --git a/crypto/sha256.cpp b/crypto/sha256.cpp index e35d526d..196f81ea 100644 --- a/crypto/sha256.cpp +++ b/crypto/sha256.cpp @@ -10,6 +10,16 @@ #include +#if defined(__linux__) && defined(ENABLE_ARM_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) +#include +#include +#endif + +#if defined(MAC_OSX) && defined(ENABLE_ARM_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) +#include +#include +#endif + #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) #if defined(USE_ASM) namespace sha256_sse4 @@ -29,16 +39,26 @@ namespace sha256d64_avx2 void Transform_8way(unsigned char* out, const unsigned char* in); } -namespace sha256d64_shani +namespace sha256d64_x86_shani { void Transform_2way(unsigned char* out, const unsigned char* in); } -namespace sha256_shani +namespace sha256_x86_shani +{ +void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks); +} + +namespace sha256_arm_shani { void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks); } +namespace sha256d64_arm_shani +{ +void Transform_2way(unsigned char* out, const unsigned char* in); +} + // Internal implementation code. namespace { @@ -566,17 +586,9 @@ std::string SHA256AutoDetect() bool have_sse4 = false; bool have_xsave = false; bool have_avx = false; - bool have_avx2 = false; - bool have_shani = false; - bool enabled_avx = false; - - (void)AVXEnabled; - (void)have_sse4; - (void)have_avx; - (void)have_xsave; - (void)have_avx2; - (void)have_shani; - (void)enabled_avx; + [[maybe_unused]] bool have_avx2 = false; + [[maybe_unused]] bool have_x86_shani = false; + [[maybe_unused]] bool enabled_avx = false; uint32_t eax, ebx, ecx, edx; GetCPUID(1, 0, eax, ebx, ecx, edx); @@ -589,15 +601,15 @@ std::string SHA256AutoDetect() if (have_sse4) { GetCPUID(7, 0, eax, ebx, ecx, edx); have_avx2 = (ebx >> 5) & 1; - have_shani = (ebx >> 29) & 1; + have_x86_shani = (ebx >> 29) & 1; } -#if defined(ENABLE_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) - if (have_shani) { - Transform = sha256_shani::Transform; - TransformD64 = TransformD64Wrapper; - TransformD64_2way = sha256d64_shani::Transform_2way; - ret = "shani(1way,2way)"; +#if defined(ENABLE_X86_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) + if (have_x86_shani) { + Transform = sha256_x86_shani::Transform; + TransformD64 = TransformD64Wrapper; + TransformD64_2way = sha256d64_x86_shani::Transform_2way; + ret = "x86_shani(1way,2way)"; have_sse4 = false; // Disable SSE4/AVX2; have_avx2 = false; } @@ -621,6 +633,38 @@ std::string SHA256AutoDetect() ret += ",avx2(8way)"; } #endif +#endif // defined(USE_ASM) && defined(HAVE_GETCPUID) + +#if defined(ENABLE_ARM_SHANI) && !defined(BUILD_BITCOIN_INTERNAL) + bool have_arm_shani = false; + +#if defined(__linux__) +#if defined(__arm__) // 32-bit + if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) { + have_arm_shani = true; + } +#endif +#if defined(__aarch64__) // 64-bit + if (getauxval(AT_HWCAP) & HWCAP_SHA2) { + have_arm_shani = true; + } +#endif +#endif + +#if defined(MAC_OSX) + int val = 0; + size_t len = sizeof(val); + if (sysctlbyname("hw.optional.arm.FEAT_SHA256", &val, &len, nullptr, 0) == 0) { + have_arm_shani = val != 0; + } +#endif + + if (have_arm_shani) { + Transform = sha256_arm_shani::Transform; + TransformD64 = TransformD64Wrapper; + TransformD64_2way = sha256d64_arm_shani::Transform_2way; + ret = "arm_shani(1way,2way)"; + } #endif assert(SelfTest()); diff --git a/debugger/interpreter.cpp b/debugger/interpreter.cpp index 6845da47..d2669277 100644 --- a/debugger/interpreter.cpp +++ b/debugger/interpreter.cpp @@ -7,8 +7,8 @@ #include -extern const CHashWriter HASHER_TAPSIGHASH; -static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak"); +extern const HashWriter HASHER_TAPSIGHASH; +static const HashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak"); TaprootCommitmentEnv::TaprootCommitmentEnv(const std::vector& control, const std::vector& program, const CScript& script, uint256* tapleaf_hash) : m_control(control) @@ -26,7 +26,7 @@ TaprootCommitmentEnv::TaprootCommitmentEnv(const std::vector& con btc_taproot_logf("- path len = %d\n", m_path_len); btc_taproot_logf("- p = %s\n", m_p.ToString().c_str()); btc_taproot_logf("- q = %s\n", m_q.ToString().c_str()); - m_k = (CHashWriter(HASHER_TAPLEAF) << uint8_t(control[0] & TAPROOT_LEAF_MASK) << script).GetSHA256(); + m_k = (HashWriter(HASHER_TAPLEAF) << uint8_t(control[0] & TAPROOT_LEAF_MASK) << script).GetSHA256(); btc_taproot_logf("- k = %s (tap leaf hash)\n", m_k.ToString().c_str()); m_k_desc = strprintf("TapLeaf(0x%02x || %s)", uint8_t(control[0] & TAPROOT_LEAF_MASK), HexStr(script).c_str()); btc_taproot_logf(" (%s)\n", m_k_desc.c_str()); @@ -36,7 +36,7 @@ TaprootCommitmentEnv::TaprootCommitmentEnv(const std::vector& con TaprootCommitmentEnv::State TaprootCommitmentEnv::Iterate() { btc_taproot_logf("- looping over path (0..%d)\n", m_path_len-1); if (m_i < m_path_len) { - CHashWriter ss_branch = HASHER_TAPBRANCH; + HashWriter ss_branch = HASHER_TAPBRANCH; Span node(m_control.data() + TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * m_i, TAPROOT_CONTROL_NODE_SIZE); if (std::lexicographical_compare(m_k.begin(), m_k.end(), node.begin(), node.end())) { btc_taproot_logf(" - %d: node = %02x...; taproot control node match -> k first\n", m_i, node[0]); @@ -55,7 +55,7 @@ TaprootCommitmentEnv::State TaprootCommitmentEnv::Iterate() { } // if (!m_applied_tweak) { // m_k_desc = strprintf("TapTweak(internal_pubkey=%s || %s)", HexStr(MakeSpan(m_p)).c_str(), m_k_desc.c_str()); - // m_k = (CHashWriter(HASHER_TAPTWEAK) << MakeSpan(m_p) << m_k).GetSHA256(); + // m_k = (HashWriter(HASHER_TAPTWEAK) << MakeSpan(m_p) << m_k).GetSHA256(); // btc_taproot_logf("- final k = %s\n", m_k.ToString().c_str()); // btc_taproot_logf(" (%s)\n", m_k_desc.c_str()); // m_applied_tweak = true; diff --git a/debugger/interpreter.h b/debugger/interpreter.h index 5e7a4d1a..d97884fa 100644 --- a/debugger/interpreter.h +++ b/debugger/interpreter.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_BTCDEB_INTERPRETER_H #define BITCOIN_BTCDEB_INTERPRETER_H -#include