Skip to content

Commit 1ff9e92

Browse files
committed
key: use static context for libsecp256k1 calls where applicable
The dynamically created signing context for libsecp256k1 calls is only needed for functions that involve generator point multiplication with a secret key, i.e. different variants of public key creation and signing. The API docs hint to this by stating "not secp256k1_context_static" for the context parameter. In our case that applies to the following calls: - `secp256k1_ec_pubkey_create` - `secp256k1_keypair_create` - `secp256k1_ellswift_create` - `secp256k1_ecdsa_sign` - `secp256k1_ecdsa_sign_recoverable` - `secp256k1_schnorrsig_sign32` - `ec_seckey_export_der` (not a direct secp256k1 function, but calls `secp256k1_ec_pubkey_create` inside) For all the other secp256k1 calls we can simply use the static context.
1 parent 2d6a0c4 commit 1ff9e92

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

src/key.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ int ec_seckey_export_der(const secp256k1_context *ctx, unsigned char *seckey, si
155155
}
156156

157157
bool CKey::Check(const unsigned char *vch) {
158-
return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch);
158+
return secp256k1_ec_seckey_verify(secp256k1_context_static, vch);
159159
}
160160

161161
void CKey::MakeNewKey(bool fCompressedIn) {
@@ -186,7 +186,7 @@ CPubKey CKey::GetPubKey() const {
186186
CPubKey result;
187187
int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, UCharCast(begin()));
188188
assert(ret);
189-
secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
189+
secp256k1_ec_pubkey_serialize(secp256k1_context_static, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
190190
assert(result.size() == clen);
191191
assert(result.IsValid());
192192
return result;
@@ -196,7 +196,7 @@ CPubKey CKey::GetPubKey() const {
196196
bool SigHasLowR(const secp256k1_ecdsa_signature* sig)
197197
{
198198
unsigned char compact_sig[64];
199-
secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_sign, compact_sig, sig);
199+
secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_static, compact_sig, sig);
200200

201201
// In DER serialization, all values are interpreted as big-endian, signed integers. The highest bit in the integer indicates
202202
// its signed-ness; 0 is positive, 1 is negative. When the value is interpreted as a negative integer, it must be converted
@@ -222,7 +222,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool gr
222222
ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, extra_entropy);
223223
}
224224
assert(ret);
225-
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, vchSig.data(), &nSigLen, &sig);
225+
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_static, vchSig.data(), &nSigLen, &sig);
226226
vchSig.resize(nSigLen);
227227
// Additional verification step to prevent using a potentially corrupted signature
228228
secp256k1_pubkey pk;
@@ -254,7 +254,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
254254
secp256k1_ecdsa_recoverable_signature rsig;
255255
int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &rsig, hash.begin(), UCharCast(begin()), secp256k1_nonce_function_rfc6979, nullptr);
256256
assert(ret);
257-
ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, &vchSig[1], &rec, &rsig);
257+
ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_static, &vchSig[1], &rec, &rsig);
258258
assert(ret);
259259
assert(rec != -1);
260260
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
@@ -277,7 +277,7 @@ bool CKey::SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const
277277

278278
bool CKey::Load(const CPrivKey &seckey, const CPubKey &vchPubKey, bool fSkipCheck=false) {
279279
MakeKeyData();
280-
if (!ec_seckey_import_der(secp256k1_context_sign, (unsigned char*)begin(), seckey.data(), seckey.size())) {
280+
if (!ec_seckey_import_der(secp256k1_context_static, (unsigned char*)begin(), seckey.data(), seckey.size())) {
281281
ClearKeyData();
282282
return false;
283283
}
@@ -303,7 +303,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
303303
}
304304
memcpy(ccChild.begin(), vout.data()+32, 32);
305305
keyChild.Set(begin(), begin() + 32, true);
306-
bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_sign, (unsigned char*)keyChild.begin(), vout.data());
306+
bool ret = secp256k1_ec_seckey_tweak_add(secp256k1_context_static, (unsigned char*)keyChild.begin(), vout.data());
307307
if (!ret) keyChild.ClearKeyData();
308308
return ret;
309309
}
@@ -331,7 +331,7 @@ ECDHSecret CKey::ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, c
331331
ECDHSecret output;
332332
// BIP324 uses the initiator as party A, and the responder as party B. Remap the inputs
333333
// accordingly:
334-
bool success = secp256k1_ellswift_xdh(secp256k1_context_sign,
334+
bool success = secp256k1_ellswift_xdh(secp256k1_context_static,
335335
UCharCast(output.data()),
336336
UCharCast(initiating ? our_ellswift.data() : their_ellswift.data()),
337337
UCharCast(initiating ? their_ellswift.data() : our_ellswift.data()),
@@ -415,8 +415,8 @@ KeyPair::KeyPair(const CKey& key, const uint256* merkle_root)
415415
if (success && merkle_root) {
416416
secp256k1_xonly_pubkey pubkey;
417417
unsigned char pubkey_bytes[32];
418-
assert(secp256k1_keypair_xonly_pub(secp256k1_context_sign, &pubkey, nullptr, keypair));
419-
assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, pubkey_bytes, &pubkey));
418+
assert(secp256k1_keypair_xonly_pub(secp256k1_context_static, &pubkey, nullptr, keypair));
419+
assert(secp256k1_xonly_pubkey_serialize(secp256k1_context_static, pubkey_bytes, &pubkey));
420420
uint256 tweak = XOnlyPubKey(pubkey_bytes).ComputeTapTweakHash(merkle_root->IsNull() ? nullptr : merkle_root);
421421
success = secp256k1_keypair_xonly_tweak_add(secp256k1_context_static, keypair, tweak.data());
422422
}

src/test/fuzz/secp256k1_ec_seckey_import_export_der.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@ int ec_seckey_export_der(const secp256k1_context* ctx, unsigned char* seckey, si
1717
FUZZ_TARGET(secp256k1_ec_seckey_import_export_der)
1818
{
1919
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
20-
secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
2120
{
2221
std::vector<uint8_t> out32(32);
23-
(void)ec_seckey_import_der(secp256k1_context_sign, out32.data(), ConsumeFixedLengthByteVector(fuzzed_data_provider, CKey::SIZE).data(), CKey::SIZE);
22+
(void)ec_seckey_import_der(secp256k1_context_static, out32.data(), ConsumeFixedLengthByteVector(fuzzed_data_provider, CKey::SIZE).data(), CKey::SIZE);
2423
}
2524
{
2625
std::vector<uint8_t> seckey(CKey::SIZE);
2726
const std::vector<uint8_t> key32 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 32);
2827
size_t seckeylen = CKey::SIZE;
2928
const bool compressed = fuzzed_data_provider.ConsumeBool();
29+
secp256k1_context* secp256k1_context_sign = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
3030
const bool exported = ec_seckey_export_der(secp256k1_context_sign, seckey.data(), &seckeylen, key32.data(), compressed);
31+
secp256k1_context_destroy(secp256k1_context_sign);
3132
if (exported) {
3233
std::vector<uint8_t> out32(32);
33-
const bool imported = ec_seckey_import_der(secp256k1_context_sign, out32.data(), seckey.data(), seckey.size()) == 1;
34+
const bool imported = ec_seckey_import_der(secp256k1_context_static, out32.data(), seckey.data(), seckey.size()) == 1;
3435
assert(imported && key32 == out32);
3536
}
3637
}
37-
secp256k1_context_destroy(secp256k1_context_sign);
3838
}

src/test/key_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,9 @@ BOOST_AUTO_TEST_CASE(key_schnorr_tweak_smoke_test)
376376
secp256k1_keypair keypair;
377377
BOOST_CHECK(secp256k1_keypair_create(secp256k1_context_sign, &keypair, UCharCast(key.begin())));
378378
secp256k1_xonly_pubkey xonly_pubkey;
379-
BOOST_CHECK(secp256k1_keypair_xonly_pub(secp256k1_context_sign, &xonly_pubkey, nullptr, &keypair));
379+
BOOST_CHECK(secp256k1_keypair_xonly_pub(secp256k1_context_static, &xonly_pubkey, nullptr, &keypair));
380380
unsigned char xonly_bytes[32];
381-
BOOST_CHECK(secp256k1_xonly_pubkey_serialize(secp256k1_context_sign, xonly_bytes, &xonly_pubkey));
381+
BOOST_CHECK(secp256k1_xonly_pubkey_serialize(secp256k1_context_static, xonly_bytes, &xonly_pubkey));
382382
uint256 tweak_old = XOnlyPubKey(xonly_bytes).ComputeTapTweakHash(&merkle_root);
383383

384384
// CPubKey

0 commit comments

Comments
 (0)