-
Notifications
You must be signed in to change notification settings - Fork 78
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
#98
base: main
Are you sure you want to change the base?
define and implement ConstantTime{Partial,}Ord
traits
#98
Conversation
- copyright and rustfmt fix - add ConstantTimeCmp - use a lookup table to avoid branching - implement ConstantTimePartialOrd - expose `index_mutually_exclusive_logical_results()` - make the constants static - make ct_cmp() a default trait method for reasons described in docs - implement ct_eq() for Ordering
c89612c
to
37a596c
Compare
- instead, extend ConditionallySelectable to Ordering
@@ -852,7 +855,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.
This line here is the motivation for this change. The prior default implementation assumes that Self
is totally ordered. We have moved this logic to ConstantTimeOrd
's default implementation of ct_cmp()
, requiring types to explicitly impl ConstantTimeOrd
in order to use this "not equal or greater" check, while ConstantTimePartialOrd
has to check all three of equals, less than, and greater.
This was part of the OP, but I've moved it out since it doesn't need to be part of the commit description: Use CaseJustification for defining + implementing
|
I think #102 might be a bit more minimal way of supporting It doesn't define any new traits, just impls the That's not to say new traits aren't worth pursuing, but maybe a more minimal start would be easier to review than design for new traits. |
This is super interesting and I hadn't considered this! However, I'm having some difficulty understanding how implementing Please confirm: I cannot see how implementing
I do not believe that it is possible for a consumer of pub(crate) fn constant_time_cmp(x: &[u8], y: &[u8]) -> Ordering {
if x.len() < y.len() {
return Ordering::Less;
}
if x.len() > y.len() {
return Ordering::Greater;
}
let mut result: u8 = 0;
for i in 0..x.len() {
let a = x[x.len() - 1 - i];
let b = y[x.len() - 1 - i];
let is_eq = ct_is_eq(a, b);
let is_lt = ct_is_lt(a, b);
result = ct_select(is_eq, result, ct_select(is_lt, 1, 255));
}
debug_assert!(result == 0 || result == 1 || result == 255);
if result == 0 {
Ordering::Equal
} else if result == 1 {
Ordering::Less
} else {
Ordering::Greater
}
} |
I guess I'm trying to say two things:
|
Problem
#79 proposed a
ConstantTimePartialOrd
trait, but that attempt was abandoned due to questions about how to create anOrdering
without the use ofmatch
. This PR picks up where that left off and implementsmatch
-less and constant-time comparison operations for partially and totally orderable objects.Solution
ConstantTime{Partial,}Ord
which return either aCtOption<Ordering>
or anOrdering
.ConstantTime{Eq,Greater}
.ConstantTime{Partial,}Ord
's comparison methods by extendingConditionallySelectable
toOrdering
.ConstantTime{Partial,}Ord
traits #98 (comment).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.