|
1 | 1 | //! [`BoxedUint`] bitwise right shift operations. |
2 | 2 |
|
3 | | -use crate::{BoxedUint, Limb}; |
| 3 | +use crate::{BoxedUint, ConstChoice, Limb}; |
4 | 4 | use core::ops::{Shr, ShrAssign}; |
5 | 5 | use subtle::{Choice, ConstantTimeLess}; |
6 | 6 |
|
@@ -76,10 +76,16 @@ impl BoxedUint { |
76 | 76 | /// |
77 | 77 | /// When used with a fixed `shift`, this function is constant-time with respect to `self`. |
78 | 78 | #[inline(always)] |
79 | | - pub fn shr_vartime(&self, shift: u32) -> Option<Self> { |
| 79 | + pub fn shr_vartime(&self, shift: u32) -> (Self, ConstChoice) { |
80 | 80 | let mut result = Self::zero_with_precision(self.bits_precision()); |
81 | | - let success = self.shr_vartime_into(&mut result, shift); |
82 | | - success.map(|_| result) |
| 81 | + if self.shr_vartime_into(&mut result, shift).is_some() { |
| 82 | + return (result, ConstChoice::FALSE); |
| 83 | + } else { |
| 84 | + return ( |
| 85 | + Self::zero_with_precision(self.bits_precision()), |
| 86 | + ConstChoice::TRUE, |
| 87 | + ); |
| 88 | + } |
83 | 89 | } |
84 | 90 |
|
85 | 91 | /// Computes `self >> 1` in constant-time, returning a true [`Choice`] |
@@ -160,9 +166,9 @@ mod tests { |
160 | 166 | #[test] |
161 | 167 | fn shr_vartime() { |
162 | 168 | let n = BoxedUint::from(0x80000000000000000u128); |
163 | | - assert_eq!(BoxedUint::zero(), n.shr_vartime(68).unwrap()); |
164 | | - assert_eq!(BoxedUint::one(), n.shr_vartime(67).unwrap()); |
165 | | - assert_eq!(BoxedUint::from(2u8), n.shr_vartime(66).unwrap()); |
166 | | - assert_eq!(BoxedUint::from(4u8), n.shr_vartime(65).unwrap()); |
| 169 | + assert_eq!(BoxedUint::zero(), n.shr_vartime(68).0); |
| 170 | + assert_eq!(BoxedUint::one(), n.shr_vartime(67).0); |
| 171 | + assert_eq!(BoxedUint::from(2u8), n.shr_vartime(66).0); |
| 172 | + assert_eq!(BoxedUint::from(4u8), n.shr_vartime(65).0); |
167 | 173 | } |
168 | 174 | } |
0 commit comments