-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support ConditionallySelectable for types that are not Copy #94
Comments
It's unclear to me what the rationale for the Looking at how |
If I understand correctly, Henry's stated reasoning is that allowing I'm not opposed to this reasoning. I just wonder if there's an escape hatch we could make that allows you to do this if you're very careful. |
The impl<T, const N: usize> ConditionallySelectable for [T; N]
where T: ConditionallySelectable + Copy
That is a reasonable concern. However, I do also sympathize with the concern that it may be unwise to impl |
Agreed. A not-great idea: make a |
Another option besides splitting the pub trait CtClone: Clone {}
impl<T: Copy> CtClone for T {} ...and then changing
|
Oh, that's pretty nice. I'd be fine with that. |
I think a similar argument applies to
which is obviously only true if the called closure runs in constant-time but there is nothing enforcing that. |
A big drawback of the |
However, changing it seems like a breaking change due to removing the supertrait bound on Currently anything that's It's the kind of thing that makes me wish we had something like Crater to see if it would break any real-world code. I think there's a real chance it might. |
It seems like the only way to support non- pub trait ConstantTimeClone: Clone {}
impl<T: Copy> ConstantTimeClone for T {}
pub trait ConstantTimeSelect: ConstantTimeClone {
fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self;
[...]
}
impl<T: ConditionallySelectable> ConstantTimeSelect for T {
[...]
} ...then |
This is an inherent function with the same type signature as `subtle::ConditionallySelectable::conditional_select`, however we can't impl the upstream trait because it has a `Copy` bound. See dalek-cryptography/subtle#94.
This is an inherent function with the same type signature as `subtle::ConditionallySelectable::conditional_select`, however we can't impl the upstream trait because it has a `Copy` bound. See dalek-cryptography/subtle#94.
I've been attempting to make use of I can attest the I can try to open a PR with what I've outlined above, which in theory should be a backwards compatible change as current
|
Unfortunately `BoxedUint` can't impl `subtle::ConditionallySelectable` due to a supertrait bound on `Copy`. See dalek-cryptography/subtle#94 This bound is required by `CtOption::map` and `CtOption::and_then` which are important for writing constant-time code. As a workaround which makes it still possible to leverate `CtOption`, this adds special `BoxedUint`-specialized combinators that are able to work around this issue by generating a placeholder (zero) value to pass to the provided callbacks in the event `CtOption` is none. This requires branching on the output of `CtOption` (which is unavoidable without an upstream fix in `subtle` itself), but still ensures that the provided callback function is called with a `BoxedUint` of a matching number of limbs regardless of whether the `CtOption` is some or none, which is the best we can do for now (and really quite close to what `subtle` is doing under the hood anyway).
Unfortunately `BoxedUint` can't impl `subtle::ConditionallySelectable` due to a supertrait bound on `Copy`. See dalek-cryptography/subtle#94 This bound is required by `CtOption::map` and `CtOption::and_then` which are important for writing constant-time code. As a workaround which makes it still possible to leverate `CtOption`, this adds special `BoxedUint`-specialized combinators that are able to work around this issue by generating a placeholder (zero) value to pass to the provided callbacks in the event `CtOption` is none. This requires branching on the output of `CtOption` (which is unavoidable without an upstream fix in `subtle` itself), but still ensures that the provided callback function is called with a `BoxedUint` of a matching number of limbs regardless of whether the `CtOption` is some or none, which is the best we can do for now (and really quite close to what `subtle` is doing under the hood anyway).
`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 dalek-cryptography#63, dalek-cryptography#94
I went ahead and impl'd my aforementioned |
`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 dalek-cryptography#63, dalek-cryptography#94
This commit contains a minimal set of proposed breaking changes, as an alternative to trying to make additive changes which may be "subtly" breaking: - Add `ConstantTimeClone` trait and use it as `ConditionallySelectable`'s supertrait bound (alternative to dalek-cryptography#118): this makes it possible to implement `ConditionallySelectable` on heap-allocated types (fixes dalek-cryptography#94) - Remove `Default` bound on `CtOption::map` and `CtOption::and_then`: allows using these methods with types that don't impl `Default` and avoids potential timing sidechannels if there might be timing variability in `Default` types (fixes dalek-cryptography#63)
To resolve dalek-cryptography#94, removes the `Copy` supertrait bound on `ConditionallySelectable`, replacing it with `Sized` instead. It turns out the bound is only used in the default implementation of `ConditionallySelectable::conditional_swap`, and is easy to replace by slightly changing that default implementation. Removing this supertrait bound is arguably a breaking change since it means types which impl `ConditionallySelectable` can no longer be assumed to be `Copy`, so also bumps the version to `3.0.0-pre`.
This is a feature request to support the trait
ConditionallySelectable
for types that are notCopy
.Motivation
I have large types (e.g. polynomials of high degree) that I'd like to be conditionally selectable.
The text was updated successfully, but these errors were encountered: