diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dac8872080a..d244dfb34f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,8 @@ set(SECP256K1_DISABLE_SHARED ON CACHE BOOL "" FORCE) set(SECP256K1_ENABLE_MODULE_ECDH OFF CACHE BOOL "" FORCE) set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE) set(SECP256K1_ENABLE_MODULE_MUSIG OFF CACHE BOOL "" FORCE) +set(SECP256K1_EXPERIMENTAL ON CACHE BOOL "" FORCE) +set(SECP256K1_ENABLE_MODULE_BATCH ON CACHE BOOL "" FORCE) set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE) set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE) @@ -133,6 +135,7 @@ endif() add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL addresstype.cpp base58.cpp + batchverify.cpp bech32.cpp chain.cpp chainparams.cpp diff --git a/src/batchverify.cpp b/src/batchverify.cpp new file mode 100644 index 00000000000..4c4ae27ccc1 --- /dev/null +++ b/src/batchverify.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2024 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 +#include +#include + +// This is the maximum number of scalar-point pairs on the batch for which +// Strauss' algorithm, which is used in the secp256k1 implementation, is +// still efficient. TODO: This will be changed when Pippenger algorithm is +// being used in the secp implementation too. +const size_t MAX_BATCH_SIZE{106}; + +BatchSchnorrVerifier::BatchSchnorrVerifier() { + unsigned char rnd[16]; + GetRandBytes(rnd); + secp256k1_batch* batch{secp256k1_batch_create(secp256k1_context_static, MAX_BATCH_SIZE, rnd)}; + m_batch = batch; +} + +BatchSchnorrVerifier::~BatchSchnorrVerifier() { + (void)secp256k1_batch_destroy(secp256k1_context_static, m_batch); +} + +bool BatchSchnorrVerifier::Add(const std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) { + LOCK(m_batch_mutex); + if (secp256k1_batch_usable(secp256k1_context_static, m_batch) == 0) { + return false; + } + + secp256k1_xonly_pubkey pubkey_parsed; + (void)secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey_parsed, pubkey.data()); + + return secp256k1_batch_add_schnorrsig(secp256k1_context_static, m_batch, sig.data(), sighash.begin(), 32, &pubkey_parsed); +} + +bool BatchSchnorrVerifier::Verify() { + LOCK(m_batch_mutex); + return secp256k1_batch_verify(secp256k1_context_static, m_batch); +} + +void BatchSchnorrVerifier::Reset() { + LOCK(m_batch_mutex); + (void)secp256k1_batch_destroy(secp256k1_context_static, m_batch); + unsigned char rnd[16]; + GetRandBytes(rnd); + secp256k1_batch* batch{secp256k1_batch_create(secp256k1_context_static, MAX_BATCH_SIZE, rnd)}; + m_batch = batch; +} diff --git a/src/batchverify.h b/src/batchverify.h new file mode 100644 index 00000000000..63cd301f470 --- /dev/null +++ b/src/batchverify.h @@ -0,0 +1,34 @@ +// Copyright (c) 2024 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_BATCHVERIFY_H +#define BITCOIN_BATCHVERIFY_H + +#include +#include + +#include +#include + +struct SchnorrSignatureToVerify { + std::vector sig; + XOnlyPubKey pubkey; + uint256 sighash; +}; + +class BatchSchnorrVerifier { +private: + secp256k1_batch* m_batch GUARDED_BY(m_batch_mutex); + mutable Mutex m_batch_mutex; + +public: + BatchSchnorrVerifier(); + ~BatchSchnorrVerifier(); + + bool Add(const std::span sig, const XOnlyPubKey& pubkey, const uint256& sighash) EXCLUSIVE_LOCKS_REQUIRED(!m_batch_mutex); + bool Verify() EXCLUSIVE_LOCKS_REQUIRED(!m_batch_mutex); + void Reset() EXCLUSIVE_LOCKS_REQUIRED(!m_batch_mutex); +}; + +#endif // BITCOIN_BATCHVERIFY_H diff --git a/src/checkqueue.h b/src/checkqueue.h index 934f672ae39..5f354035b28 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -5,16 +5,23 @@ #ifndef BITCOIN_CHECKQUEUE_H #define BITCOIN_CHECKQUEUE_H +#include #include #include #include +#include