Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: update libsecp256k1 to v0.3.0 #2655

Merged
merged 5 commits into from
Mar 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
unset PKG_CONFIG_LIBDIR
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"

ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery"
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery --disable-module-ecdh"

ADDITIONAL_BDB_FLAGS=""

Expand Down
4 changes: 0 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ extern constexpr int DEFAULT_WAIT_CLIENT_TIMEOUT = 0;

std::unique_ptr<BanMan> g_banman;

static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;

/**
* The PID file facilities.
*/
Expand Down Expand Up @@ -165,7 +163,6 @@ void Shutdown(void* parg)
// This causes issues on daemons where it tries to create a second
// lock file.
//CTxDB().Close();
globalVerifyHandle.reset();
ECC_Stop();
UninterruptibleSleep(std::chrono::milliseconds{50});
LogPrintf("Gridcoin exited");
Expand Down Expand Up @@ -966,7 +963,6 @@ bool AppInit2(ThreadHandlerPtr threads)
LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
RandomInit();
ECC_Start();
globalVerifyHandle.reset(new ECCVerifyHandle());

// Sanity check
if (!InitSanityCheck())
Expand Down
8 changes: 4 additions & 4 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool gr
secp256k1_pubkey pk;
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pk, begin());
assert(ret);
ret = secp256k1_ecdsa_verify(GetVerifyContext(), &sig, hash.begin(), &pk);
ret = secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pk);
assert(ret);
return true;
}
Expand Down Expand Up @@ -274,9 +274,9 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
secp256k1_pubkey epk, rpk;
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, begin());
assert(ret);
ret = secp256k1_ecdsa_recover(GetVerifyContext(), &rpk, &rsig, hash.begin());
ret = secp256k1_ecdsa_recover(secp256k1_context_static, &rpk, &rsig, hash.begin());
assert(ret);
ret = secp256k1_ec_pubkey_cmp(GetVerifyContext(), &epk, &rpk);
ret = secp256k1_ec_pubkey_cmp(secp256k1_context_static, &epk, &rpk);
assert(ret == 0);
return true;
}
Expand Down Expand Up @@ -372,7 +372,7 @@ bool ECC_InitSanityCheck() {
void ECC_Start() {
assert(secp256k1_context_sign == nullptr);

secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
assert(ctx != nullptr);

{
Expand Down
82 changes: 28 additions & 54 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
#include <secp256k1_extrakeys.h>
#include <secp256k1_recovery.h>

namespace
namespace {

struct Secp256k1SelfTester
{
/* Global secp256k1_context object used for verification. */
secp256k1_context* secp256k1_context_verify = nullptr;
Secp256k1SelfTester() {
/* Run libsecp256k1 self-test before using the secp256k1_context_static. */
secp256k1_selftest();
}
} SECP256K1_SELFTESTER;

} // namespace

/** This function is taken from the libsecp256k1 distribution and implements
Expand All @@ -25,15 +31,15 @@ secp256k1_context* secp256k1_context_verify = nullptr;
* strict DER before being passed to this module, and we know it supports all
* violations present in the blockchain before that point.
*/
int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
size_t rpos, rlen, spos, slen;
size_t pos = 0;
size_t lenbyte;
unsigned char tmpsig[64] = {0};
int overflow = 0;

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

/* Sequence tag byte */
if (pos == inputlen || input[pos] != 0x30) {
Expand Down Expand Up @@ -156,13 +162,13 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
}

if (!overflow) {
overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
overflow = !secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
}
if (overflow) {
/* Overwrite the result again with a correctly-parsed but invalid
signature if parsing failed. */
memset(tmpsig, 0, 64);
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
}
return 1;
}
Expand All @@ -172,18 +178,17 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
return false;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_signature sig;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
return false;
}
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
return false;
}
/* libsecp256k1's ECDSA verification requires lower-S signatures, which have
* not historically been enforced in Bitcoin, so normalize them first. */
// This however is not the case with Gridcoin.
// secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
// secp256k1_ecdsa_signature_normalize(secp256k1_context_static, &sig, &sig);
return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
}

bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
Expand All @@ -193,16 +198,15 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
bool fComp = ((vchSig[0] - 27) & 4) != 0;
secp256k1_pubkey pubkey;
secp256k1_ecdsa_recoverable_signature sig;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &sig, &vchSig[1], recid)) {
return false;
}
if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
if (!secp256k1_ecdsa_recover(secp256k1_context_static, &pubkey, &sig, hash.begin())) {
return false;
}
unsigned char pub[SIZE];
size_t publen = SIZE;
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
Set(pub, pub + publen);
return true;
}
Expand All @@ -211,21 +215,19 @@ bool CPubKey::IsFullyValid() const {
if (!IsValid())
return false;
secp256k1_pubkey pubkey;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
return secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size());
}

bool CPubKey::Decompress() {
if (!IsValid())
return false;
secp256k1_pubkey pubkey;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
return false;
}
unsigned char pub[SIZE];
size_t publen = SIZE;
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
Set(pub, pub + publen);
return true;
}
Expand All @@ -238,16 +240,15 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild.begin(), out+32, 32);
secp256k1_pubkey pubkey;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
if (!secp256k1_ec_pubkey_parse(secp256k1_context_static, &pubkey, vch, size())) {
return false;
}
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_static, &pubkey, out)) {
return false;
}
unsigned char pub[COMPRESSED_SIZE];
size_t publen = COMPRESSED_SIZE;
secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
secp256k1_ec_pubkey_serialize(secp256k1_context_static, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
pubkeyChild.Set(pub, pub + publen);
return true;
}
Expand Down Expand Up @@ -292,35 +293,8 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {

/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
secp256k1_ecdsa_signature sig;
assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
if (!ecdsa_signature_parse_der_lax(&sig, vchSig.data(), vchSig.size())) {
return false;
}
return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
}

/* static */ int ECCVerifyHandle::refcount = 0;

ECCVerifyHandle::ECCVerifyHandle()
{
if (refcount == 0) {
assert(secp256k1_context_verify == nullptr);
secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
assert(secp256k1_context_verify != nullptr);
}
refcount++;
}

ECCVerifyHandle::~ECCVerifyHandle()
{
refcount--;
if (refcount == 0) {
assert(secp256k1_context_verify != nullptr);
secp256k1_context_destroy(secp256k1_context_verify);
secp256k1_context_verify = nullptr;
}
}

const secp256k1_context* GetVerifyContext() {
return secp256k1_context_verify;
return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_static, nullptr, &sig));
}
17 changes: 0 additions & 17 deletions src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,21 +258,4 @@ struct CExtPubKey {
bool Derive(CExtPubKey& out, unsigned int nChild) const;
};

/** Users of this module must hold an ECCVerifyHandle. The constructor and
* destructor of these are not allowed to run in parallel, though. */
class ECCVerifyHandle
{
static int refcount;

public:
ECCVerifyHandle();
~ECCVerifyHandle();
};

typedef struct secp256k1_context_struct secp256k1_context;

/** Access to the internal secp256k1 context used for verification. Only intended to be used
* by key.cpp. */
const secp256k1_context* GetVerifyContext();

#endif // BITCOIN_PUBKEY_H
Loading