@@ -286,12 +286,6 @@ pub trait ConstantTimeEq {
286
286
impl < T : ConstantTimeEq > ConstantTimeEq for [ T ] {
287
287
/// Check whether two slices of `ConstantTimeEq` types are equal.
288
288
///
289
- /// # Note
290
- ///
291
- /// This function short-circuits if the lengths of the input slices
292
- /// are different. Otherwise, it should execute in time independent
293
- /// of the slice contents.
294
- ///
295
289
/// Since arrays coerce to slices, this function works with fixed-size arrays:
296
290
///
297
291
/// ```
@@ -308,23 +302,17 @@ impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
308
302
/// ```
309
303
#[ inline]
310
304
fn ct_eq ( & self , _rhs : & [ T ] ) -> Choice {
311
- let len = self . len ( ) ;
312
-
313
- // Short-circuit on the *lengths* of the slices, not their
314
- // contents.
315
- if len != _rhs. len ( ) {
316
- return Choice :: from ( 0 ) ;
317
- }
305
+ // Determine if the lengths are equal in constant time
306
+ let len_ct_eq = self . len ( ) . ct_eq ( & _rhs. len ( ) ) ;
318
307
319
- // This loop shouldn't be shortcircuitable, since the compiler
320
- // shouldn't be able to reason about the value of the `u8`
321
- // unwrapped from the `ct_eq` result.
322
- let mut x = 1u8 ;
308
+ // Check each byte for equality in constant time
309
+ let mut contents_ct_eq = Choice :: from ( 1u8 ) ;
323
310
for ( ai, bi) in self . iter ( ) . zip ( _rhs. iter ( ) ) {
324
- x &= ai. ct_eq ( bi) . unwrap_u8 ( ) ;
311
+ contents_ct_eq &= ai. ct_eq ( bi) ;
325
312
}
326
313
327
- x. into ( )
314
+ // Now check that the length and bytes are both equal in constant time
315
+ len_ct_eq & contents_ct_eq
328
316
}
329
317
}
330
318
0 commit comments