diff --git a/benches/boxed_uint.rs b/benches/boxed_uint.rs index dbdf3dc1..28f88fb9 100644 --- a/benches/boxed_uint.rs +++ b/benches/boxed_uint.rs @@ -11,7 +11,7 @@ fn bench_shifts(c: &mut Criterion) { group.bench_function("shl_vartime", |b| { b.iter_batched( || BoxedUint::random(&mut OsRng, UINT_BITS), - |x| black_box(x.shl_vartime(UINT_BITS / 2 + 10)), + |x| black_box(x.overflowing_shl(UINT_BITS / 2 + 10).0), BatchSize::SmallInput, ) }); @@ -27,7 +27,7 @@ fn bench_shifts(c: &mut Criterion) { group.bench_function("shr_vartime", |b| { b.iter_batched( || BoxedUint::random(&mut OsRng, UINT_BITS), - |x| black_box(x.shr_vartime(UINT_BITS / 2 + 10)), + |x| black_box(x.overflowing_shr(UINT_BITS / 2 + 10).0), BatchSize::SmallInput, ) }); diff --git a/src/uint/boxed/bits.rs b/src/uint/boxed/bits.rs index 5567fd61..c3756350 100644 --- a/src/uint/boxed/bits.rs +++ b/src/uint/boxed/bits.rs @@ -140,7 +140,7 @@ mod tests { fn uint_with_bits_at(positions: &[u32]) -> BoxedUint { let mut result = BoxedUint::zero_with_precision(256); for &pos in positions { - result |= BoxedUint::one_with_precision(256).shl_vartime(pos).0; + result |= BoxedUint::one_with_precision(256).overflowing_shl(pos).0; } result } diff --git a/src/uint/boxed/div.rs b/src/uint/boxed/div.rs index 8c4a9671..cfbc8f97 100644 --- a/src/uint/boxed/div.rs +++ b/src/uint/boxed/div.rs @@ -52,7 +52,7 @@ impl BoxedUint { let mut bd = self.bits_precision() - mb; let mut rem = self.clone(); // Will not overflow since `bd < bits_precision` - let mut c = rhs.shl_vartime(bd).0; + let mut c = rhs.overflowing_shl(bd).0; loop { let (r, borrow) = rem.sbb(&c, Limb::ZERO); @@ -135,7 +135,7 @@ impl BoxedUint { let mut remainder = self.clone(); let mut quotient = Self::zero_with_precision(self.bits_precision()); // Will not overflow since `bd < bits_precision` - let mut c = rhs.shl_vartime(bd).0; + let mut c = rhs.overflowing_shl(bd).0; loop { let (mut r, borrow) = remainder.sbb(&c, Limb::ZERO); diff --git a/src/uint/boxed/shl.rs b/src/uint/boxed/shl.rs index b90d74a8..db641641 100644 --- a/src/uint/boxed/shl.rs +++ b/src/uint/boxed/shl.rs @@ -111,25 +111,6 @@ impl BoxedUint { Some(()) } - /// Computes `self << shift`. - /// Returns `None` if `shift >= self.bits_precision()`. - /// - /// NOTE: this operation is variable time with respect to `shift` *ONLY*. - /// - /// When used with a fixed `shift`, this function is constant-time with respect to `self`. - #[inline(always)] - pub fn shl_vartime(&self, shift: u32) -> (Self, ConstChoice) { - let mut result = Self::zero_with_precision(self.bits_precision()); - let success = self.shl_vartime_into(&mut result, shift); - // TODO: is this okay? - - ( - result, - // If success, then return ConstChoice::False since it's not overflowing - success.map_or(ConstChoice::TRUE, |_| ConstChoice::FALSE), - ) - } - /// Computes `self << 1` in constant-time. pub(crate) fn shl1(&self) -> Self { let mut ret = self.clone(); @@ -240,7 +221,7 @@ mod tests { assert_eq!(BoxedUint::from(4u8), &one << 2); assert_eq!( BoxedUint::from(0x80000000000000000u128), - one.shl_vartime(67).0 + one.overflowing_shl(67).0 ); } @@ -248,11 +229,11 @@ mod tests { fn shl_vartime() { let one = BoxedUint::one_with_precision(128); - assert_eq!(BoxedUint::from(2u8), one.shl_vartime(1).0); - assert_eq!(BoxedUint::from(4u8), one.shl_vartime(2).0); + assert_eq!(BoxedUint::from(2u8), one.overflowing_shl(1).0); + assert_eq!(BoxedUint::from(4u8), one.overflowing_shl(2).0); assert_eq!( BoxedUint::from(0x80000000000000000u128), - one.shl_vartime(67).0 + one.overflowing_shl(67).0 ); } } diff --git a/src/uint/boxed/shr.rs b/src/uint/boxed/shr.rs index 08a981c8..e94938f2 100644 --- a/src/uint/boxed/shr.rs +++ b/src/uint/boxed/shr.rs @@ -1,6 +1,6 @@ //! [`BoxedUint`] bitwise right shift operations. -use crate::{BoxedUint, ConstChoice, ConstantTimeSelect, Limb, WrappingShr, Zero}; +use crate::{BoxedUint, ConstantTimeSelect, Limb, WrappingShr, Zero}; use core::ops::{Shr, ShrAssign}; use subtle::{Choice, ConstantTimeLess}; @@ -115,24 +115,6 @@ impl BoxedUint { Some(()) } - /// Computes `self >> shift`. - /// Returns `None` if `shift >= self.bits_precision()`. - /// - /// NOTE: this operation is variable time with respect to `shift` *ONLY*. - /// - /// When used with a fixed `shift`, this function is constant-time with respect to `self`. - #[inline(always)] - pub fn shr_vartime(&self, shift: u32) -> (Self, ConstChoice) { - let mut result = Self::zero_with_precision(self.bits_precision()); - let success = self.shr_vartime_into(&mut result, shift); - // TODO: is this okay? - ( - result, - // If success, then return ConstChoice::False since it's not overflowing - success.map_or(ConstChoice::TRUE, |_| ConstChoice::FALSE), - ) - } - /// Computes `self >> 1` in constant-time, returning a true [`Choice`] /// if the least significant bit was set, and a false [`Choice::FALSE`] otherwise. pub(crate) fn shr1_with_carry(&self) -> (Self, Choice) { @@ -221,9 +203,9 @@ mod tests { #[test] fn shr_vartime() { let n = BoxedUint::from(0x80000000000000000u128); - assert_eq!(BoxedUint::zero(), n.shr_vartime(68).0); - assert_eq!(BoxedUint::one(), n.shr_vartime(67).0); - assert_eq!(BoxedUint::from(2u8), n.shr_vartime(66).0); - assert_eq!(BoxedUint::from(4u8), n.shr_vartime(65).0); + assert_eq!(BoxedUint::zero(), n.overflowing_shr(68).0); + assert_eq!(BoxedUint::one(), n.overflowing_shr(67).0); + assert_eq!(BoxedUint::from(2u8), n.overflowing_shr(66).0); + assert_eq!(BoxedUint::from(4u8), n.overflowing_shr(65).0); } } diff --git a/tests/boxed_uint_proptests.rs b/tests/boxed_uint_proptests.rs index 43b2d9e7..f793878c 100644 --- a/tests/boxed_uint_proptests.rs +++ b/tests/boxed_uint_proptests.rs @@ -3,10 +3,11 @@ #![cfg(feature = "alloc")] use core::cmp::Ordering; -use crypto_bigint::{BoxedUint, CheckedAdd, ConstChoice, Integer, Limb, NonZero}; +use crypto_bigint::{BoxedUint, CheckedAdd, Integer, Limb, NonZero}; use num_bigint::{BigUint, ModInverse}; use num_traits::identities::One; use proptest::prelude::*; +use subtle::Choice; fn to_biguint(uint: &BoxedUint) -> BigUint { BigUint::from_bytes_be(&uint.to_be_bytes()) @@ -239,10 +240,10 @@ proptest! { let shift = u32::from(shift) % (a.bits_precision() * 2); let expected = to_uint((a_bi << shift as usize) & ((BigUint::one() << a.bits_precision() as usize) - BigUint::one())); - let (actual, overflow) = a.shl_vartime(shift); + let (actual, overflow) = a.overflowing_shl(shift); if shift >= a.bits_precision() { - assert!(>::into(overflow)); + assert!(>::into(overflow)); } else { assert_eq!(expected, actual); @@ -275,10 +276,10 @@ proptest! { let shift = u32::from(shift) % (a.bits_precision() * 2); let expected = to_uint(a_bi >> shift as usize); - let (actual, overflow) = a.shr_vartime(shift); + let (actual, overflow) = a.overflowing_shr(shift); if shift >= a.bits_precision() { - assert!(>::into(overflow)); + assert!(>::into(overflow)); } else { assert_eq!(expected, actual); }