From 0a5e6128680c8b4f43fcb2d0450d41d5e4603c9d Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Sun, 25 Feb 2024 21:02:17 +0100 Subject: [PATCH] BatchVerify: Add basic schnorr sig batch verification in ConnectBlock() --- src/Makefile.am | 2 ++ src/batchverify.cpp | 46 ++++++++++++++++++++++++++++ src/batchverify.h | 26 ++++++++++++++++ src/script/sigcache.cpp | 15 +++++++++ src/script/sigcache.h | 15 +++++++++ src/test/txvalidationcache_tests.cpp | 3 +- src/validation.cpp | 25 ++++++++++++--- src/validation.h | 6 ++-- 8 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 src/batchverify.cpp create mode 100644 src/batchverify.h diff --git a/src/Makefile.am b/src/Makefile.am index 3e8870c8286684..8a7f56cf011b5b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -128,6 +128,7 @@ BITCOIN_CORE_H = \ attributes.h \ banman.h \ base58.h \ + batchverify.h \ bech32.h \ bip324.h \ blockencodings.h \ @@ -678,6 +679,7 @@ libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ addresstype.cpp \ base58.cpp \ + batchverify.cpp \ bech32.cpp \ chainparams.cpp \ coins.cpp \ diff --git a/src/batchverify.cpp b/src/batchverify.cpp new file mode 100644 index 00000000000000..ca79cb0726346e --- /dev/null +++ b/src/batchverify.cpp @@ -0,0 +1,46 @@ +// 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 + +BatchSchnorrVerifier::BatchSchnorrVerifier() { + unsigned char rnd[16]; + GetRandBytes(rnd); + // 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. + const size_t max_batch_size{106}; + 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 Span sig, const XOnlyPubKey& pubkey, const uint256& sighash) { + LOCK(m_batch_mutex); + if (secp256k1_batch_usable(secp256k1_context_static, m_batch) == 0) { + LogPrintf("ERROR: BatchSchnorrVerifier m_batch unusable\n"); + 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); +} diff --git a/src/batchverify.h b/src/batchverify.h new file mode 100644 index 00000000000000..dc69130cfd2177 --- /dev/null +++ b/src/batchverify.h @@ -0,0 +1,26 @@ +// 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 + +class BatchSchnorrVerifier { +private: + secp256k1_batch* m_batch GUARDED_BY(m_batch_mutex); + mutable Mutex m_batch_mutex; + +public: + BatchSchnorrVerifier(); + ~BatchSchnorrVerifier(); + + bool Add(const Span sig, const XOnlyPubKey& pubkey, const uint256& sighash) EXCLUSIVE_LOCKS_REQUIRED(!m_batch_mutex); + bool Verify() EXCLUSIVE_LOCKS_REQUIRED(!m_batch_mutex); +}; + +#endif // BITCOIN_BATCHVERIFY_H diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 7c6c282cc470d6..2a21a78e475aea 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -5,6 +5,7 @@ #include