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