Skip to content

Conversation

Kixunil
Copy link
Collaborator

@Kixunil Kixunil commented Jun 9, 2022

This adds Scalar newtype to better represent values accepted by
tweaking functions. This type is always 32-bytes and guarantees being
within curve order.

This is an initial iteration. Things I'm not 100% sure of, would appreciate help:

  • Is it actually required for scalar to be within curve order?
  • Are non-constant-time operations actually an issue?

Alterntive tweaking API designs:

  • Accept Into<Scalar> generic argument, so people can pass SecretKey, may slightly worsen performance
  • unsafe-ly implement AsRef<Scalar> for SecretKey (casting raw pointers) and accept that

Possible extension: API to convert from slices so that the user doesn't need two steps (convert to array first).

This adds `Scalar` newtype to better represent values accepted by
tweaking functions. This type is always 32-bytes and guarantees being
within curve order.
Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 5a03324

@apoelstra
Copy link
Member

Very interesting. In future this also may give us a hook to provide direct rust implementations of some functionality (though we probably don't want to use it by default, for perf reasons) and/or support for reduced-size groups for exhaustive testing.

@apoelstra apoelstra merged commit aab77b1 into rust-bitcoin:master Jun 9, 2022
@apoelstra
Copy link
Member

Sneaking this in before #444

@Kixunil Kixunil deleted the scalar branch June 9, 2022 13:31


/// Error returned when the value of scalar is invalid - larger than the curve order.
// Intentionally doesn't implement `Copy` to improve forward compatibility.
Copy link
Member

Choose a reason for hiding this comment

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

Why does implementing Copy hurt forward compatibility @Kixunil?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had the idea of a feature gate adding boxed input. (boxed to decrease cost of moving - this is common for error types)

Copy link
Member

Choose a reason for hiding this comment

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

Cool, cheers.

@sanket1729
Copy link
Member

For comparison: I did something similar last year
BlockstreamResearch/rust-secp256k1-zkp#16


/// Tries to deserialize from big endian bytes
///
/// **Security warning:** this function is not constant time!
Copy link
Member

Choose a reason for hiding this comment

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

If there is interest here, you can also add my implementation that is constant time for non-zero values.

BlockstreamResearch/rust-secp256k1-zkp@53d1947

I think it makes sense to use the _var suffix naming from upstream to signify variable time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Cool trick! I would like to make it constant time and in pure Rust in the future because it'll also be needed for private key checking without the C library. Looking at the C code, there doesn't seem to be anything C-specific that would make it constant time, so I think it should be doable.

Copy link
Member

Choose a reason for hiding this comment

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

Should we rename things to _var before cutting a release?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would rather use @sanket1729 trick to not cause churn if we don't want non-constant-time functions without the suffix.
(Also secp256k1 can do the exact check we need but I guess the function is private.)

sander2 added a commit to sander2/polkabtc-clients that referenced this pull request Oct 6, 2022
sander2 added a commit to sander2/polkabtc-clients that referenced this pull request Oct 6, 2022
sander2 added a commit to sander2/polkabtc-clients that referenced this pull request Oct 7, 2022
moonman889 added a commit to moonman889/interbtc-clients that referenced this pull request Sep 15, 2025
chain-forgexcr45 added a commit to chain-forgexcr45/rust-secp256k1 that referenced this pull request Sep 28, 2025
…t in tweaking APIs

5a0332463d1ae6b982258999b1ddf7ef0ef23a1f Add `Scalar` newtype and use it in tweaking APIs (Martin Habovstiak)

Pull request description:

  This adds `Scalar` newtype to better represent values accepted by
  tweaking functions. This type is always 32-bytes and guarantees being
  within curve order.

  This is an initial iteration. Things I'm not 100% sure of, would appreciate help:

  * Is it actually required for scalar to be within curve order?
  * Are non-constant-time operations actually an issue?

  Alterntive tweaking API designs:

  * Accept `Into<Scalar>` generic argument, so people can pass `SecretKey`, may slightly worsen performance
  * `unsafe`-ly implement `AsRef<Scalar> for SecretKey` (casting raw pointers) and accept that

  Possible extension: API to convert from slices so that the user doesn't need two steps (convert to array first).

ACKs for top commit:
  apoelstra:
    ACK 5a0332463d1ae6b982258999b1ddf7ef0ef23a1f

Tree-SHA512: cf639c91f0c6f6e0178d8a6d4125fd041708a59661fbd2f1924881001011e4cfe2b998148ae652995cdc9a3791c6644fcd5f004e059d76d9182a5e409b791446
neon-rider578 added a commit to neon-rider578/interbtc-clients that referenced this pull request Sep 30, 2025
william2332-limf added a commit to william2332-limf/rust-secp256k1 that referenced this pull request Oct 2, 2025
…t in tweaking APIs

5a0332463d1ae6b982258999b1ddf7ef0ef23a1f Add `Scalar` newtype and use it in tweaking APIs (Martin Habovstiak)

Pull request description:

  This adds `Scalar` newtype to better represent values accepted by
  tweaking functions. This type is always 32-bytes and guarantees being
  within curve order.

  This is an initial iteration. Things I'm not 100% sure of, would appreciate help:

  * Is it actually required for scalar to be within curve order?
  * Are non-constant-time operations actually an issue?

  Alterntive tweaking API designs:

  * Accept `Into<Scalar>` generic argument, so people can pass `SecretKey`, may slightly worsen performance
  * `unsafe`-ly implement `AsRef<Scalar> for SecretKey` (casting raw pointers) and accept that

  Possible extension: API to convert from slices so that the user doesn't need two steps (convert to array first).

ACKs for top commit:
  apoelstra:
    ACK 5a0332463d1ae6b982258999b1ddf7ef0ef23a1f

Tree-SHA512: cf639c91f0c6f6e0178d8a6d4125fd041708a59661fbd2f1924881001011e4cfe2b998148ae652995cdc9a3791c6644fcd5f004e059d76d9182a5e409b791446
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants