Skip to content

ecdh/ellswift/schnorrsig: return early for invalid inputs (consistent handling w.r.t. constant-time) - #1919

Open
theStack wants to merge 3 commits into
bitcoin-core:masterfrom
theStack:ctime-only_for_valid_inputs
Open

ecdh/ellswift/schnorrsig: return early for invalid inputs (consistent handling w.r.t. constant-time)#1919
theStack wants to merge 3 commits into
bitcoin-core:masterfrom
theStack:ctime-only_for_valid_inputs

Conversation

@theStack

@theStack theStack commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

This PR partly addresses issue #1621, handling invalid inputs consistently w.r.t. constant-time, by applying the suggested "functions are constant-time only for valid inputs" approach (number 2. in the issue), for the following modules and API functions:

  • ecdh: secp256k1_ecdh
  • ellswift: secp256k1_ellswift_create and secp256k1_ellswift_xdh
  • schnorrsig: secp256k1_schnorrsig_sign{32,_custom}

As stated in #1621, this leads to more readable and maintainable code, getting rid of constructs like return (!!ret) & is_sec_valid; or intermediate ret &= ...; statements. Conditional assignments like secp256k1_scalar_cmov can be removed as well.

Tests are added for the newly introduced branches if there were none. There are still further instances to tackle (mostly the main module API functions in secp256k1.c, and potential cleanups like e.g. removing the dummy assignments in _keypair_load), happy to add these here or in another PR, mostly chasing Conecpt ACKs for now if this is we want to handle constant-time behavior for current and future modules.

@theStack theStack changed the title ecdh/ellswift/schnorrsig: return early for invalid inputs (consistant handling w.r.t. constant-time) ecdh/ellswift/schnorrsig: return early for invalid inputs (consistent handling w.r.t. constant-time) Aug 20, 2026
Applies the suggested "function is constant-time only for valid inputs"
suggestion in issue bitcoin-core#1621 ("Handle invalid inputs consistently w.r.t.
constant-time") for the API function `secp256k1_ecdh`.

While being at it, also introduce a check for the pubkey object
validity for consistency with other modules. Strictly speaking this is
a behaviour change, but it should be fine as it only improves things
for the user (from potentially arbitrary behaviour to defined one) and
as developers we don't have to reason anymore about code-paths with
how the remainder of the function behaves if the pubkey wasn't loaded
successfully.
Applies the suggested "function is constant-time only for valid inputs"
suggestion in issue bitcoin-core#1621 ("Handle invalid inputs consistently w.r.t.
constant-time") for the API functions `secp256k1_ellswift_create` and
`secp256k1_ellswift_xdh`.
Applies the suggested "function is constant-time only for valid inputs"
suggestion in issue bitcoin-core#1621 ("Handle invalid inputs consistently w.r.t.
constant-time") for the API functions `secp256k1_schnorrsig_sign32` and
`secp256k1_schnorrsig_sign_custom` (both calling
the non-public `secp256k1_schnorrsig_internal` function).
@theStack
theStack force-pushed the ctime-only_for_valid_inputs branch from c451973 to 971bc49 Compare August 24, 2026 15:05
Comment on lines +53 to +56
if (!is_sec_valid) {
secp256k1_ge_clear(&pt);
return 0;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should we also clear s here? I understand that since we already know that s is not a valid secret key, it really doesn't matter that much. However, originally the invalid input path would reach the end of the function and s would be cleared anyway.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question. I'd argue that there is not much value in protecting invalid key material from leaking (see also recent review comment #1802 (comment)), but being conservative and still clearing it is of course also an option. Curious what other reviewers think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants