Clarify API doc of ecdsa_recover return value #1718

issue jonasnick openend this issue on August 5, 2025
  1. jonasnick commented at 7:51 pm on August 5, 2025: contributor

    The API doc for ecdsa_recover states the following:

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

    After reading this, one may assume that when ecdsa_recover successfully recovers a pubkey, ecdsa_verify on the same signature, message and public key will never fail. Or more precisely, the assertion in the following code snippet never fails:

     0secp256k1_ecdsa_signature sig;
     1secp256k1_ecdsa_recoverable_signature rsig;
     2
     3/* Set rsig to something */
     4/* ... */
     5
     6if (secp256k1_ecdsa_recover(ctx, pubkey, rsig, msg)) {
     7    secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig);
     8    assert(secp256k1_ecdsa_verify(CTX, &sig, msg, &pubkey));
     9
    10}
    

    However, this is not true due to “s-malleability” of ECDSA signatures: ecdsa_verify requires low-s while ecdsa_recover does not. Thus, if we add

    0    secp256k1_ecdsa_signature_normalize(CTX, &sig, &sig);
    

    after the ecdsa_recoverable_signature_convert call in above code snipped, then the assertion never fails.

    In other words, ecdsa_recover returning 1 does guarantee a correct signature, but ecdsa_verify passes only after the signature is normalized. We should document this fact more clearly.

    Thanks to @erickcestari for reporting this!

  2. real-or-random added the label user-documentation on Aug 6, 2025
  3. real-or-random added the label tweak/refactor on Aug 6, 2025

github-metadata-mirror

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: 2025-08-30 22:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me