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

Only create signatures with even S, and verification mode to check. #2131

Merged
merged 1 commit into from Aug 16, 2013

Conversation

sipa
Copy link
Member

@sipa sipa commented Dec 26, 2012

To fix a minor malleability found by Sergio Lerner (reported here: https://bitcointalk.org/index.php?topic=8392.msg1245898#msg1245898)

The problem is that if (R,S) is a valid ECDSA signature for a given message and public key, (R,-S) is also valid. Modulo N (the order of the secp256k1 curve), this means that both (R,S) and (R,N-S) are valid. Given that N is odd, S and N-S have a different lowest bit. We solve the problem by forcing signatures to have an even S, excluding one of the alternatives.

This pull request just changes the signing code to always produce even S values, and adds a verification mode to check it. This code is not enabled anywhere yet. Existing tests in key_tests.cpp verify that the produced signatures are still valid.

{
vchSig.clear();
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig == NULL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subtle change in semantics here: if sig == NULL, the old code cleared vchSig.

For defensive programming, I'd suggest a vchSig.clear(); as the first statement in this routine.

@sipa
Copy link
Member Author

sipa commented Dec 28, 2012

@gavinandresen Updated.

@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/3e4655404a8839a03c241fdcf67e063940eb462b for binaries and test log.

@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/e1771b85af3d16e12bab2243ea50adf2d52eaf3c for binaries and test log.

@gavinandresen
Copy link
Contributor

I think this goes one step too far.

Some almost-baked thoughts on the problem we're actually trying to solve (we'd like transactions ids to be immutable):

I think this ties into a bunch of other almost-baked thoughts I've had surrounding bumping the transaction.version. I think it might make sense to introduce transaction.version=2 messages onto the network, with additional rules for relaying/DoS-banning. In particular, I'm imagining a signature from one of the keys used to sign the inputs (maybe.. . more thought needed on how the signing is tied to the transaction's creator) that covers the transaction id and transaction fee paid.

That should solve the "relayer modifies the signature to change the txid".

(the transaction fee paid would be to help out SPV clients, which is a separate feature)

@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/e1771b85af3d16e12bab2243ea50adf2d52eaf3c for binaries and test log.

@gmaxwell
Copy link
Contributor

DOS rules don't prevent a miner from modifying a transaction. We really do need to actually remove the malleability. ... though the actual enforcement would need to be on a version=2 transaction.

@sipa
Copy link
Member Author

sipa commented Feb 5, 2013

@gavinandresen I really don't like the fact that this would mean rules at the transaction validation level would need knowledge about the precise inner script semantics. IMHO, we should just gradually introduce rules to remove malleabilities, and then perhaps use tx.nVersion==2 rule to enforce them in the block chain at some later point.

@luke-jr
Copy link
Member

luke-jr commented Jul 17, 2013

@sipa Needs rebase (or close if it was merged in another form?).

To fix a minor malleability found by Sergio Lerner (reported here:
https://bitcointalk.org/index.php?topic=8392.msg1245898#msg1245898)

The problem is that if (R,S) is a valid ECDSA signature for a given
message and public key, (R,-S) is also valid. Modulo N (the order
of the secp256k1 curve), this means that both (R,S) and (R,N-S) are
valid. Given that N is odd, S and N-S have a different lowest bit.
We solve the problem by forcing signatures to have an even S value,
excluding one of the alternatives.

This commit just changes the signing code to always produce even S
values, and adds a verification mode to check it. This code is not
enabled anywhere yet. Existing tests in key_tests.cpp verify that
the produced signatures are still valid.
@sipa
Copy link
Member Author

sipa commented Aug 15, 2013

Rebased. @jgarzik @gmaxwell @gavinandresen @laanwj: opinions?

@gmaxwell
Copy link
Contributor

Without this, or a substantially similar, change we cannot eliminate malleability attacks on unconfirmed transaction chains.

Though I almost wish the evenness procedure had been specified in BIP32, as now we're going to see hardware wallet deployed that produce odd signatures. They can be fixed with an after the fact mutation, so perhaps thats not the end of the world.

@BitcoinPullTester
Copy link

Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/a81cd96805ce6b65cca3a40ebbd3b2eb428abb7b for binaries and test log.
This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/
Contact BlueMatt on freenode if something looks broken.

@gavinandresen
Copy link
Contributor

ACK.

gmaxwell added a commit that referenced this pull request Aug 16, 2013
Only create signatures with even S, and verification mode to check.
@gmaxwell gmaxwell merged commit 47491a9 into bitcoin:master Aug 16, 2013
lunokhod pushed a commit to lunokhod/anoncoin that referenced this pull request Feb 26, 2015
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Jul 2, 2018
Instead just mark them as MASTERNODE_UPDATE_REQUIRED and proceed further.
HashUnlimited added a commit to chaincoin/chaincoin that referenced this pull request Jul 2, 2018
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Jul 2, 2018
Instead just mark them as MASTERNODE_UPDATE_REQUIRED and proceed further.
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Jul 3, 2018
Instead just mark them as MASTERNODE_UPDATE_REQUIRED and proceed further.
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jul 6, 2018
Instead just mark them as MASTERNODE_UPDATE_REQUIRED and proceed further.
owlhooter pushed a commit to owlhooter/mazacoin-new that referenced this pull request Oct 11, 2018
Instead just mark them as MASTERNODE_UPDATE_REQUIRED and proceed further.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants