-
Notifications
You must be signed in to change notification settings - Fork 36.9k
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
Switch to libsecp256k1-based ECDSA validation #6954
Conversation
concept ACK |
ACK |
Concept ACK
|
Concept ACK. Will start testing shortly. |
In the build process, you run
Is this compatible with our gitian/crossbuild processes? |
@paveljanik: Yes. It is. I also tested a gitian build: https://bitcoin.jonasschnelli.ch/pulls/6954/ |
concept ACK |
Just synced a fresh node with this branch with System: Quad Core Intel(R) Xeon(R) CPU E31245 @ 3.30GHz, 16GB Ram, 7200rpm disk. |
Concept ACK |
ACK. I provided some nits, I consider them super minor and not blockers. Also tested IBD w/ no checkpoints, reindex, reindex in valgrind, signmessage/verify message. Could not test derive, because we don't actually expose it. |
Unrepresentative non-scientific trivial IBD comparison with standard parameters: Current Master:
Time for IBD: ~11h59' This PR
Time for IBD: ~8h50` Will do the same now with |
FWIW, you need a coinscache around 5500 MB to actually have the UTXO in ram. In that configuration with this patch and checkpoints disabled I performed an IBD off the network in about three and a half hours:
|
current master: This PR |
Total: 3h22 |
Just encountered a possible issue: The node running this PR is stuck on height 382748.
Therefore the mempool is getting relatively big:
Node running current master (openssl verification) on the same machine (same ip, different port) reports:
last 1000 lines of the debug log: https://bitcoin.jonasschnelli.ch/secp/stuck_debug.log |
I'm very in favor of this being merged, however I can't say I have reviewed this code or done specific testing. I have however been using it over the last several months and never encountered a problem. |
Re: libsecp256k1 testing, awesome work! Is there a document anywhere describing that process a bit more formally? It'd be good to have that to point people too. (particularly if you have enough time to make it repeatable by others) |
F.Y.I: |
@@ -967,6 +967,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) | |||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log | |||
|
|||
// Initialize elliptic curve code | |||
ECC_Verify_Start(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it would be nice if we could print a log entry similar to L1005 about the usage of libsecp256k1 for verification (maybe with a version number [in future]). It might be helpful when analyzing a debug.log coming out of self-compiled bitcoin-core versions.
Tested & Code-Review ACK. Did serval IBD's and running nodes with this PR since 3 days without problems (expect the one that is not related to this PR). Attached my OSX leaks detector during IBD and -verifyblocks=288 phase (can only collect the BDB leaks). +1 for next step to fully remove the openssl dependency by replacing |
Reindex up to block 380912 w/ dbcache=8000 took 3.2 hours with this patch, 8.0 hours without. |
Concept ACK. I've been waiting for this. |
This needs more people to review the integration code before it can be merged. (Enough benchmarks.) |
@@ -205,4 +210,12 @@ struct CExtPubKey { | |||
bool Derive(CExtPubKey& out, unsigned int nChild) const; | |||
}; | |||
|
|||
/** Users of this module must hold an ECCVerifyHandle. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users have to hold a ECCVerifyHandle. Maybe we should make them pass it in to make sure of that? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've considered that, but it would be a mess to pass it down all the way from libconsensus' main function through all validation and script code to pubkey.cpp...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree
Code review ACK |
} | ||
if (overflow) { | ||
memset(tmpsig, 0, 64); | ||
secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like another "Hack to initialize sig with a correctly-parsed but invalid signature"? We already did this in the beginning (not that it can hurt to do it again)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other call to secp256k1_ecdsa_signature_parse_compact above may have overwritten the result in sig, but still have returned overflow.
Note that this function is (at this point) a literal copy from the src/secp256k1/contrib directory, where it is well-tested. It's however copied as the code in contrib carries no real guarantees of providing the exact same behaviour in the long run, and this is consensus critical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch. That one is subtle. I'd suggest adding a comment so that other people don't have the same dumb thought as me.
This pull could write the release notes too, see comments for benchmark numbers. :) |
I can also confirm this makes Bitcoin work on unmodified RHEL7. |
@@ -154,6 +154,7 @@ class CCoinsViewErrorCatcher : public CCoinsViewBacked | |||
|
|||
static CCoinsViewDB *pcoinsdbview = NULL; | |||
static CCoinsViewErrorCatcher *pcoinscatcher = NULL; | |||
static boost::scoped_ptr<ECCVerifyHandle> verify_handle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bike-shedding: s/verify_handle/globalVerifyHandle or something of the short to make its scope clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I cannot give an utACK because I'm not trying to understand everything that is done here. |
Addressed some nits. |
Bikeshedding over different (but semantically equivalent) syntax can happen later. I'd like to move forward with this, to make sure it ends up in 0.12 and to save @sipa the work of rebasing this every time. Further testing and review will probably only happen anyway when this is merged. |
6e18268 Switch to libsecp256k1-based validation for ECDSA (Pieter Wuille)
Sure, my non-addressed suggestion was too disruptive to make this happen fast and it's not a priority. |
Is there proper and academic documentation for these proposed changes and is there a BIP? This isn't solely a code change, in my opinion. New algorithms are being proposed towards some of the most fundamental aspects of bitcoin - signature validation. As we all know, things can go terribly wrong in this space and unfortunately it is not even knowable what can go wrong. Certain experts have expressed concerns about seemingly impossible claims that 700% improvements can be achieved by these "invented" mathematical algorithms. Further concerns have been raised towards suggestions that this is more tested than standard practice when standard practice requires some 20 years of testing. I am not, of course, suggesting that the proposed changes are conceptually deficient, but I would not be comfortable with these changes in the absence of proper documentation and wider review from experts who specialise in this area because it is far too easy to hide backdoors in this space or less maliciously to unknowably fatally weaken the algorithm and its security. |
@Aquentus While I agree with your concerns, I am not sure this needs a BIP beyond BIP 66. The review of libsecp256k1 (which included comparison of results with the current consensus-protocol OpenSSL verification) turned up serious consensus-failure bugs in OpenSSL which BIP 66 solved. When review of the new code has fixed de facto problems in the old code, I think it demonstrates a clear higher standard of testing for the new code. "20 years of testing" is non-existent insofar as consensus safety is concerned - the field of decentralised consensus systems is only 6 years old, after all. |
I disagree with a need for a BIP. None of the consensus rules are intended I do agree that better visibility of the algorithms used is useful. One thing that is planned before final release is an explanation of the A small summary of the optimizations used in signature verification, and are not used by OpenSSL:
For all of the above, we have:
Furthermore:
|
Switch to libsecp256k1-based validation for ECDSA Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#6983 - bitcoin/bitcoin#6954 Part of #2333.
This updates the libsecp256k1 subtree to upstream master, and switches ECDSA validation to it.
Practical upshot:
Libsecp256k1 itself has not had a stable release, but we're very close to that. This PR is effectively a preview, with the intention of switching to the released version before the Bitcoin Core 0.12 release.
The past months libsecp256k1 has undergone very extensive testing and validation, though some of that work is still under review. This includes:
The above things are planned to be finished before final release, as well as some API changes - though probably none that affect Bitcoin's usage.
Thanks to everyone who contributed so far (including but not limited to @gmaxwell, @apoelstra, @peterdettman, @theuni, @luke-jr, ...).