Skip to content

Conversation

amadeuszpawlik
Copy link
Contributor

@amadeuszpawlik amadeuszpawlik commented Sep 9, 2021

As detailed in #22435, BIP340 defines that during Schnorr signing a verification should be done. This is so that potentially corrupt signage does not leak information about private keys used during the process. This is not followed today as no such verification step is being done. The same is valid for ECDSA signing functions Sign and SignCompact.
This PR adds this missing verification step to SignSchnorr, Sign and SignCompact.

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 10, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #23394 (Taproot wallet test vectors (generation+tests) by sipa)
  • #23383 (Update libsecp256k1 subtree to current master by sipa)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@benthecarman
Copy link
Contributor

Concept ACK

Copy link
Member

@sipa sipa left a comment

Choose a reason for hiding this comment

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

Concept ACK, two small comments.

Any reason not to do the same for ECDSA?

@amadeuszpawlik amadeuszpawlik changed the title Add verification to SignSchnorr Add verification to Sign, SignCompact and SignSchnorr Sep 15, 2021
@amadeuszpawlik
Copy link
Contributor Author

As per @sipa's suggestion, I added verification step to ECDSA signing functions too.
Changed the disable flag name to reflect that.

@benthecarman
Copy link
Contributor

@amadeuszpawlik amadeuszpawlik force-pushed the schnorr_sig branch 4 times, most recently from 67e3138 to 454be06 Compare September 20, 2021 19:55
@laanwj
Copy link
Member

laanwj commented Sep 27, 2021

at the same time allowing for disabling the extra verification in case this extra step is computationally too expensive (--disable-verify-signing).

Does this ever come up in practice? I mean, yes, the secp256k1 library is used on some very low-end hardware. However Bitcoin Core's minimum specifications are a lot higher. The amount of signatures generated is also fairly low, compared to the number of verifications done, so it's important that verification is fast. Does it add that much overhead?

But maybe I'm missing something.

@practicalswift
Copy link
Contributor

practicalswift commented Sep 30, 2021

@amadeuszpawlik Do you have any measurements suggesting that --disable-verify-signing might be needed in practice for performance reasons? If not I think it would be better to not introduce that option :)

@amadeuszpawlik
Copy link
Contributor Author

@laanwj @practicalswift I got this idea from the original issue: #22435, but I agree with you both and have thus dropped the "disable option".

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Concept ACK

Left a code-review comment below. As an additional improvement, I'd suggest to add a comment like "// Additional verification step to prevent using a potentially corrupted signature" in each function before your introduced code to increase readability.

To fix the failed CI run on windows, rebasing on master should help (to include #23089).

@amadeuszpawlik amadeuszpawlik force-pushed the schnorr_sig branch 2 times, most recently from 96ec9d8 to c9a920e Compare October 4, 2021 15:09
@amadeuszpawlik
Copy link
Contributor Author

@theStack I don't think #23089 is it
CirrusCI:
TestFramework (ERROR): Unexpected exception caught during testing File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\wallet_send.py", line 506, in run_test ext_utxo = ext_fund.listunspent(addresses=[addr])[0] IndexError: list index out of range
Can't reproduce on linux though

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Light code-review ACK c9a920e
(LGTM, though I don't have strong experience with correct secp256k1 usage, hence only "light")

@amadeuszpawlik: Weird that it still fails on the Windows CI. I think it's unlikely that it's connected to this PR; if your introduced code failed in the course of a wallet send RPC, an assertion would be thrown (crashing bitcoind) and the "generate" RPC call above the line where the test assertion fails would not have succeeded.

@amadeuszpawlik
Copy link
Contributor Author

@theStack Agree, I reran the Win64 build and it went through just fine 👍

As defined in BIP340, a verification step should be executed after
`secp256k1_schnorrsig_sign` to ensure that a potentially corrupted
signature isn't used; using corrupted signatures could reveal
information about the private key used. This applies to ECSDA as
well.

Additionally clears schnorr signature if signing failed.
@sipa
Copy link
Member

sipa commented Nov 2, 2021

utACK 79fd28c

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

re-ACK 79fd28c

Checked that compared to my last ACK, the verificiation verification step in CKey::SignCompact is now done via ECDSA public key recovery (secp256k1 function secp256k1_ecdsa_recover), which according to the interface documentation "guarantees a correct signature" if successful,

/** Recover an ECDSA public key from a signature.
*
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
* 0: otherwise.

plus a comparison (secp256k1_ec_pubkey_cmp) between the recovered and the created public key (secp256k1_ec_pubkey_create). Also ran unit tests locally.

@laanwj
Copy link
Member

laanwj commented Nov 9, 2021

Code review ACK 79fd28c

@laanwj laanwj merged commit cb4adbd into bitcoin:master Nov 9, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Nov 9, 2021
…ignSchnorr`

79fd28c Adds verification step to Schnorr and ECDSA signing (amadeuszpawlik)

Pull request description:

  As detailed in bitcoin#22435, BIP340 defines that during Schnorr signing a verification should be done. This is so that potentially corrupt signage does not leak information about private keys used during the process. This is not followed today as no such verification step is being done. The same is valid for ECDSA signing functions `Sign` and `SignCompact`.
  This PR adds this missing verification step to `SignSchnorr`, `Sign` and `SignCompact`.

ACKs for top commit:
  sipa:
    utACK 79fd28c
  laanwj:
    Code review ACK 79fd28c
  theStack:
    re-ACK 79fd28c

Tree-SHA512: 8fefa26caea577ae8631cc16c4e2f4cc6cfa1c7cf51d45a4a34165636ee290950617a17a19b4237c6f7a841db0e40fd5c36ad12ef43da82507c0e9fb9375ab82
@bitcoin bitcoin locked and limited conversation to collaborators Nov 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants