@@ -341,8 +341,8 @@ impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
341
341
/// Since arrays coerce to slices, this function works with fixed-size arrays:
342
342
///
343
343
/// ```
344
- /// # use subtle::ConstantTimeEq;
345
- /// #
344
+ /// use subtle::ConstantTimeEq;
345
+ ///
346
346
/// let a: [u8; 8] = [0,1,2,3,4,5,6,7];
347
347
/// let b: [u8; 8] = [0,1,2,3,0,1,2,3];
348
348
///
@@ -359,7 +359,7 @@ impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
359
359
// Short-circuit on the *lengths* of the slices, not their
360
360
// contents.
361
361
if len != _rhs. len ( ) {
362
- return Choice :: from ( 0 ) ;
362
+ return Choice :: of_bool ( false ) ;
363
363
}
364
364
365
365
let mut x = IteratedEq :: initiate ( ) ;
@@ -938,7 +938,7 @@ generate_unsigned_integer_greater!(u64, 64);
938
938
#[ cfg( feature = "i128" ) ]
939
939
generate_unsigned_integer_greater ! ( u128 , 128 ) ;
940
940
941
- impl < T : ConstantTimeGreater + ConstantTimeEq > ConstantTimeGreater for [ T ] {
941
+ impl < T : ConstantTimeGreater > ConstantTimeGreater for [ T ] {
942
942
/// Compare whether one slice of `ConstantTimeGreater` types is greater than another.
943
943
///
944
944
/// # Note
@@ -953,8 +953,8 @@ impl<T: ConstantTimeGreater + ConstantTimeEq> ConstantTimeGreater for [T] {
953
953
/// Since arrays coerce to slices, this function also works with fixed-size arrays:
954
954
///
955
955
/// ```
956
- /// # use subtle::ConstantTimeGreater;
957
- /// #
956
+ /// use subtle::ConstantTimeGreater;
957
+ ///
958
958
/// let a: [u8; 8] = [0,1,2,3,4,5,6,7];
959
959
/// let b: [u8; 8] = [0,1,2,3,0,1,2,3];
960
960
///
@@ -973,10 +973,10 @@ impl<T: ConstantTimeGreater + ConstantTimeEq> ConstantTimeGreater for [T] {
973
973
match len. cmp ( & _rhs. len ( ) ) {
974
974
Ordering :: Equal => ( ) ,
975
975
Ordering :: Less => {
976
- return Choice :: from ( 0 ) ;
976
+ return Choice :: of_bool ( false ) ;
977
977
}
978
978
Ordering :: Greater => {
979
- return Choice :: from ( 1 ) ;
979
+ return Choice :: of_bool ( true ) ;
980
980
}
981
981
}
982
982
@@ -1099,3 +1099,54 @@ impl LexicographicIteratedLess {
1099
1099
* was_gt |= b. ct_lt ( & a) ;
1100
1100
}
1101
1101
}
1102
+
1103
+ impl < T : ConstantTimeLess > ConstantTimeLess for [ T ] {
1104
+ /// Compare whether one slice of `ConstantTimeLess` types is greater than another.
1105
+ ///
1106
+ /// # Note
1107
+ ///
1108
+ /// This function short-circuits if the lengths of the input slices are different. Otherwise,
1109
+ /// it should execute in time independent of the slice contents. When the slice lengths differ,
1110
+ /// this implementation applies the [shortlex] ordering scheme, which sorts shorter slices
1111
+ /// before longer slices without checking the contents.
1112
+ ///
1113
+ /// [shortlex]: https://en.wikipedia.org/wiki/Shortlex_order
1114
+ ///
1115
+ /// Since arrays coerce to slices, this function also works with fixed-size arrays:
1116
+ ///
1117
+ /// ```
1118
+ /// use subtle::ConstantTimeLess;
1119
+ ///
1120
+ /// let a: [u8; 8] = [0,1,2,3,0,1,2,3];
1121
+ /// let b: [u8; 8] = [0,1,2,3,4,5,6,7];
1122
+ ///
1123
+ /// let a_lt_a = a.ct_lt(&a);
1124
+ /// let a_lt_b = a.ct_lt(&b);
1125
+ ///
1126
+ /// assert_eq!(a_lt_a.unwrap_u8(), 0);
1127
+ /// assert_eq!(a_lt_b.unwrap_u8(), 1);
1128
+ /// ```
1129
+ #[ inline]
1130
+ fn ct_lt ( & self , _rhs : & [ T ] ) -> Choice {
1131
+ let len = self . len ( ) ;
1132
+
1133
+ // Short-circuit on the *lengths* of the slices, not their contents. Here we apply shortlex
1134
+ // ordering, sorting shorter slices before longer ones.
1135
+ match len. cmp ( & _rhs. len ( ) ) {
1136
+ Ordering :: Equal => ( ) ,
1137
+ Ordering :: Less => {
1138
+ return Choice :: of_bool ( true ) ;
1139
+ }
1140
+ Ordering :: Greater => {
1141
+ return Choice :: of_bool ( false ) ;
1142
+ }
1143
+ }
1144
+
1145
+ let mut x = LexicographicIteratedLess :: initiate ( ) ;
1146
+ for ( ai, bi) in self . iter ( ) . zip ( _rhs. iter ( ) ) {
1147
+ x. apply_lt ( ai, bi) ;
1148
+ }
1149
+
1150
+ x. extract_result ( )
1151
+ }
1152
+ }
0 commit comments