@@ -299,12 +299,6 @@ pub trait ConstantTimeEq {
299299impl < T : ConstantTimeEq > ConstantTimeEq for [ T ] {
300300 /// Check whether two slices of `ConstantTimeEq` types are equal.
301301 ///
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- ///
308302 /// Since arrays coerce to slices, this function works with fixed-size arrays:
309303 ///
310304 /// ```
@@ -321,23 +315,17 @@ impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
321315 /// ```
322316 #[ inline]
323317 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 ( ) ) ;
331320
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 ) ;
336323 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) ;
338325 }
339326
340- x. into ( )
327+ // Now check that the length and bytes are both equal in constant time
328+ len_ct_eq & contents_ct_eq
341329 }
342330}
343331
0 commit comments