subtle icon indicating copy to clipboard operation
subtle copied to clipboard

Add `ConstantTimeSelect` and `ConstantTimeClone` traits

Open tarcieri opened this issue 1 year ago • 3 comments
trafficstars

ConstantTimeSelect is intended as a replacement to ConditionallySelectable, which is preserved but deprecated. It replaces the previous Copy bound with a bound on a new ConstantTimeClone marker trait, which allows the trait to be impl'd for heap-allocated types.

No existing impls of ConditionallySelectable have been removed, however a blanket impl of ConstantTimeSelect for T: ConditionallySelectable has been added, allowing the two traits to interoperate and for ConstantTimeSelect to work on all types which currently impl ConditionallySelectable.

ConstantTimeClone likewise has a blanket impl for all types which impl Copy.

CtOption's combinator methods have been changed to bound on ConstantTimeSelect which unlocks using them with heap-allocated types, which otherwise is a major limitation. In theory these changes are all backwards compatible due to the blanket impl, which should allow all types which previously worked to continue to do so.

Closes #63, #94

tarcieri avatar Nov 29 '23 21:11 tarcieri

Another option here would be to make the breaking changes necessary to solve #63 and #94, retaining the current name for ConditionallySelectable, but removing the Copy bound, and removing the default bounds in the CtOption combinator methods.

While technically breaking, most users of subtle could work with either version that way, and could change their version requirements to something like:

subtle = ">=2, <4"

This would allow compatible crates to work with either subtle v2 or v3, which would allow for non-breaking upgrades to e.g. curve25519-dalek and ed25519-dalek though testing both combinations might be a bit painful (we use a minimum-versions resolution in @RustCrypto to test this sort of thing).

Still, a major version bump would be annoying, but full backwards compatibility is a bit hard to preserve here.

tarcieri avatar Dec 01 '23 22:12 tarcieri

Yet another option would be to use the semver trick to provide backwards compatibility between subtle v2 and v3 which would enable an incremental upgrade, and also avoid changing trait/method names.

In this case, I think that would need to involve subtle v3 providing opt-in blanket impls for subtle v2 traits similar to the blanket impl of ConstantTimeEq for ConditionallySelectable in this PR (that's a bit different from the typical "semver trick", where the old crates import the new ones, but needed to make the blanket impls work since removing the Copy bound means not all types which can impl this PR's ConstantTimeSelect can impl ConditionallySelectable).

tarcieri avatar Dec 02 '23 14:12 tarcieri

I've been thinking more about the "semver trick" approach and how it could be done the proper way according to that blog: releasing a subtle v3 with breaking changes, but adding something like a v3 feature to a future subtle v2.x which pulls in subtle v3 as a dependency and re-exports everything which hasn't changed (which would be everything except ConditionallySelectable and CtOption), gating the rest of the old implementation out and using the subtle v3 traits/types instead.

subtle v2 could also blanket impl its ConditionallySelectable trait for subtle v3's ConditionallySelectable + Copy, and provide From impls for converting the CtOption types.

That would provide a huge degree of interop between the two versions to allow for a gradual transition, and also ensure that subtle v3 has no dependency on subtle v2.

tarcieri avatar Dec 17 '23 16:12 tarcieri

Note: opened #136 as an alternative which makes a deliberate breaking change to ConditionallySelectable's supertrait bound as an alternative to this PR, since this PR contains changes I'd consider subtly breaking

tarcieri avatar Aug 03 '24 22:08 tarcieri

Closing in favor of #137

tarcieri avatar Aug 03 '24 23:08 tarcieri