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
200194bool 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
206200bool 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
214208static const HashWriter HASHER_TAPTWEAK{TaggedHash (" TapTweak" )};
@@ -227,23 +221,23 @@ uint256 XOnlyPubKey::ComputeTapTweakHash(const uint256* merkle_root) const
227221bool 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
235229std::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
271264bool 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
300291bool 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