Skip to content

Commit 4462cb0

Browse files
committed
Adapt to libsecp256k1 API changes
* Use SECP256K1_CONTEXT_NONE when creating signing context, as SECP256K1_CONTEXT_SIGN is deprecated and unnecessary. * Use secp256k1_static_context where applicable.
1 parent 3d8a6ae commit 4462cb0

29 files changed

+44
-166
lines changed

src/bench/ccoins_caching.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
1919
static void CCoinsCaching(benchmark::Bench& bench)
2020
{
21-
const ECCVerifyHandle verify_handle;
2221
ECC_Start();
2322

2423
FillableSigningProvider keystore;

src/bench/checkqueue.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ static void CCheckQueueSpeedPrevectorJob(benchmark::Bench& bench)
2525
// We shouldn't ever be running with the checkqueue on a single core machine.
2626
if (GetNumCores() <= 1) return;
2727

28-
const ECCVerifyHandle verify_handle;
2928
ECC_Start();
3029

3130
struct PrevectorJob {

src/bench/descriptors.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
static void ExpandDescriptor(benchmark::Bench& bench)
1515
{
16-
const ECCVerifyHandle verify_handle;
1716
ECC_Start();
1817

1918
const auto desc_str = "sh(wsh(multi(16,03669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600,0362a74e399c39ed5593852a30147f2959b56bb827dfa3e60e464b02ccf87dc5e8,0261345b53de74a4d721ef877c255429961b7e43714171ac06168d7e08c542a8b8,02da72e8b46901a65d4374fe6315538d8f368557dda3a1dcf9ea903f3afe7314c8,0318c82dd0b53fd3a932d16e0ba9e278fcc937c582d5781be626ff16e201f72286,0297ccef1ef99f9d73dec9ad37476ddb232f1238aff877af19e72ba04493361009,02e502cfd5c3f972fe9a3e2a18827820638f96b6f347e54d63deb839011fd5765d,03e687710f0e3ebe81c1037074da939d409c0025f17eb86adb9427d28f0f7ae0e9,02c04d3a5274952acdbc76987f3184b346a483d43be40874624b29e3692c1df5af,02ed06e0f418b5b43a7ec01d1d7d27290fa15f75771cb69b642a51471c29c84acd,036d46073cbb9ffee90473f3da429abc8de7f8751199da44485682a989a4bebb24,02f5d1ff7c9029a80a4e36b9a5497027ef7f3e73384a4a94fbfe7c4e9164eec8bc,02e41deffd1b7cce11cde209a781adcffdabd1b91c0ba0375857a2bfd9302419f3,02d76625f7956a7fc505ab02556c23ee72d832f1bac391bcd2d3abce5710a13d06,0399eb0a5487515802dc14544cf10b3666623762fbed2ec38a3975716e2c29c232)))";

src/bench/verify_script.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
// modified to measure performance of other types of scripts.
1919
static void VerifyScriptBench(benchmark::Bench& bench)
2020
{
21-
const ECCVerifyHandle verify_handle;
2221
ECC_Start();
2322

2423
const uint32_t flags{SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH};

src/bitcoin-tx.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,6 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
681681

682682
class Secp256k1Init
683683
{
684-
ECCVerifyHandle globalVerifyHandle;
685-
686684
public:
687685
Secp256k1Init() {
688686
ECC_Start();

src/bitcoin-wallet.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ MAIN_FUNCTION
130130
return EXIT_FAILURE;
131131
}
132132

133-
ECCVerifyHandle globalVerifyHandle;
134133
ECC_Start();
135134
if (!wallet::WalletTool::ExecuteWalletToolFunc(args, command->command)) {
136135
return EXIT_FAILURE;

src/kernel/context.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ Context::Context()
2121
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
2222
RandomInit();
2323
ECC_Start();
24-
ecc_verify_handle.reset(new ECCVerifyHandle());
2524
}
2625

2726
Context::~Context()
2827
{
29-
ecc_verify_handle.reset();
3028
ECC_Stop();
3129
}
3230

src/kernel/context.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
#include <memory>
99

10-
class ECCVerifyHandle;
11-
1210
namespace kernel {
1311
//! Context struct holding the kernel library's logically global state, and
1412
//! passed to external libbitcoin_kernel functions which need access to this
@@ -18,8 +16,6 @@ namespace kernel {
1816
//! State stored directly in this struct should be simple. More complex state
1917
//! should be stored to std::unique_ptr members pointing to opaque types.
2018
struct Context {
21-
std::unique_ptr<ECCVerifyHandle> ecc_verify_handle;
22-
2319
//! Declare default constructor and destructor that are not inline, so code
2420
//! instantiating the kernel::Context struct doesn't need to #include class
2521
//! definitions for all the unique_ptr members.

src/key.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool gr
233233
secp256k1_pubkey pk;
234234
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, begin());
235235
assert(ret);
236-
ret = secp256k1_ecdsa_verify(GetVerifyContext(), &sig, hash.begin(), &pk);
236+
ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk);
237237
assert(ret);
238238
return true;
239239
}
@@ -268,9 +268,9 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
268268
secp256k1_pubkey epk, rpk;
269269
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, begin());
270270
assert(ret);
271-
ret = secp256k1_ecdsa_recover(GetVerifyContext(), &rpk, &rsig, hash.begin());
271+
ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin());
272272
assert(ret);
273-
ret = secp256k1_ec_pubkey_cmp(GetVerifyContext(), &epk, &rpk);
273+
ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk);
274274
assert(ret == 0);
275275
return true;
276276
}
@@ -286,14 +286,14 @@ bool CKey::SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint2
286286
unsigned char pubkey_bytes[32];
287287
if (!secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, pubkey_bytes, &pubkey)) return false;
288288
uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root);
289-
if (!secp256k1_keypair_xonly_tweak_add(GetVerifyContext(), &keypair, tweak.data())) return false;
289+
if (!secp256k1_keypair_xonly_tweak_add(secp256k1_context_static, &keypair, tweak.data())) return false;
290290
}
291291
bool ret = secp256k1_schnorrsig_sign32(secp256k1_context_sign, sig.data(), hash.data(), &keypair, aux.data());
292292
if (ret) {
293293
// Additional verification step to prevent using a potentially corrupted signature
294294
secp256k1_xonly_pubkey pubkey_verify;
295-
ret = secp256k1_keypair_xonly_pub(GetVerifyContext(), &pubkey_verify, nullptr, &keypair);
296-
ret &= secp256k1_schnorrsig_verify(GetVerifyContext(), sig.data(), hash.begin(), 32, &pubkey_verify);
295+
ret = secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey_verify, nullptr, &keypair);
296+
ret &= secp256k1_schnorrsig_verify(secp256k1_context_static, sig.data(), hash.begin(), 32, &pubkey_verify);
297297
}
298298
if (!ret) memory_cleanse(sig.data(), sig.size());
299299
memory_cleanse(&keypair, sizeof(keypair));
@@ -392,7 +392,7 @@ bool ECC_InitSanityCheck() {
392392
void ECC_Start() {
393393
assert(secp256k1_context_sign == nullptr);
394394

395-
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
395+
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
396396
assert(ctx != nullptr);
397397

398398
{

src/pubkey.cpp

Lines changed: 28 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
#include <algorithm>
1717
#include <cassert>
1818

19-
namespace
20-
{
21-
/* Global secp256k1_context object used for verification. */
22-
secp256k1_context* secp256k1_context_verify = nullptr;
23-
} // namespace
24-
2519
/** This function is taken from the libsecp256k1 distribution and implements
2620
* DER parsing for ECDSA signatures, while supporting an arbitrary subset of
2721
* format violations.
@@ -32,15 +26,15 @@ secp256k1_context* secp256k1_context_verify = nullptr;
3226
* strict DER before being passed to this module, and we know it supports all
3327
* violations present in the blockchain before that point.
3428
*/
35-
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
29+
int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
3630
size_t rpos, rlen, spos, slen;
3731
size_t pos = 0;
3832
size_t lenbyte;
3933
unsigned char tmpsig[64] = {0};
4034
int overflow = 0;
4135

4236
/* Hack to initialize sig with a correctly-parsed but invalid signature. */
43-
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
37+
secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
4438

4539
/* Sequence tag byte */
4640
if (pos == inputlen || input[pos] != 0x30) {
@@ -163,13 +157,13 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
163157
}
164158

165159
if (!overflow) {
166-
overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
160+
overflow = !secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
167161
}
168162
if (overflow) {
169163
/* Overwrite the result again with a correctly-parsed but invalid
170164
signature if parsing failed. */
171165
memset(tmpsig, 0, 64);
172-
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
166+
secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
173167
}
174168
return 1;
175169
}
@@ -200,15 +194,15 @@ std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
200194
bool XOnlyPubKey::IsFullyValid() const
201195
{
202196
secp256k1_xonly_pubkey pubkey;
203-
return secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &pubkey, m_keydata.data());
197+
return secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data());
204198
}
205199

206200
bool XOnlyPubKey::VerifySchnorr(const uint256& msg, Span<const unsigned char> sigbytes) const
207201
{
208202
assert(sigbytes.size() == 64);
209203
secp256k1_xonly_pubkey pubkey;
210-
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &pubkey, m_keydata.data())) return false;
211-
return secp256k1_schnorrsig_verify(secp256k1_context_verify, sigbytes.data(), msg.begin(), 32, &pubkey);
204+
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &pubkey, m_keydata.data())) return false;
205+
return secp256k1_schnorrsig_verify(secp256k1_context_static, sigbytes.data(), msg.begin(), 32, &pubkey);
212206
}
213207

214208
static const HashWriter HASHER_TAPTWEAK{TaggedHash("TapTweak")};
@@ -227,23 +221,23 @@ uint256 XOnlyPubKey::ComputeTapTweakHash(const uint256* merkle_root) const
227221
bool XOnlyPubKey::CheckTapTweak(const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const
228222
{
229223
secp256k1_xonly_pubkey internal_key;
230-
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &internal_key, internal.data())) return false;
224+
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &internal_key, internal.data())) return false;
231225
uint256 tweak = internal.ComputeTapTweakHash(&merkle_root);
232-
return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_verify, m_keydata.begin(), parity, &internal_key, tweak.begin());
226+
return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_static, m_keydata.begin(), parity, &internal_key, tweak.begin());
233227
}
234228

235229
std::optional<std::pair<XOnlyPubKey, bool>> XOnlyPubKey::CreateTapTweak(const uint256* merkle_root) const
236230
{
237231
secp256k1_xonly_pubkey base_point;
238-
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &base_point, data())) return std::nullopt;
232+
if (!secp256k1_xonly_pubkey_parse(secp256k1_context_static, &base_point, data())) return std::nullopt;
239233
secp256k1_pubkey out;
240234
uint256 tweak = ComputeTapTweakHash(merkle_root);
241-
if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_verify, &out, &base_point, tweak.data())) return std::nullopt;
235+
if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_static, &out, &base_point, tweak.data())) return std::nullopt;
242236
int parity = -1;
243237
std::pair<XOnlyPubKey, bool> ret;
244238
secp256k1_xonly_pubkey out_xonly;
245-
if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_verify, &out_xonly, &parity, &out)) return std::nullopt;
246-
secp256k1_xonly_pubkey_serialize(secp256k1_context_verify, ret.first.begin(), &out_xonly);
239+
if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_static, &out_xonly, &parity, &out)) return std::nullopt;
240+
secp256k1_xonly_pubkey_serialize(secp256k1_context_static, ret.first.begin(), &out_xonly);
247241
assert(parity == 0 || parity == 1);
248242
ret.second = parity;
249243
return ret;
@@ -255,17 +249,16 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
255249
return false;
256250
secp256k1_pubkey pubkey;
257251
secp256k1_ecdsa_signature sig;
258-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
259-
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
252+
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
260253
return false;
261254
}
262-
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
255+
if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
263256
return false;
264257
}
265258
/* libsecp256k1's ECDSA verification requires lower-S signatures, which have
266259
* not historically been enforced in Bitcoin, so normalize them first. */
267-
secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
268-
return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
260+
secp256k1_ecdsa_signature_normalize(secp256k1_context_static, &sig, &sig);
261+
return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
269262
}
270263

271264
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
@@ -275,16 +268,15 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
275268
bool fComp = ((vchSig[0] - 27) & 4) != 0;
276269
secp256k1_pubkey pubkey;
277270
secp256k1_ecdsa_recoverable_signature sig;
278-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
279-
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
271+
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &sig, &vchSig[1], recid)) {
280272
return false;
281273
}
282-
if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
274+
if (!secp256k1_ecdsa_recover(secp256k1_context_static, &pubkey, &sig, hash.begin())) {
283275
return false;
284276
}
285277
unsigned char pub[SIZE];
286278
size_t publen = SIZE;
287-
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
279+
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
288280
Set(pub, pub + publen);
289281
return true;
290282
}
@@ -293,21 +285,19 @@ bool CPubKey::IsFullyValid() const {
293285
if (!IsValid())
294286
return false;
295287
secp256k1_pubkey pubkey;
296-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
297-
return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
288+
return secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size());
298289
}
299290

300291
bool CPubKey::Decompress() {
301292
if (!IsValid())
302293
return false;
303294
secp256k1_pubkey pubkey;
304-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
305-
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
295+
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
306296
return false;
307297
}
308298
unsigned char pub[SIZE];
309299
size_t publen = SIZE;
310-
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
300+
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
311301
Set(pub, pub + publen);
312302
return true;
313303
}
@@ -320,16 +310,15 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
320310
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
321311
memcpy(ccChild.begin(), out+32, 32);
322312
secp256k1_pubkey pubkey;
323-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
324-
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
313+
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
325314
return false;
326315
}
327-
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
316+
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_static, &pubkey, out)) {
328317
return false;
329318
}
330319
unsigned char pub[COMPRESSED_SIZE];
331320
size_t publen = COMPRESSED_SIZE;
332-
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
321+
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
333322
pubkeyChild.Set(pub, pub + publen);
334323
return true;
335324
}
@@ -375,35 +364,8 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
375364

376365
/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
377366
secp256k1_ecdsa_signature sig;
378-
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
379-
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
367+
if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
380368
return false;
381369
}
382-
return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
383-
}
384-
385-
/* static */ int ECCVerifyHandle::refcount = 0;
386-
387-
ECCVerifyHandle::ECCVerifyHandle()
388-
{
389-
if (refcount == 0) {
390-
assert(secp256k1_context_verify == nullptr);
391-
secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
392-
assert(secp256k1_context_verify != nullptr);
393-
}
394-
refcount++;
395-
}
396-
397-
ECCVerifyHandle::~ECCVerifyHandle()
398-
{
399-
refcount--;
400-
if (refcount == 0) {
401-
assert(secp256k1_context_verify != nullptr);
402-
secp256k1_context_destroy(secp256k1_context_verify);
403-
secp256k1_context_verify = nullptr;
404-
}
405-
}
406-
407-
const secp256k1_context* GetVerifyContext() {
408-
return secp256k1_context_verify;
370+
return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_static, nullptr, &sig));
409371
}

0 commit comments

Comments
 (0)