16
16
#include < algorithm>
17
17
#include < cassert>
18
18
19
- namespace
20
- {
21
- /* Global secp256k1_context object used for verification. */
22
- secp256k1_context* secp256k1_context_verify = nullptr ;
23
- } // namespace
24
-
25
19
/* * This function is taken from the libsecp256k1 distribution and implements
26
20
* DER parsing for ECDSA signatures, while supporting an arbitrary subset of
27
21
* format violations.
@@ -32,15 +26,15 @@ secp256k1_context* secp256k1_context_verify = nullptr;
32
26
* strict DER before being passed to this module, and we know it supports all
33
27
* violations present in the blockchain before that point.
34
28
*/
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) {
36
30
size_t rpos, rlen, spos, slen;
37
31
size_t pos = 0 ;
38
32
size_t lenbyte;
39
33
unsigned char tmpsig[64 ] = {0 };
40
34
int overflow = 0 ;
41
35
42
36
/* 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);
44
38
45
39
/* Sequence tag byte */
46
40
if (pos == inputlen || input[pos] != 0x30 ) {
@@ -163,13 +157,13 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
163
157
}
164
158
165
159
if (!overflow) {
166
- overflow = !secp256k1_ecdsa_signature_parse_compact (ctx , sig, tmpsig);
160
+ overflow = !secp256k1_ecdsa_signature_parse_compact (secp256k1_context_static , sig, tmpsig);
167
161
}
168
162
if (overflow) {
169
163
/* Overwrite the result again with a correctly-parsed but invalid
170
164
signature if parsing failed. */
171
165
memset (tmpsig, 0 , 64 );
172
- secp256k1_ecdsa_signature_parse_compact (ctx , sig, tmpsig);
166
+ secp256k1_ecdsa_signature_parse_compact (secp256k1_context_static , sig, tmpsig);
173
167
}
174
168
return 1 ;
175
169
}
@@ -200,15 +194,15 @@ std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
200
194
bool XOnlyPubKey::IsFullyValid () const
201
195
{
202
196
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 ());
204
198
}
205
199
206
200
bool XOnlyPubKey::VerifySchnorr (const uint256& msg, Span<const unsigned char > sigbytes) const
207
201
{
208
202
assert (sigbytes.size () == 64 );
209
203
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);
212
206
}
213
207
214
208
static const HashWriter HASHER_TAPTWEAK{TaggedHash (" TapTweak" )};
@@ -227,23 +221,23 @@ uint256 XOnlyPubKey::ComputeTapTweakHash(const uint256* merkle_root) const
227
221
bool XOnlyPubKey::CheckTapTweak (const XOnlyPubKey& internal, const uint256& merkle_root, bool parity) const
228
222
{
229
223
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 ;
231
225
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 ());
233
227
}
234
228
235
229
std::optional<std::pair<XOnlyPubKey, bool >> XOnlyPubKey::CreateTapTweak (const uint256* merkle_root) const
236
230
{
237
231
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;
239
233
secp256k1_pubkey out;
240
234
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;
242
236
int parity = -1 ;
243
237
std::pair<XOnlyPubKey, bool > ret;
244
238
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);
247
241
assert (parity == 0 || parity == 1 );
248
242
ret.second = parity;
249
243
return ret;
@@ -255,17 +249,16 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
255
249
return false ;
256
250
secp256k1_pubkey pubkey;
257
251
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 ())) {
260
253
return false ;
261
254
}
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 ())) {
263
256
return false ;
264
257
}
265
258
/* libsecp256k1's ECDSA verification requires lower-S signatures, which have
266
259
* 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);
269
262
}
270
263
271
264
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
275
268
bool fComp = ((vchSig[0 ] - 27 ) & 4 ) != 0 ;
276
269
secp256k1_pubkey pubkey;
277
270
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)) {
280
272
return false ;
281
273
}
282
- if (!secp256k1_ecdsa_recover (secp256k1_context_verify , &pubkey, &sig, hash.begin ())) {
274
+ if (!secp256k1_ecdsa_recover (secp256k1_context_static , &pubkey, &sig, hash.begin ())) {
283
275
return false ;
284
276
}
285
277
unsigned char pub[SIZE];
286
278
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);
288
280
Set (pub, pub + publen);
289
281
return true ;
290
282
}
@@ -293,21 +285,19 @@ bool CPubKey::IsFullyValid() const {
293
285
if (!IsValid ())
294
286
return false ;
295
287
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 ());
298
289
}
299
290
300
291
bool CPubKey::Decompress () {
301
292
if (!IsValid ())
302
293
return false ;
303
294
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 ())) {
306
296
return false ;
307
297
}
308
298
unsigned char pub[SIZE];
309
299
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);
311
301
Set (pub, pub + publen);
312
302
return true ;
313
303
}
@@ -320,16 +310,15 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
320
310
BIP32Hash (cc, nChild, *begin (), begin ()+1 , out);
321
311
memcpy (ccChild.begin (), out+32 , 32 );
322
312
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 ())) {
325
314
return false ;
326
315
}
327
- if (!secp256k1_ec_pubkey_tweak_add (secp256k1_context_verify , &pubkey, out)) {
316
+ if (!secp256k1_ec_pubkey_tweak_add (secp256k1_context_static , &pubkey, out)) {
328
317
return false ;
329
318
}
330
319
unsigned char pub[COMPRESSED_SIZE];
331
320
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);
333
322
pubkeyChild.Set (pub, pub + publen);
334
323
return true ;
335
324
}
@@ -375,35 +364,8 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
375
364
376
365
/* static */ bool CPubKey::CheckLowS (const std::vector<unsigned char >& vchSig) {
377
366
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 ())) {
380
368
return false ;
381
369
}
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));
409
371
}
0 commit comments