9
9
#include < secp256k1_extrakeys.h>
10
10
#include < secp256k1_recovery.h>
11
11
12
- namespace
12
+ namespace {
13
+
14
+ struct Secp256k1SelfTester
13
15
{
14
- /* Global secp256k1_context object used for verification. */
15
- secp256k1_context* secp256k1_context_verify = nullptr ;
16
+ Secp256k1SelfTester () {
17
+ /* Run libsecp256k1 self-test before using the secp256k1_context_static. */
18
+ secp256k1_selftest ();
19
+ }
20
+ } SECP256K1_SELFTESTER;
21
+
16
22
} // namespace
17
23
18
24
/* * This function is taken from the libsecp256k1 distribution and implements
@@ -25,15 +31,15 @@ secp256k1_context* secp256k1_context_verify = nullptr;
25
31
* strict DER before being passed to this module, and we know it supports all
26
32
* violations present in the blockchain before that point.
27
33
*/
28
- int ecdsa_signature_parse_der_lax (const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
34
+ int ecdsa_signature_parse_der_lax (secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
29
35
size_t rpos, rlen, spos, slen;
30
36
size_t pos = 0 ;
31
37
size_t lenbyte;
32
38
unsigned char tmpsig[64 ] = {0 };
33
39
int overflow = 0 ;
34
40
35
41
/* Hack to initialize sig with a correctly-parsed but invalid signature. */
36
- secp256k1_ecdsa_signature_parse_compact (ctx , sig, tmpsig);
42
+ secp256k1_ecdsa_signature_parse_compact (secp256k1_context_static , sig, tmpsig);
37
43
38
44
/* Sequence tag byte */
39
45
if (pos == inputlen || input[pos] != 0x30 ) {
@@ -156,13 +162,13 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
156
162
}
157
163
158
164
if (!overflow) {
159
- overflow = !secp256k1_ecdsa_signature_parse_compact (ctx , sig, tmpsig);
165
+ overflow = !secp256k1_ecdsa_signature_parse_compact (secp256k1_context_static , sig, tmpsig);
160
166
}
161
167
if (overflow) {
162
168
/* Overwrite the result again with a correctly-parsed but invalid
163
169
signature if parsing failed. */
164
170
memset (tmpsig, 0 , 64 );
165
- secp256k1_ecdsa_signature_parse_compact (ctx , sig, tmpsig);
171
+ secp256k1_ecdsa_signature_parse_compact (secp256k1_context_static , sig, tmpsig);
166
172
}
167
173
return 1 ;
168
174
}
@@ -172,18 +178,17 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
172
178
return false ;
173
179
secp256k1_pubkey pubkey;
174
180
secp256k1_ecdsa_signature sig;
175
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
176
- if (!secp256k1_ec_pubkey_parse (secp256k1_context_verify, &pubkey, vch, size ())) {
181
+ if (!secp256k1_ec_pubkey_parse (secp256k1_context_static, &pubkey, vch, size ())) {
177
182
return false ;
178
183
}
179
- if (!ecdsa_signature_parse_der_lax (secp256k1_context_verify, &sig, vchSig.data (), vchSig.size ())) {
184
+ if (!ecdsa_signature_parse_der_lax (&sig, vchSig.data (), vchSig.size ())) {
180
185
return false ;
181
186
}
182
187
/* libsecp256k1's ECDSA verification requires lower-S signatures, which have
183
188
* not historically been enforced in Bitcoin, so normalize them first. */
184
189
// This however is not the case with Gridcoin.
185
- // secp256k1_ecdsa_signature_normalize(secp256k1_context_verify , &sig, &sig);
186
- return secp256k1_ecdsa_verify (secp256k1_context_verify , &sig, hash.begin (), &pubkey);
190
+ // secp256k1_ecdsa_signature_normalize(secp256k1_context_static , &sig, &sig);
191
+ return secp256k1_ecdsa_verify (secp256k1_context_static , &sig, hash.begin (), &pubkey);
187
192
}
188
193
189
194
bool CPubKey::RecoverCompact (const uint256 &hash, const std::vector<unsigned char >& vchSig) {
@@ -193,16 +198,15 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
193
198
bool fComp = ((vchSig[0 ] - 27 ) & 4 ) != 0 ;
194
199
secp256k1_pubkey pubkey;
195
200
secp256k1_ecdsa_recoverable_signature sig;
196
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
197
- if (!secp256k1_ecdsa_recoverable_signature_parse_compact (secp256k1_context_verify, &sig, &vchSig[1 ], recid)) {
201
+ if (!secp256k1_ecdsa_recoverable_signature_parse_compact (secp256k1_context_static, &sig, &vchSig[1 ], recid)) {
198
202
return false ;
199
203
}
200
- if (!secp256k1_ecdsa_recover (secp256k1_context_verify , &pubkey, &sig, hash.begin ())) {
204
+ if (!secp256k1_ecdsa_recover (secp256k1_context_static , &pubkey, &sig, hash.begin ())) {
201
205
return false ;
202
206
}
203
207
unsigned char pub[SIZE];
204
208
size_t publen = SIZE;
205
- secp256k1_ec_pubkey_serialize (secp256k1_context_verify , pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
209
+ secp256k1_ec_pubkey_serialize (secp256k1_context_static , pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
206
210
Set (pub, pub + publen);
207
211
return true ;
208
212
}
@@ -211,21 +215,19 @@ bool CPubKey::IsFullyValid() const {
211
215
if (!IsValid ())
212
216
return false ;
213
217
secp256k1_pubkey pubkey;
214
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
215
- return secp256k1_ec_pubkey_parse (secp256k1_context_verify, &pubkey, vch, size ());
218
+ return secp256k1_ec_pubkey_parse (secp256k1_context_static, &pubkey, vch, size ());
216
219
}
217
220
218
221
bool CPubKey::Decompress () {
219
222
if (!IsValid ())
220
223
return false ;
221
224
secp256k1_pubkey pubkey;
222
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
223
- if (!secp256k1_ec_pubkey_parse (secp256k1_context_verify, &pubkey, vch, size ())) {
225
+ if (!secp256k1_ec_pubkey_parse (secp256k1_context_static, &pubkey, vch, size ())) {
224
226
return false ;
225
227
}
226
228
unsigned char pub[SIZE];
227
229
size_t publen = SIZE;
228
- secp256k1_ec_pubkey_serialize (secp256k1_context_verify , pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
230
+ secp256k1_ec_pubkey_serialize (secp256k1_context_static , pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
229
231
Set (pub, pub + publen);
230
232
return true ;
231
233
}
@@ -238,16 +240,15 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
238
240
BIP32Hash (cc, nChild, *begin (), begin ()+1 , out);
239
241
memcpy (ccChild.begin (), out+32 , 32 );
240
242
secp256k1_pubkey pubkey;
241
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
242
- if (!secp256k1_ec_pubkey_parse (secp256k1_context_verify, &pubkey, vch, size ())) {
243
+ if (!secp256k1_ec_pubkey_parse (secp256k1_context_static, &pubkey, vch, size ())) {
243
244
return false ;
244
245
}
245
- if (!secp256k1_ec_pubkey_tweak_add (secp256k1_context_verify , &pubkey, out)) {
246
+ if (!secp256k1_ec_pubkey_tweak_add (secp256k1_context_static , &pubkey, out)) {
246
247
return false ;
247
248
}
248
249
unsigned char pub[COMPRESSED_SIZE];
249
250
size_t publen = COMPRESSED_SIZE;
250
- secp256k1_ec_pubkey_serialize (secp256k1_context_verify , pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
251
+ secp256k1_ec_pubkey_serialize (secp256k1_context_static , pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
251
252
pubkeyChild.Set (pub, pub + publen);
252
253
return true ;
253
254
}
@@ -292,35 +293,8 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
292
293
293
294
/* static */ bool CPubKey::CheckLowS (const std::vector<unsigned char >& vchSig) {
294
295
secp256k1_ecdsa_signature sig;
295
- assert (secp256k1_context_verify && " secp256k1_context_verify must be initialized to use CPubKey." );
296
- if (!ecdsa_signature_parse_der_lax (secp256k1_context_verify, &sig, vchSig.data (), vchSig.size ())) {
296
+ if (!ecdsa_signature_parse_der_lax (&sig, vchSig.data (), vchSig.size ())) {
297
297
return false ;
298
298
}
299
- return (!secp256k1_ecdsa_signature_normalize (secp256k1_context_verify, nullptr , &sig));
300
- }
301
-
302
- /* static */ int ECCVerifyHandle::refcount = 0 ;
303
-
304
- ECCVerifyHandle::ECCVerifyHandle ()
305
- {
306
- if (refcount == 0 ) {
307
- assert (secp256k1_context_verify == nullptr );
308
- secp256k1_context_verify = secp256k1_context_create (SECP256K1_CONTEXT_VERIFY);
309
- assert (secp256k1_context_verify != nullptr );
310
- }
311
- refcount++;
312
- }
313
-
314
- ECCVerifyHandle::~ECCVerifyHandle ()
315
- {
316
- refcount--;
317
- if (refcount == 0 ) {
318
- assert (secp256k1_context_verify != nullptr );
319
- secp256k1_context_destroy (secp256k1_context_verify);
320
- secp256k1_context_verify = nullptr ;
321
- }
322
- }
323
-
324
- const secp256k1_context* GetVerifyContext () {
325
- return secp256k1_context_verify;
299
+ return (!secp256k1_ecdsa_signature_normalize (secp256k1_context_static, nullptr , &sig));
326
300
}
0 commit comments