This PR aims to fix #1718. I thought it's nice to provide an usage example, but not sure if we want actual code snippets in the API header (it's also incomplete, as the declarations are missing), so an alternative might be to drop it, or add a "(see example)" reference in the future in case #1714 gets in.
doc: clarify API doc of `secp256k1_ecdsa_recover` return value #1741
pull theStack wants to merge 1 commits into bitcoin-core:master from theStack:doc-ecdsa_recover-clarify-return-value changing 1 files +11 −1-
theStack commented at 12:41 PM on September 9, 2025: contributor
- real-or-random added the label user-documentation on Sep 12, 2025
- real-or-random added the label tweak/refactor on Sep 12, 2025
-
in include/secp256k1_recovery.h:101 in e9c10f7df8 outdated
97 | + * in a mathematical sense, but it is only guaranteed to also pass verification 98 | + * with `secp256k1_ecdsa_verify` if it is in lower-S form. For verifying 99 | + * recoverable signatures that were not created with libsecp256k1 (or might have 100 | + * been malleated), it is thus necessary to normalize the signature using 101 | + * `secp256k1_ecdsa_signature_normalize` between conversion and verification. 102 | + * A typical usage might look like this:
jonasnick commented at 6:45 PM on September 14, 2025:I think it'd be better if the docs pointed out that this is not typical usage. In typical usage you only care whether the signature is valid for the recovered public key. So you just need run
ecdsa_recoverand do not need to callecdsa_verify.Maybe there are cases where this is necessary (e.g., you have to hand over the signature and public key to a verify that doesn't support
ecdsa_recover, like the Bitcoin consensus protocol).
theStack commented at 12:10 AM on September 15, 2025:Makes sense. My assumption when writing this was that most users would very likely want to enforce lower-S in order to avoid malleability, but that was more based on gut feeling than actual research (seems BOLT11 now explicitly allows low- and high-S signatures if pubkey recovery is used: https://github.com/lightning/bolts/pull/1284).
in include/secp256k1_recovery.h:97 in e9c10f7df8 outdated
91 | @@ -92,7 +92,22 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable( 92 | 93 | /** Recover an ECDSA public key from a signature. 94 | * 95 | - * Returns: 1: public key successfully recovered (which guarantees a correct signature). 96 | + * Note that successful public key recovery implies a correct ECDSA signature 97 | + * in a mathematical sense, but it is only guaranteed to also pass verification 98 | + * with `secp256k1_ecdsa_verify` if it is in lower-S form. For verifying
jonasnick commented at 7:18 PM on September 14, 2025:"correct ECDSA signature in a mathematical sense" sounds a bit imprecise. How about the following wording, which avoids that term entirely?
Successful public key recovery guarantees that the signature, when normalized, passes `secp256k1_ecdsa_verify`. Thus, explicit verification is not necessary. A recoverable signature converted to a normal signature may not pass `secp256k1_ecdsa_verify` if it is not normalized. If a normalized signature is required, call `secp256k1_ecdsa_signature_normalize` after `secp256k1_ecdsa_recover`.
theStack commented at 12:01 AM on September 15, 2025:Took that suggestion, and set you as commit author accordingly. As tiny-nit, it's slightly unfortunate that "normal" and "normalized" sound so similar, but not sure how to avoid it (maybe it's not a big deal).
real-or-random commented at 6:56 PM on September 15, 2025:Took that suggestion, and set you as commit author accordingly. As tiny-nit, it's slightly unfortunate that "normal" and "normalized" sound so similar, but not sure how to avoid it (maybe it's not a big deal).
Stumbled upon this, too. One fix is s/normal/non-recoverable. Another one is to spell out the types explicitly:
Here's an improved version. This uses a middle way. It says "non-recoverable" but mentions
secp256k1_ecdsa_recoverable_signature_convertso the reader can look up the exact types.Successful public key recovery guarantees that the signature, after normalization, passes `secp256k1_ecdsa_verify`. Thus, explicit verification is not necessary. However, a non-recoverable signature converted from a recoverable signature (using `secp256k1_ecdsa_recoverable_signature_convert`) is not guaranteed to be normalized and thus not guaranteed to pass `secp256k1_ecdsa_verify` (even if it passes `secp256k1_ecdsa_recover`). If a normalized signature is required, call `secp256k1_ecdsa_signature_normalize` after `secp256k1_ecdsa_recoverable_signature_convert`.
theStack commented at 12:26 AM on September 16, 2025:SGTM, taken.
jonasnick commented at 7:14 AM on September 16, 2025:"a non-recoverable signature [...] (even if it passes
secp256k1_ecdsa_recover)" may be a bit confusing because a non-recoverable signature cannot passsecp256k1_ecdsa_recover.How about this:
However, a recoverable signature that successfully passes `secp256k1_ecdsa_recover`, when converted to a non-recoverable signature (using `secp256k1_ecdsa_recoverable_signature_convert`), is not guaranteed to be normalized and thus not guaranteed to pass `secp256k1_ecdsa_verify`.
real-or-random commented at 7:23 AM on September 16, 2025:"a non-recoverable signature [...] (even if it passes
secp256k1_ecdsa_recover)" may be a bit confusing because a non-recoverable signature cannot passsecp256k1_ecdsa_recover.Good point.
theStack commented at 7:31 PM on September 16, 2025:Updated again with the suggestion.
theStack force-pushed on Sep 15, 2025theStack force-pushed on Sep 16, 2025real-or-random approvedreal-or-random commented at 6:26 AM on September 16, 2025: contributorutACK 131f871469945c3c0da53456b6d74ef72a5fd587
7321bdf27bdoc: clarify API doc of `secp256k1_ecdsa_recover` return value
Co-authored-by: Tim Ruffing <me@real-or-random.org>
theStack force-pushed on Sep 16, 2025jonasnick approvedjonasnick merged this on Sep 17, 2025jonasnick closed this on Sep 17, 2025theStack deleted the branch on Sep 17, 2025fanquake referenced this in commit 42c7d35d3a on Oct 14, 2025fanquake referenced this in commit 3cbf7cb3e6 on Oct 15, 2025Sjors referenced this in commit d5660d3a13 on Feb 16, 2026github-actions[bot] referenced this in commit c3f80fff5f on Mar 1, 2026github-actions[bot] referenced this in commit 4aeff8400e on Mar 1, 2026github-actions[bot] referenced this in commit 5f15eb0c55 on Mar 1, 20260x000000000019d6689c085ae165831e934ff76 referenced this in commit d54574beca on Mar 2, 2026csjones referenced this in commit fb3e16af04 on Mar 2, 2026real-or-random referenced this in commit 56751a4cf0 on Mar 2, 20260x000000000019d6689c085ae165831e934ff76 referenced this in commit 924c279a64 on Mar 2, 2026csjones referenced this in commit bf90997db1 on Mar 2, 2026vmta referenced this in commit 1ddc2f947f on Apr 26, 2026vmta referenced this in commit 56c40fe100 on Apr 27, 2026
This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-19 06:52 UTC