-
Notifications
You must be signed in to change notification settings - Fork 6
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
define and implement ConstantTime{Partial,}Ord
traits
#5
Conversation
Note that unlike dalek-cryptography#79, I do not attempt to provide a constant-time analogue of However, if we think we'll want to have a separate EDIT: have now added back the |
4fd40e6
to
8dce821
Compare
8dce821
to
9e258d9
Compare
ConstantTimeCmp
trait
cca032e
to
29008e6
Compare
29008e6
to
14d884c
Compare
ConstantTimeCmp
traitConstantTime{Partial,}Ord
traits
After reminding myself that partial orders still have the equality, I have revised this PR to create a |
@@ -778,7 +783,7 @@ pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater { | |||
/// ``` | |||
#[inline] | |||
fn ct_lt(&self, other: &Self) -> Choice { | |||
!self.ct_gt(other) & !self.ct_eq(other) | |||
other.ct_gt(self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current default definition assumes a total ordering over Self
, which could introduce sneaky logic errors for users! It also makes two calls to comparison functions instead of one. I believe this new default definition will now be correct for partially-ordered Self
and will only ever need to be modified for cases where x < y
does not imply y > x
(which I believe is a strict subset of partially ordered sets).
ping @hdevalence @isislovecruft! Let me know if this is something the project would be interested in merging. I think the explanation for the change in this comment #5 (comment) is a good argument for introducing these traits. |
This repo is unmaintained, use the original instead: https://github.com/dalek-cryptography/subtle. |
dalek-cryptography#79 proposed a
ConstantTimePartialOrd
trait, but this was abandoned since (I am guessing) there wasn't a clear general use case, and there were concerns about how to create anOrdering
without the use ofmatch
. This PR describes a general use case for constant-time ordering, and amends that PR with a naive attempt to avoid branching when creating anOrdering
.Use Case
In the signal rust codebase, we (I am not affiliated with Signal) handroll a function
constant_time_cmp()
to essentially implementOrd
for[u8]
slices, which we use to directly implementOrd
for our public keys. I was going to expose that method to our API consumers in signalapp/libsignal#469, but I was advised to raise this use case to thesubtle-ng
crate instead.Signal ends up consuming the
Ord
impl for public keys in our client library's FFI, which is then used to implementOrd
interfaces in the foreign languages.I think that if the proposed solution correctly achieves constant-time comparisons, it would benefit users of this library, who can now avoid hand-rolling their own
Ord
implementations which may not have been audited to correctly run in constant time.Proposed Solution
ConstantTime{PartialOrd,Ord}
which return either aCtOption<Ordering>
or anOrdering
.ConstantTime{Eq,Greater}
.Note: I do not know if this implementation correctly avoids branching in the implementation of
ct_cmp
. It is directly based off of the code in dalek-cryptography#79, adding the use of a lookup tableORDERS
instead of amatch
.Result
Consumers of this library were already able to impl
core::cmp::{Partial,}Eq
withConstantTimeEq
to makeConstantTimeEq
implementors usable as keys inHashSet
s, for example. This change provides a safe constant-time implementation of an equivalent tocore::cmp::{Partial,}Ord
so that users can ensure constant-time comparisons between keys in an ordered collection such asBTreeSet
as well.