diff --git a/src/ct_choice.rs b/src/ct_choice.rs index 205564e63..40c49dee7 100644 --- a/src/ct_choice.rs +++ b/src/ct_choice.rs @@ -6,9 +6,9 @@ use crate::Word; // TODO: should be replaced by `subtle::Choice` or `CtOption` // when `subtle` starts supporting const fns. #[derive(Debug, Copy, Clone)] -pub struct CtChoice(Word); +pub struct ConstChoice(Word); -impl CtChoice { +impl ConstChoice { /// The falsy value. pub const FALSE: Self = Self(0); @@ -137,7 +137,7 @@ impl CtChoice { #[inline] pub(crate) const fn is_true_vartime(&self) -> bool { - self.0 == CtChoice::TRUE.0 + self.0 == ConstChoice::TRUE.0 } #[inline] @@ -146,19 +146,19 @@ impl CtChoice { } } -impl From for Choice { - fn from(choice: CtChoice) -> Self { +impl From for Choice { + fn from(choice: ConstChoice) -> Self { Choice::from(choice.to_u8()) } } -impl From for bool { - fn from(choice: CtChoice) -> Self { +impl From for bool { + fn from(choice: ConstChoice) -> Self { choice.is_true_vartime() } } -impl PartialEq for CtChoice { +impl PartialEq for ConstChoice { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } @@ -166,14 +166,14 @@ impl PartialEq for CtChoice { #[cfg(test)] mod tests { - use super::CtChoice; + use super::ConstChoice; use crate::Word; #[test] fn select() { let a: Word = 1; let b: Word = 2; - assert_eq!(CtChoice::TRUE.select_word(a, b), b); - assert_eq!(CtChoice::FALSE.select_word(a, b), a); + assert_eq!(ConstChoice::TRUE.select_word(a, b), b); + assert_eq!(ConstChoice::FALSE.select_word(a, b), a); } } diff --git a/src/lib.rs b/src/lib.rs index ecf524cd3..ece307087 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -176,7 +176,7 @@ mod wrapping; pub use crate::{ checked::Checked, - ct_choice::CtChoice, + ct_choice::ConstChoice, limb::{Limb, WideWord, Word}, non_zero::NonZero, traits::*, diff --git a/src/limb/cmp.rs b/src/limb/cmp.rs index 1de0f443e..834270c5e 100644 --- a/src/limb/cmp.rs +++ b/src/limb/cmp.rs @@ -1,6 +1,6 @@ //! Limb comparisons -use crate::{CtChoice, Limb}; +use crate::{ConstChoice, Limb}; use core::cmp::Ordering; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -28,14 +28,14 @@ impl Limb { /// Return `b` if `c` is truthy, otherwise return `a`. #[inline] - pub(crate) const fn ct_select(a: Self, b: Self, c: CtChoice) -> Self { + pub(crate) const fn select(a: Self, b: Self, c: ConstChoice) -> Self { Self(c.select_word(a.0, b.0)) } /// Returns the truthy value if `self != 0` and the falsy value otherwise. #[inline] - pub(crate) const fn ct_is_nonzero(&self) -> CtChoice { - CtChoice::from_word_nonzero(self.0) + pub(crate) const fn is_nonzero(&self) -> ConstChoice { + ConstChoice::from_word_nonzero(self.0) } } diff --git a/src/modular/div_by_2.rs b/src/modular/div_by_2.rs index 12d82ed79..1ad53b2a6 100644 --- a/src/modular/div_by_2.rs +++ b/src/modular/div_by_2.rs @@ -26,5 +26,5 @@ pub(crate) fn div_by_2(a: &Uint, modulus: &Uint::ONE); - Uint::::ct_select(&if_even, &if_odd, is_odd) + Uint::::select(&if_even, &if_odd, is_odd) } diff --git a/src/modular/dyn_residue/inv.rs b/src/modular/dyn_residue/inv.rs index f41c5aae3..0f9a59316 100644 --- a/src/modular/dyn_residue/inv.rs +++ b/src/modular/dyn_residue/inv.rs @@ -1,7 +1,7 @@ //! Multiplicative inverses of residues with a modulus set at runtime. use super::DynResidue; -use crate::{modular::inv::inv_montgomery_form, traits::Invert, CtChoice}; +use crate::{modular::inv::inv_montgomery_form, traits::Invert, ConstChoice}; use subtle::CtOption; impl DynResidue { @@ -9,7 +9,7 @@ impl DynResidue { /// I.e. `self * self^-1 = 1`. /// If the number was invertible, the second element of the tuple is the truthy value, /// otherwise it is the falsy value (in which case the first element's value is unspecified). - pub const fn invert(&self) -> (Self, CtChoice) { + pub const fn invert(&self) -> (Self, ConstChoice) { let (montgomery_form, is_some) = inv_montgomery_form( &self.montgomery_form, &self.residue_params.modulus, diff --git a/src/modular/inv.rs b/src/modular/inv.rs index 408c03fb8..e4daff198 100644 --- a/src/modular/inv.rs +++ b/src/modular/inv.rs @@ -1,11 +1,11 @@ -use crate::{modular::reduction::montgomery_reduction, CtChoice, Limb, Uint}; +use crate::{modular::reduction::montgomery_reduction, ConstChoice, Limb, Uint}; pub const fn inv_montgomery_form( x: &Uint, modulus: &Uint, r3: &Uint, mod_neg_inv: Limb, -) -> (Uint, CtChoice) { +) -> (Uint, ConstChoice) { let (inverse, is_some) = x.inv_odd_mod(modulus); ( montgomery_reduction(&inverse.mul_wide(r3), modulus, mod_neg_inv), diff --git a/src/modular/pow.rs b/src/modular/pow.rs index 5f6d74e8e..b750c4e0f 100644 --- a/src/modular/pow.rs +++ b/src/modular/pow.rs @@ -1,4 +1,4 @@ -use crate::{CtChoice, Limb, Uint, Word}; +use crate::{ConstChoice, Limb, Uint, Word}; use super::mul::{mul_montgomery_form, square_montgomery_form}; @@ -163,8 +163,8 @@ const fn multi_exponentiate_montgomery_form_internal::ct_select(&power, &powers[j as usize], choice); + let choice = ConstChoice::from_word_eq(j, idx); + power = Uint::::select(&power, &powers[j as usize], choice); j += 1; } diff --git a/src/modular/residue.rs b/src/modular/residue.rs index b74f66e60..e58348f4e 100644 --- a/src/modular/residue.rs +++ b/src/modular/residue.rs @@ -204,7 +204,7 @@ where D: Deserializer<'de>, { Uint::::deserialize(deserializer).and_then(|montgomery_form| { - if Uint::ct_lt(&montgomery_form, &MOD::MODULUS).into() { + if montgomery_form < MOD::MODULUS.0 { Ok(Self { montgomery_form, phantom: PhantomData, diff --git a/src/modular/residue/inv.rs b/src/modular/residue/inv.rs index 06eb4a790..844a8a76a 100644 --- a/src/modular/residue/inv.rs +++ b/src/modular/residue/inv.rs @@ -1,7 +1,7 @@ //! Multiplicative inverses of residues with a constant modulus. use super::{Residue, ResidueParams}; -use crate::{modular::inv::inv_montgomery_form, traits::Invert, CtChoice, NonZero}; +use crate::{modular::inv::inv_montgomery_form, traits::Invert, ConstChoice, NonZero}; use core::marker::PhantomData; use subtle::CtOption; @@ -10,7 +10,7 @@ impl, const LIMBS: usize> Residue { /// I.e. `self * self^-1 = 1`. /// If the number was invertible, the second element of the tuple is the truthy value, /// otherwise it is the falsy value (in which case the first element's value is unspecified). - pub const fn invert(&self) -> (Self, CtChoice) { + pub const fn invert(&self) -> (Self, ConstChoice) { let (montgomery_form, is_some) = inv_montgomery_form( &self.montgomery_form, &MOD::MODULUS.0, diff --git a/src/non_zero.rs b/src/non_zero.rs index cd6af0753..3c00148ee 100644 --- a/src/non_zero.rs +++ b/src/non_zero.rs @@ -1,6 +1,6 @@ //! Wrapper type for non-zero integers. -use crate::{Bounded, Constants, CtChoice, Encoding, Limb, Uint, Zero}; +use crate::{Bounded, ConstChoice, Constants, Encoding, Limb, Uint, Zero}; use core::{ fmt, num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8}, @@ -27,16 +27,16 @@ pub struct NonZero(pub(crate) T); impl NonZero { /// Creates a new non-zero limb in a const context. /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise. - pub const fn const_new(n: Limb) -> (Self, CtChoice) { - (Self(n), n.ct_is_nonzero()) + pub const fn const_new(n: Limb) -> (Self, ConstChoice) { + (Self(n), n.is_nonzero()) } } impl NonZero> { /// Creates a new non-zero integer in a const context. /// The second return value is `FALSE` if `n` is zero, `TRUE` otherwise. - pub const fn const_new(n: Uint) -> (Self, CtChoice) { - (Self(n), n.ct_is_nonzero()) + pub const fn const_new(n: Uint) -> (Self, ConstChoice) { + (Self(n), n.is_nonzero()) } } diff --git a/src/uint/add.rs b/src/uint/add.rs index 94047743e..402c48a63 100644 --- a/src/uint/add.rs +++ b/src/uint/add.rs @@ -1,6 +1,6 @@ //! [`Uint`] addition operations. -use crate::{Checked, CheckedAdd, CtChoice, Limb, Uint, Wrapping, Zero}; +use crate::{Checked, CheckedAdd, ConstChoice, Limb, Uint, Wrapping, Zero}; use core::ops::{Add, AddAssign}; use subtle::CtOption; @@ -24,7 +24,7 @@ impl Uint { /// Perform saturating addition, returning `MAX` on overflow. pub const fn saturating_add(&self, rhs: &Self) -> Self { let (res, overflow) = self.adc(rhs, Limb::ZERO); - Self::ct_select(&res, &Self::MAX, CtChoice::from_word_lsb(overflow.0)) + Self::select(&res, &Self::MAX, ConstChoice::from_word_lsb(overflow.0)) } /// Perform wrapping addition, discarding overflow. @@ -37,11 +37,11 @@ impl Uint { pub(crate) const fn conditional_wrapping_add( &self, rhs: &Self, - choice: CtChoice, - ) -> (Self, CtChoice) { - let actual_rhs = Uint::ct_select(&Uint::ZERO, rhs, choice); + choice: ConstChoice, + ) -> (Self, ConstChoice) { + let actual_rhs = Uint::select(&Uint::ZERO, rhs, choice); let (sum, carry) = self.adc(&actual_rhs, Limb::ZERO); - (sum, CtChoice::from_word_lsb(carry.0)) + (sum, ConstChoice::from_word_lsb(carry.0)) } } diff --git a/src/uint/bits.rs b/src/uint/bits.rs index 70eb584b5..30682cb31 100644 --- a/src/uint/bits.rs +++ b/src/uint/bits.rs @@ -1,9 +1,9 @@ -use crate::{CtChoice, Limb, Uint}; +use crate::{ConstChoice, Limb, Uint}; impl Uint { - /// Get the value of the bit at position `index`, as a truthy or falsy `CtChoice`. + /// Get the value of the bit at position `index`, as a truthy or falsy `ConstChoice`. /// Returns the falsy value for indices out of range. - pub const fn bit(&self, index: u32) -> CtChoice { + pub const fn bit(&self, index: u32) -> ConstChoice { let limb_num = index / Limb::BITS; let index_in_limb = index % Limb::BITS; let index_mask = 1 << index_in_limb; @@ -14,12 +14,12 @@ impl Uint { let mut i = 0; while i < LIMBS { let bit = limbs[i] & index_mask; - let is_right_limb = CtChoice::from_u32_eq(i as u32, limb_num); + let is_right_limb = ConstChoice::from_u32_eq(i as u32, limb_num); result |= is_right_limb.if_true_word(bit); i += 1; } - CtChoice::from_word_lsb(result >> index_in_limb) + ConstChoice::from_word_lsb(result >> index_in_limb) } /// Returns `true` if the bit at position `index` is set, `false` otherwise. @@ -59,14 +59,14 @@ impl Uint { let mut count = 0; let mut i = LIMBS; - let mut nonzero_limb_not_encountered = CtChoice::TRUE; + let mut nonzero_limb_not_encountered = ConstChoice::TRUE; while i > 0 { i -= 1; let l = limbs[i]; let z = l.leading_zeros(); count += nonzero_limb_not_encountered.if_true_u32(z); nonzero_limb_not_encountered = - nonzero_limb_not_encountered.and(CtChoice::from_word_nonzero(l.0).not()); + nonzero_limb_not_encountered.and(ConstChoice::from_word_nonzero(l.0).not()); } count @@ -98,13 +98,13 @@ impl Uint { let mut count = 0; let mut i = 0; - let mut nonzero_limb_not_encountered = CtChoice::TRUE; + let mut nonzero_limb_not_encountered = ConstChoice::TRUE; while i < LIMBS { let l = limbs[i]; let z = l.trailing_zeros(); count += nonzero_limb_not_encountered.if_true_u32(z); nonzero_limb_not_encountered = - nonzero_limb_not_encountered.and(CtChoice::from_word_nonzero(l.0).not()); + nonzero_limb_not_encountered.and(ConstChoice::from_word_nonzero(l.0).not()); i += 1; } @@ -137,13 +137,13 @@ impl Uint { let mut count = 0; let mut i = 0; - let mut nonmax_limb_not_encountered = CtChoice::TRUE; + let mut nonmax_limb_not_encountered = ConstChoice::TRUE; while i < LIMBS { let l = limbs[i]; let z = l.trailing_ones(); count += nonmax_limb_not_encountered.if_true_u32(z); nonmax_limb_not_encountered = - nonmax_limb_not_encountered.and(CtChoice::from_word_eq(l.0, Limb::MAX.0)); + nonmax_limb_not_encountered.and(ConstChoice::from_word_eq(l.0, Limb::MAX.0)); i += 1; } @@ -171,7 +171,7 @@ impl Uint { } /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`. - pub(crate) const fn set_bit(self, index: u32, bit_value: CtChoice) -> Self { + pub(crate) const fn set_bit(self, index: u32, bit_value: ConstChoice) -> Self { let mut result = self; let limb_num = index / Limb::BITS; let index_in_limb = index % Limb::BITS; @@ -179,7 +179,7 @@ impl Uint { let mut i = 0; while i < LIMBS { - let is_right_limb = CtChoice::from_u32_eq(i as u32, limb_num); + let is_right_limb = ConstChoice::from_u32_eq(i as u32, limb_num); let old_limb = result.limbs[i].0; let new_limb = bit_value.select_word(old_limb & !index_mask, old_limb | index_mask); result.limbs[i] = Limb(is_right_limb.select_word(old_limb, new_limb)); @@ -191,7 +191,7 @@ impl Uint { #[cfg(test)] mod tests { - use crate::{CtChoice, U256}; + use crate::{ConstChoice, U256}; fn uint_with_bits_at(positions: &[u32]) -> U256 { let mut result = U256::ZERO; @@ -337,25 +337,25 @@ mod tests { fn set_bit() { let u = uint_with_bits_at(&[16, 79, 150]); assert_eq!( - u.set_bit(127, CtChoice::TRUE), + u.set_bit(127, ConstChoice::TRUE), uint_with_bits_at(&[16, 79, 127, 150]) ); let u = uint_with_bits_at(&[16, 79, 150]); assert_eq!( - u.set_bit(150, CtChoice::TRUE), + u.set_bit(150, ConstChoice::TRUE), uint_with_bits_at(&[16, 79, 150]) ); let u = uint_with_bits_at(&[16, 79, 150]); assert_eq!( - u.set_bit(127, CtChoice::FALSE), + u.set_bit(127, ConstChoice::FALSE), uint_with_bits_at(&[16, 79, 150]) ); let u = uint_with_bits_at(&[16, 79, 150]); assert_eq!( - u.set_bit(150, CtChoice::FALSE), + u.set_bit(150, ConstChoice::FALSE), uint_with_bits_at(&[16, 79]) ); } diff --git a/src/uint/boxed/cmp.rs b/src/uint/boxed/cmp.rs index a3bf5b0a6..14bef8d1f 100644 --- a/src/uint/boxed/cmp.rs +++ b/src/uint/boxed/cmp.rs @@ -5,7 +5,7 @@ pub(super) use core::cmp::{max, Ordering}; use super::BoxedUint; -use crate::{CtChoice, Limb}; +use crate::{ConstChoice, Limb}; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, }; @@ -30,7 +30,7 @@ impl ConstantTimeGreater for BoxedUint { #[inline] fn ct_gt(&self, other: &Self) -> Choice { let (_, borrow) = other.sbb(self, Limb::ZERO); - CtChoice::from_word_mask(borrow.0).into() + ConstChoice::from_word_mask(borrow.0).into() } } @@ -38,7 +38,7 @@ impl ConstantTimeLess for BoxedUint { #[inline] fn ct_lt(&self, other: &Self) -> Choice { let (_, borrow) = self.sbb(other, Limb::ZERO); - CtChoice::from_word_mask(borrow.0).into() + ConstChoice::from_word_mask(borrow.0).into() } } diff --git a/src/uint/boxed/inv_mod.rs b/src/uint/boxed/inv_mod.rs index d873ef577..e47969588 100644 --- a/src/uint/boxed/inv_mod.rs +++ b/src/uint/boxed/inv_mod.rs @@ -38,8 +38,8 @@ impl BoxedUint { /// Computes 1/`self` mod `2^k`. /// /// If the inverse does not exist (`k > 0` and `self` is even), - /// returns `CtChoice::FALSE` as the second element of the tuple, - /// otherwise returns `CtChoice::TRUE`. + /// returns `ConstChoice::FALSE` as the second element of the tuple, + /// otherwise returns `ConstChoice::TRUE`. pub(crate) fn inv_mod2k(&self, k: u32) -> (Self, Choice) { let mut x = Self::zero_with_precision(self.bits_precision()); // keeps `x` during iterations let mut b = Self::one_with_precision(self.bits_precision()); // keeps `b_i` during iterations diff --git a/src/uint/cmp.rs b/src/uint/cmp.rs index e2740d179..f4fa58a04 100644 --- a/src/uint/cmp.rs +++ b/src/uint/cmp.rs @@ -3,19 +3,19 @@ //! By default these are all constant-time and use the `subtle` crate. use super::Uint; -use crate::{CtChoice, Limb}; +use crate::{ConstChoice, Limb}; use core::cmp::Ordering; use subtle::{Choice, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess}; impl Uint { /// Return `b` if `c` is truthy, otherwise return `a`. #[inline] - pub(crate) const fn ct_select(a: &Self, b: &Self, c: CtChoice) -> Self { + pub(crate) const fn select(a: &Self, b: &Self, c: ConstChoice) -> Self { let mut limbs = [Limb::ZERO; LIMBS]; let mut i = 0; while i < LIMBS { - limbs[i] = Limb::ct_select(a.limbs[i], b.limbs[i], c); + limbs[i] = Limb::select(a.limbs[i], b.limbs[i], c); i += 1; } @@ -23,33 +23,33 @@ impl Uint { } #[inline] - pub(crate) const fn ct_swap(a: &Self, b: &Self, c: CtChoice) -> (Self, Self) { - let new_a = Self::ct_select(a, b, c); - let new_b = Self::ct_select(b, a, c); + pub(crate) const fn swap(a: &Self, b: &Self, c: ConstChoice) -> (Self, Self) { + let new_a = Self::select(a, b, c); + let new_b = Self::select(b, a, c); (new_a, new_b) } /// Returns the truthy value if `self`!=0 or the falsy value otherwise. #[inline] - pub(crate) const fn ct_is_nonzero(&self) -> CtChoice { + pub(crate) const fn is_nonzero(&self) -> ConstChoice { let mut b = 0; let mut i = 0; while i < LIMBS { b |= self.limbs[i].0; i += 1; } - Limb(b).ct_is_nonzero() + Limb(b).is_nonzero() } /// Returns the truthy value if `self` is odd or the falsy value otherwise. - pub(crate) const fn ct_is_odd(&self) -> CtChoice { - CtChoice::from_word_lsb(self.limbs[0].0 & 1) + pub(crate) const fn is_odd(&self) -> ConstChoice { + ConstChoice::from_word_lsb(self.limbs[0].0 & 1) } /// Returns the truthy value if `self == rhs` or the falsy value otherwise. #[inline] - pub(crate) const fn ct_eq(lhs: &Self, rhs: &Self) -> CtChoice { + pub(crate) const fn eq(lhs: &Self, rhs: &Self) -> ConstChoice { let mut acc = 0; let mut i = 0; @@ -59,24 +59,24 @@ impl Uint { } // acc == 0 if and only if self == rhs - Limb(acc).ct_is_nonzero().not() + Limb(acc).is_nonzero().not() } /// Returns the truthy value if `self <= rhs` and the falsy value otherwise. #[inline] - pub(crate) const fn ct_lt(lhs: &Self, rhs: &Self) -> CtChoice { + pub(crate) const fn lt(lhs: &Self, rhs: &Self) -> ConstChoice { // We could use the same approach as in Limb::ct_lt(), // but since we have to use Uint::wrapping_sub(), which calls `sbb()`, // there are no savings compared to just calling `sbb()` directly. let (_res, borrow) = lhs.sbb(rhs, Limb::ZERO); - CtChoice::from_word_mask(borrow.0) + ConstChoice::from_word_mask(borrow.0) } /// Returns the truthy value if `self >= rhs` and the falsy value otherwise. #[inline] - pub(crate) const fn ct_gt(lhs: &Self, rhs: &Self) -> CtChoice { + pub(crate) const fn gt(lhs: &Self, rhs: &Self) -> ConstChoice { let (_res, borrow) = rhs.sbb(lhs, Limb::ZERO); - CtChoice::from_word_mask(borrow.0) + ConstChoice::from_word_mask(borrow.0) } /// Returns the ordering between `self` and `rhs` as an i8. @@ -85,7 +85,7 @@ impl Uint { /// 0 is Equal /// 1 is Greater #[inline] - pub(crate) const fn ct_cmp(lhs: &Self, rhs: &Self) -> i8 { + pub(crate) const fn cmp(lhs: &Self, rhs: &Self) -> i8 { let mut i = 0; let mut borrow = Limb::ZERO; let mut diff = Limb::ZERO; @@ -97,7 +97,7 @@ impl Uint { i += 1; } let sgn = ((borrow.0 & 2) as i8) - 1; - (diff.ct_is_nonzero().to_u8() as i8) * sgn + (diff.is_nonzero().to_u8() as i8) * sgn } /// Returns the Ordering between `self` and `rhs` in variable time. @@ -123,21 +123,21 @@ impl Uint { impl ConstantTimeEq for Uint { #[inline] fn ct_eq(&self, other: &Self) -> Choice { - Uint::ct_eq(self, other).into() + Uint::eq(self, other).into() } } impl ConstantTimeGreater for Uint { #[inline] fn ct_gt(&self, other: &Self) -> Choice { - Uint::ct_gt(self, other).into() + Uint::gt(self, other).into() } } impl ConstantTimeLess for Uint { #[inline] fn ct_lt(&self, other: &Self) -> Choice { - Uint::ct_lt(self, other).into() + Uint::lt(self, other).into() } } @@ -145,7 +145,7 @@ impl Eq for Uint {} impl Ord for Uint { fn cmp(&self, other: &Self) -> Ordering { - let c = Self::ct_cmp(self, other); + let c = Self::cmp(self, other); match c { -1 => Ordering::Less, 0 => Ordering::Equal, @@ -181,9 +181,15 @@ mod tests { #[test] fn is_odd() { + // inherent methods assert!(!bool::from(U128::ZERO.is_odd())); assert!(bool::from(U128::ONE.is_odd())); assert!(bool::from(U128::MAX.is_odd())); + + // `Integer` methods + assert!(!bool::from(::is_odd(&U128::ZERO))); + assert!(bool::from(::is_odd(&U128::ONE))); + assert!(bool::from(::is_odd(&U128::MAX))); } #[test] diff --git a/src/uint/div.rs b/src/uint/div.rs index 7e22f72e4..98f6f3c81 100644 --- a/src/uint/div.rs +++ b/src/uint/div.rs @@ -1,7 +1,7 @@ //! [`Uint`] division operations. use super::div_limb::{div_rem_limb_with_reciprocal, Reciprocal}; -use crate::{CheckedDiv, CtChoice, Limb, NonZero, Uint, Word, Wrapping}; +use crate::{CheckedDiv, ConstChoice, Limb, NonZero, Uint, Word, Wrapping}; use core::ops::{Div, DivAssign, Rem, RemAssign}; use subtle::CtOption; @@ -31,21 +31,21 @@ impl Uint { let (mut c, _overflow) = rhs.0.shl(Self::BITS - mb); let mut i = Self::BITS; - let mut done = CtChoice::FALSE; + let mut done = ConstChoice::FALSE; loop { let (mut r, borrow) = rem.sbb(&c, Limb::ZERO); - rem = Self::ct_select(&r, &rem, CtChoice::from_word_mask(borrow.0).or(done)); + rem = Self::select(&r, &rem, ConstChoice::from_word_mask(borrow.0).or(done)); r = quo.bitor(&Self::ONE); - quo = Self::ct_select(&r, &quo, CtChoice::from_word_mask(borrow.0).or(done)); + quo = Self::select(&r, &quo, ConstChoice::from_word_mask(borrow.0).or(done)); if i == 0 { break; } i -= 1; // when `i < mb`, the computation is actually done, so we ensure `quo` and `rem` // aren't modified further (but do the remaining iterations anyway to be constant-time) - done = CtChoice::from_word_lt(i as Word, mb as Word); + done = ConstChoice::from_word_lt(i as Word, mb as Word); c = c.shr1(); - quo = Self::ct_select(&quo.shl1(), &quo, done); + quo = Self::select(&quo.shl1(), &quo, done); } (quo, rem) @@ -68,9 +68,9 @@ impl Uint { loop { let (mut r, borrow) = rem.sbb(&c, Limb::ZERO); - rem = Self::ct_select(&r, &rem, CtChoice::from_word_mask(borrow.0)); + rem = Self::select(&r, &rem, ConstChoice::from_word_mask(borrow.0)); r = quo.bitor(&Self::ONE); - quo = Self::ct_select(&r, &quo, CtChoice::from_word_mask(borrow.0)); + quo = Self::select(&r, &quo, ConstChoice::from_word_mask(borrow.0)); if bd == 0 { break; } @@ -96,7 +96,7 @@ impl Uint { loop { let (r, borrow) = rem.sbb(&c, Limb::ZERO); - rem = Self::ct_select(&r, &rem, CtChoice::from_word_mask(borrow.0)); + rem = Self::select(&r, &rem, ConstChoice::from_word_mask(borrow.0)); if bd == 0 { break; } @@ -129,8 +129,8 @@ impl Uint { let (lower_sub, borrow) = lower.sbb(&c.0, Limb::ZERO); let (upper_sub, borrow) = upper.sbb(&c.1, borrow); - lower = Self::ct_select(&lower_sub, &lower, CtChoice::from_word_mask(borrow.0)); - upper = Self::ct_select(&upper_sub, &upper, CtChoice::from_word_mask(borrow.0)); + lower = Self::select(&lower_sub, &lower, ConstChoice::from_word_mask(borrow.0)); + upper = Self::select(&upper_sub, &upper, ConstChoice::from_word_mask(borrow.0)); if bd == 0 { break; } @@ -147,7 +147,7 @@ impl Uint { pub const fn rem2k(&self, k: u32) -> Self { let highest = (LIMBS - 1) as u32; let index = k / Limb::BITS; - let le = CtChoice::from_u32_le(index, highest); + let le = ConstChoice::from_u32_le(index, highest); let limb_num = le.select_u32(highest, index) as usize; let base = k % Limb::BITS; @@ -156,7 +156,7 @@ impl Uint { let outmask = Limb(out.limbs[limb_num].0 & mask); - out.limbs[limb_num] = Limb::ct_select(out.limbs[limb_num], outmask, le); + out.limbs[limb_num] = Limb::select(out.limbs[limb_num], outmask, le); // TODO: this is not constant-time. let mut i = limb_num + 1; diff --git a/src/uint/div_limb.rs b/src/uint/div_limb.rs index f86b65a56..8e74b5335 100644 --- a/src/uint/div_limb.rs +++ b/src/uint/div_limb.rs @@ -3,7 +3,7 @@ //! (DOI: 10.1109/TC.2010.143, ). use subtle::{Choice, ConditionallySelectable}; -use crate::{CtChoice, Limb, NonZero, Uint, WideWord, Word}; +use crate::{ConstChoice, Limb, NonZero, Uint, WideWord, Word}; /// Calculates the reciprocal of the given 32-bit divisor with the highmost bit set. #[cfg(target_pointer_width = "32")] @@ -33,7 +33,7 @@ pub const fn reciprocal(d: Word) -> Word { // Hence the `ct_select()`. let x = v2.wrapping_add(1); let (hi, _lo) = mulhilo(x, d); - let hi = CtChoice::from_u32_nonzero(x).select_word(d, hi); + let hi = ConstChoice::from_u32_nonzero(x).select_word(d, hi); v2.wrapping_sub(hi).wrapping_sub(d) } @@ -63,21 +63,21 @@ pub const fn reciprocal(d: Word) -> Word { // Hence the `ct_select()`. let x = v3.wrapping_add(1); let (hi, _lo) = mulhilo(x, d); - let hi = CtChoice::from_word_nonzero(x).select_word(d, hi); + let hi = ConstChoice::from_word_nonzero(x).select_word(d, hi); v3.wrapping_sub(hi).wrapping_sub(d) } /// Returns `u32::MAX` if `a < b` and `0` otherwise. #[inline] -const fn ct_lt(a: u32, b: u32) -> u32 { +const fn lt(a: u32, b: u32) -> u32 { let bit = (((!a) & b) | (((!a) | b) & (a.wrapping_sub(b)))) >> (u32::BITS - 1); bit.wrapping_neg() } /// Returns `a` if `c == 0` and `b` if `c == u32::MAX`. #[inline(always)] -const fn ct_select(a: u32, b: u32, c: u32) -> u32 { +const fn select(a: u32, b: u32, c: u32) -> u32 { a ^ (c & (a ^ b)) } @@ -101,8 +101,8 @@ const fn short_div(dividend: u32, dividend_bits: u32, divisor: u32, divisor_bits while i > 0 { i -= 1; - let bit = ct_lt(dividend, divisor); - dividend = ct_select(dividend.wrapping_sub(divisor), dividend, bit); + let bit = lt(dividend, divisor); + dividend = select(dividend.wrapping_sub(divisor), dividend, bit); divisor >>= 1; let inv_bit = !bit; quotient |= (inv_bit >> (u32::BITS - 1)) << i; @@ -142,7 +142,7 @@ const fn div2by1(u1: Word, u0: Word, reciprocal: &Reciprocal) -> (Word, Word) { let q1 = q1.wrapping_add(1); let r = u0.wrapping_sub(q1.wrapping_mul(d)); - let r_gt_q0 = CtChoice::from_word_lt(q0, r); + let r_gt_q0 = ConstChoice::from_word_lt(q0, r); let q1 = r_gt_q0.select_word(q1, q1.wrapping_sub(1)); let r = r_gt_q0.select_word(r, r.wrapping_add(d)); @@ -150,7 +150,7 @@ const fn div2by1(u1: Word, u0: Word, reciprocal: &Reciprocal) -> (Word, Word) { // But since we calculate both results either way, we have to wrap. // Added an assert to still check the lack of overflow in debug mode. debug_assert!(r < d || q1 < Word::MAX); - let r_ge_d = CtChoice::from_word_le(d, r); + let r_ge_d = ConstChoice::from_word_le(d, r); let q1 = r_ge_d.select_word(q1, q1.wrapping_add(1)); let r = r_ge_d.select_word(r, r.wrapping_sub(d)); diff --git a/src/uint/inv_mod.rs b/src/uint/inv_mod.rs index 236f0ac1c..80e7ecbec 100644 --- a/src/uint/inv_mod.rs +++ b/src/uint/inv_mod.rs @@ -1,14 +1,14 @@ use super::Uint; -use crate::CtChoice; +use crate::ConstChoice; impl Uint { /// Computes 1/`self` mod `2^k`. /// This method is constant-time w.r.t. `self` but not `k`. /// /// If the inverse does not exist (`k > 0` and `self` is even), - /// returns `CtChoice::FALSE` as the second element of the tuple, - /// otherwise returns `CtChoice::TRUE`. - pub const fn inv_mod2k_vartime(&self, k: u32) -> (Self, CtChoice) { + /// returns `ConstChoice::FALSE` as the second element of the tuple, + /// otherwise returns `ConstChoice::TRUE`. + pub const fn inv_mod2k_vartime(&self, k: u32) -> (Self, ConstChoice) { // Using the Algorithm 3 from "A Secure Algorithm for Inversion Modulo 2k" // by Sadiel de la Fe and Carles Ferrer. // See . @@ -21,14 +21,14 @@ impl Uint { let mut i = 0; // The inverse exists either if `k` is 0 or if `self` is odd. - let is_some = CtChoice::from_u32_nonzero(k).not().or(self.ct_is_odd()); + let is_some = ConstChoice::from_u32_nonzero(k).not().or(self.is_odd()); while i < k { // X_i = b_i mod 2 let x_i = b.limbs[0].0 & 1; - let x_i_choice = CtChoice::from_word_lsb(x_i); + let x_i_choice = ConstChoice::from_word_lsb(x_i); // b_{i+1} = (b_i - a * X_i) / 2 - b = Self::ct_select(&b, &b.wrapping_sub(self), x_i_choice).shr1(); + b = Self::select(&b, &b.wrapping_sub(self), x_i_choice).shr1(); // Store the X_i bit in the result (x = x | (1 << X_i)) let (shifted, _overflow) = Uint::from_word(x_i).shl_vartime(i); x = x.bitor(&shifted); @@ -42,9 +42,9 @@ impl Uint { /// Computes 1/`self` mod `2^k`. /// /// If the inverse does not exist (`k > 0` and `self` is even), - /// returns `CtChoice::FALSE` as the second element of the tuple, - /// otherwise returns `CtChoice::TRUE`. - pub const fn inv_mod2k(&self, k: u32) -> (Self, CtChoice) { + /// returns `ConstChoice::FALSE` as the second element of the tuple, + /// otherwise returns `ConstChoice::TRUE`. + pub const fn inv_mod2k(&self, k: u32) -> (Self, ConstChoice) { // This is the same algorithm as in `inv_mod2k_vartime()`, // but made constant-time w.r.t `k` as well. @@ -53,18 +53,18 @@ impl Uint { let mut i = 0; // The inverse exists either if `k` is 0 or if `self` is odd. - let is_some = CtChoice::from_u32_nonzero(k).not().or(self.ct_is_odd()); + let is_some = ConstChoice::from_u32_nonzero(k).not().or(self.is_odd()); while i < Self::BITS { // Only iterations for i = 0..k need to change `x`, // the rest are dummy ones performed for the sake of constant-timeness. - let within_range = CtChoice::from_u32_lt(i, k); + let within_range = ConstChoice::from_u32_lt(i, k); // X_i = b_i mod 2 let x_i = b.limbs[0].0 & 1; - let x_i_choice = CtChoice::from_word_lsb(x_i); + let x_i_choice = ConstChoice::from_word_lsb(x_i); // b_{i+1} = (b_i - self * X_i) / 2 - b = Self::ct_select(&b, &b.wrapping_sub(self), x_i_choice).shr1(); + b = Self::select(&b, &b.wrapping_sub(self), x_i_choice).shr1(); // Store the X_i bit in the result (x = x | (1 << X_i)) // Don't change the result in dummy iterations. @@ -93,7 +93,7 @@ impl Uint { modulus: &Self, bits: u32, modulus_bits: u32, - ) -> (Self, CtChoice) { + ) -> (Self, ConstChoice) { let mut a = *self; let mut u = Uint::ONE; @@ -106,24 +106,24 @@ impl Uint { let m1hp = modulus.shr1().wrapping_add(&Uint::ONE); - let modulus_is_odd = modulus.ct_is_odd(); + let modulus_is_odd = modulus.is_odd(); let mut i = 0; while i < bit_size { // A sanity check that `b` stays odd. Only matters if `modulus` was odd to begin with, // otherwise this whole thing produces nonsense anyway. - debug_assert!(modulus_is_odd.not().or(b.ct_is_odd()).is_true_vartime()); + debug_assert!(modulus_is_odd.not().or(b.is_odd()).is_true_vartime()); - let self_odd = a.ct_is_odd(); + let self_odd = a.is_odd(); // Set `self -= b` if `self` is odd. let (new_a, swap) = a.conditional_wrapping_sub(&b, self_odd); // Set `b += self` if `swap` is true. - b = Uint::ct_select(&b, &b.wrapping_add(&new_a), swap); + b = Uint::select(&b, &b.wrapping_add(&new_a), swap); // Negate `self` if `swap` is true. a = new_a.conditional_wrapping_neg(swap); - let (new_u, new_v) = Uint::ct_swap(&u, &v, swap); + let (new_u, new_v) = Uint::swap(&u, &v, swap); let (new_u, cy) = new_u.conditional_wrapping_sub(&new_v, self_odd); let (new_u, cyy) = new_u.conditional_wrapping_add(modulus, cy); debug_assert!(cy.is_true_vartime() == cyy.is_true_vartime()); @@ -143,23 +143,23 @@ impl Uint { debug_assert!(modulus_is_odd .not() - .or(a.ct_is_nonzero().not()) + .or(a.is_nonzero().not()) .is_true_vartime()); - (v, Uint::ct_eq(&b, &Uint::ONE).and(modulus_is_odd)) + (v, Uint::eq(&b, &Uint::ONE).and(modulus_is_odd)) } /// Computes the multiplicative inverse of `self` mod `modulus`, where `modulus` is odd. - /// Returns `(inverse, CtChoice::TRUE)` if an inverse exists, - /// otherwise `(undefined, CtChoice::FALSE)`. - pub const fn inv_odd_mod(&self, modulus: &Self) -> (Self, CtChoice) { + /// Returns `(inverse, ConstChoice::TRUE)` if an inverse exists, + /// otherwise `(undefined, ConstChoice::FALSE)`. + pub const fn inv_odd_mod(&self, modulus: &Self) -> (Self, ConstChoice) { self.inv_odd_mod_bounded(modulus, Uint::::BITS, Uint::::BITS) } /// Computes the multiplicative inverse of `self` mod `modulus`. - /// Returns `(inverse, CtChoice::TRUE)` if an inverse exists, - /// otherwise `(undefined, CtChoice::FALSE)`. - pub const fn inv_mod(&self, modulus: &Self) -> (Self, CtChoice) { + /// Returns `(inverse, ConstChoice::TRUE)` if an inverse exists, + /// otherwise `(undefined, ConstChoice::FALSE)`. + pub const fn inv_mod(&self, modulus: &Self) -> (Self, ConstChoice) { // Decompose `modulus = s * 2^k` where `s` is odd let k = modulus.trailing_zeros(); let (s, _overflow) = modulus.shr(k); @@ -191,7 +191,7 @@ impl Uint { #[cfg(test)] mod tests { - use crate::{CtChoice, U1024, U256, U64}; + use crate::{ConstChoice, U1024, U256, U64}; #[test] fn inv_mod2k() { @@ -201,11 +201,11 @@ mod tests { U256::from_be_hex("3642e6faeaac7c6663b93d3d6a0d489e434ddc0123db5fa627c7f6e22ddacacf"); let (a, is_some) = v.inv_mod2k(256); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); let (a, is_some) = v.inv_mod2k_vartime(256); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); let v = U256::from_be_hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"); @@ -213,11 +213,11 @@ mod tests { U256::from_be_hex("261776f29b6b106c7680cf3ed83054a1af5ae537cb4613dbb4f20099aa774ec1"); let (a, is_some) = v.inv_mod2k(256); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); let (a, is_some) = v.inv_mod2k_vartime(256); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); // Check that even if the number is >= 2^k, the inverse is still correct. @@ -227,25 +227,25 @@ mod tests { U256::from_be_hex("0000000000000000000000000000000000000000034613dbb4f20099aa774ec1"); let (a, is_some) = v.inv_mod2k(90); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); let (a, is_some) = v.inv_mod2k_vartime(90); assert_eq!(e, a); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); // An inverse of an even number does not exist. let (_a, is_some) = U256::from(10u64).inv_mod2k(4); - assert_eq!(is_some, CtChoice::FALSE); + assert_eq!(is_some, ConstChoice::FALSE); let (_a, is_some) = U256::from(10u64).inv_mod2k_vartime(4); - assert_eq!(is_some, CtChoice::FALSE); + assert_eq!(is_some, ConstChoice::FALSE); // A degenerate case. An inverse mod 2^0 == 1 always exists even for even numbers. let (a, is_some) = U256::from(10u64).inv_mod2k_vartime(0); assert_eq!(a, U256::ZERO); - assert_eq!(is_some, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); } #[test] diff --git a/src/uint/mul.rs b/src/uint/mul.rs index 41e9e0eb9..54d78cc58 100644 --- a/src/uint/mul.rs +++ b/src/uint/mul.rs @@ -76,7 +76,7 @@ impl Uint { /// Perform saturating multiplication, returning `MAX` on overflow. pub const fn saturating_mul(&self, rhs: &Uint) -> Self { let (res, overflow) = self.mul_wide(rhs); - Self::ct_select(&res, &Self::MAX, overflow.ct_is_nonzero()) + Self::select(&res, &Self::MAX, overflow.is_nonzero()) } /// Perform wrapping multiplication, discarding overflow. diff --git a/src/uint/neg.rs b/src/uint/neg.rs index 4881a279e..6d3d10716 100644 --- a/src/uint/neg.rs +++ b/src/uint/neg.rs @@ -1,6 +1,6 @@ use core::ops::Neg; -use crate::{CtChoice, Limb, Uint, WideWord, Word, Wrapping}; +use crate::{ConstChoice, Limb, Uint, WideWord, Word, Wrapping}; impl Neg for Wrapping> { type Output = Self; @@ -12,8 +12,8 @@ impl Neg for Wrapping> { impl Uint { /// Negates based on `choice` by wrapping the integer. - pub(crate) const fn conditional_wrapping_neg(&self, choice: CtChoice) -> Uint { - Uint::ct_select(self, &self.wrapping_neg(), choice) + pub(crate) const fn conditional_wrapping_neg(&self, choice: ConstChoice) -> Uint { + Uint::select(self, &self.wrapping_neg(), choice) } /// Perform wrapping negation. diff --git a/src/uint/neg_mod.rs b/src/uint/neg_mod.rs index 28cd24b32..b6ca39273 100644 --- a/src/uint/neg_mod.rs +++ b/src/uint/neg_mod.rs @@ -6,7 +6,7 @@ impl Uint { /// Computes `-a mod p`. /// Assumes `self` is in `[0, p)`. pub const fn neg_mod(&self, p: &Self) -> Self { - let z = self.ct_is_nonzero(); + let z = self.is_nonzero(); let mut ret = p.sbb(self, Limb::ZERO).0; let mut i = 0; while i < LIMBS { diff --git a/src/uint/shl.rs b/src/uint/shl.rs index 2b885d8df..23c74ade8 100644 --- a/src/uint/shl.rs +++ b/src/uint/shl.rs @@ -1,43 +1,43 @@ //! [`Uint`] bitwise left shift operations. -use crate::{CtChoice, Limb, Uint, Word}; +use crate::{ConstChoice, Limb, Uint, Word}; use core::ops::{Shl, ShlAssign}; impl Uint { /// Computes `self << shift`. /// If `shift >= Self::BITS`, returns zero as the first tuple element, - /// and `CtChoice::TRUE` as the second element. - pub const fn shl(&self, shift: u32) -> (Self, CtChoice) { + /// and `ConstChoice::TRUE` as the second element. + pub const fn shl(&self, shift: u32) -> (Self, ConstChoice) { // `floor(log2(BITS - 1))` is the number of bits in the representation of `shift` // (which lies in range `0 <= shift < BITS`). let shift_bits = u32::BITS - (Self::BITS - 1).leading_zeros(); - let overflow = CtChoice::from_u32_lt(shift, Self::BITS).not(); + let overflow = ConstChoice::from_u32_lt(shift, Self::BITS).not(); let shift = shift % Self::BITS; let mut result = *self; let mut i = 0; while i < shift_bits { - let bit = CtChoice::from_u32_lsb((shift >> i) & 1); - result = Uint::ct_select(&result, &result.shl_vartime(1 << i).0, bit); + let bit = ConstChoice::from_u32_lsb((shift >> i) & 1); + result = Uint::select(&result, &result.shl_vartime(1 << i).0, bit); i += 1; } - (Uint::ct_select(&result, &Self::ZERO, overflow), overflow) + (Uint::select(&result, &Self::ZERO, overflow), overflow) } /// Computes `self << shift`. /// If `shift >= Self::BITS`, returns zero as the first tuple element, - /// and `CtChoice::TRUE` as the second element. + /// and `ConstChoice::TRUE` as the second element. /// /// 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 const fn shl_vartime(&self, shift: u32) -> (Self, CtChoice) { + pub const fn shl_vartime(&self, shift: u32) -> (Self, ConstChoice) { let mut limbs = [Limb::ZERO; LIMBS]; if shift >= Self::BITS { - return (Self::ZERO, CtChoice::TRUE); + return (Self::ZERO, ConstChoice::TRUE); } let shift_num = (shift / Limb::BITS) as usize; @@ -50,7 +50,7 @@ impl Uint { } if rem == 0 { - return (Self { limbs }, CtChoice::FALSE); + return (Self { limbs }, ConstChoice::FALSE); } let mut carry = Limb::ZERO; @@ -64,12 +64,12 @@ impl Uint { i += 1; } - (Self { limbs }, CtChoice::FALSE) + (Self { limbs }, ConstChoice::FALSE) } /// Computes a left shift on a wide input as `(lo, hi)`. /// If `shift >= Self::BITS`, returns a tuple of zeros as the first element, - /// and `CtChoice::TRUE` as the second element. + /// and `ConstChoice::TRUE` as the second element. /// /// NOTE: this operation is variable time with respect to `shift` *ONLY*. /// @@ -79,18 +79,18 @@ impl Uint { pub const fn shl_vartime_wide( lower_upper: (Self, Self), shift: u32, - ) -> ((Self, Self), CtChoice) { + ) -> ((Self, Self), ConstChoice) { let (lower, upper) = lower_upper; if shift >= 2 * Self::BITS { - ((Self::ZERO, Self::ZERO), CtChoice::TRUE) + ((Self::ZERO, Self::ZERO), ConstChoice::TRUE) } else if shift >= Self::BITS { let (upper, _) = lower.shl_vartime(shift - Self::BITS); - ((Self::ZERO, upper), CtChoice::FALSE) + ((Self::ZERO, upper), ConstChoice::FALSE) } else { let (new_lower, _) = lower.shl_vartime(shift); let (upper_lo, _) = lower.shr_vartime(Self::BITS - shift); let (upper_hi, _) = upper.shl_vartime(shift); - ((new_lower, upper_lo.bitor(&upper_hi)), CtChoice::FALSE) + ((new_lower, upper_lo.bitor(&upper_hi)), ConstChoice::FALSE) } } @@ -100,7 +100,7 @@ impl Uint { pub(crate) const fn shl_limb(&self, shift: u32) -> (Self, Limb) { let mut limbs = [Limb::ZERO; LIMBS]; - let nz = CtChoice::from_u32_nonzero(shift); + let nz = ConstChoice::from_u32_nonzero(shift); let lshift = shift; let rshift = nz.if_true_u32(Limb::BITS - shift); let carry = nz.if_true_word(self.limbs[LIMBS - 1].0.wrapping_shr(Word::BITS - shift)); @@ -118,10 +118,10 @@ impl Uint { (Uint::::new(limbs), Limb(carry)) } - /// Computes `self << 1` in constant-time, returning [`CtChoice::TRUE`] - /// if the most significant bit was set, and [`CtChoice::FALSE`] otherwise. + /// Computes `self << 1` in constant-time, returning [`ConstChoice::TRUE`] + /// if the most significant bit was set, and [`ConstChoice::FALSE`] otherwise. #[inline(always)] - pub(crate) const fn shl1_with_carry(&self) -> (Self, CtChoice) { + pub(crate) const fn shl1_with_carry(&self) -> (Self, ConstChoice) { let mut ret = Self::ZERO; let mut i = 0; let mut carry = Limb::ZERO; @@ -132,7 +132,7 @@ impl Uint { i += 1; } - (ret, CtChoice::from_word_lsb(carry.0)) + (ret, ConstChoice::from_word_lsb(carry.0)) } /// Computes `self << 1` in constant-time. @@ -171,7 +171,7 @@ impl ShlAssign for Uint { #[cfg(test)] mod tests { - use crate::{CtChoice, Limb, Uint, U128, U256}; + use crate::{ConstChoice, Limb, Uint, U128, U256}; const N: U256 = U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); @@ -222,8 +222,8 @@ mod tests { #[test] fn shl256_const() { - assert_eq!(N.shl(256), (U256::ZERO, CtChoice::TRUE)); - assert_eq!(N.shl_vartime(256), (U256::ZERO, CtChoice::TRUE)); + assert_eq!(N.shl(256), (U256::ZERO, ConstChoice::TRUE)); + assert_eq!(N.shl_vartime(256), (U256::ZERO, ConstChoice::TRUE)); } #[test] @@ -241,11 +241,11 @@ mod tests { fn shl_wide_1_1_128() { assert_eq!( Uint::shl_vartime_wide((U128::ONE, U128::ONE), 128), - ((U128::ZERO, U128::ONE), CtChoice::FALSE) + ((U128::ZERO, U128::ONE), ConstChoice::FALSE) ); assert_eq!( Uint::shl_vartime_wide((U128::ONE, U128::ONE), 128), - ((U128::ZERO, U128::ONE), CtChoice::FALSE) + ((U128::ZERO, U128::ONE), ConstChoice::FALSE) ); } @@ -255,7 +255,7 @@ mod tests { Uint::shl_vartime_wide((U128::MAX, U128::ZERO), 1), ( (U128::MAX.sbb(&U128::ONE, Limb::ZERO).0, U128::ONE), - CtChoice::FALSE + ConstChoice::FALSE ) ); } @@ -264,7 +264,7 @@ mod tests { fn shl_wide_max_max_256() { assert_eq!( Uint::shl_vartime_wide((U128::MAX, U128::MAX), 256), - ((U128::ZERO, U128::ZERO), CtChoice::TRUE) + ((U128::ZERO, U128::ZERO), ConstChoice::TRUE) ); } } diff --git a/src/uint/shr.rs b/src/uint/shr.rs index 5bb8093bc..3b0c83c2c 100644 --- a/src/uint/shr.rs +++ b/src/uint/shr.rs @@ -1,43 +1,43 @@ //! [`Uint`] bitwise right shift operations. -use crate::{CtChoice, Limb, Uint}; +use crate::{ConstChoice, Limb, Uint}; use core::ops::{Shr, ShrAssign}; impl Uint { /// Computes `self >> shift`. /// If `shift >= Self::BITS`, returns zero as the first tuple element, - /// and `CtChoice::TRUE` as the second element. - pub const fn shr(&self, shift: u32) -> (Self, CtChoice) { + /// and `ConstChoice::TRUE` as the second element. + pub const fn shr(&self, shift: u32) -> (Self, ConstChoice) { // `floor(log2(BITS - 1))` is the number of bits in the representation of `shift` // (which lies in range `0 <= shift < BITS`). let shift_bits = u32::BITS - (Self::BITS - 1).leading_zeros(); - let overflow = CtChoice::from_u32_lt(shift, Self::BITS).not(); + let overflow = ConstChoice::from_u32_lt(shift, Self::BITS).not(); let shift = shift % Self::BITS; let mut result = *self; let mut i = 0; while i < shift_bits { - let bit = CtChoice::from_u32_lsb((shift >> i) & 1); - result = Uint::ct_select(&result, &result.shr_vartime(1 << i).0, bit); + let bit = ConstChoice::from_u32_lsb((shift >> i) & 1); + result = Uint::select(&result, &result.shr_vartime(1 << i).0, bit); i += 1; } - (Uint::ct_select(&result, &Self::ZERO, overflow), overflow) + (Uint::select(&result, &Self::ZERO, overflow), overflow) } /// Computes `self >> shift`. /// If `shift >= Self::BITS`, returns zero as the first tuple element, - /// and `CtChoice::TRUE` as the second element. + /// and `ConstChoice::TRUE` as the second element. /// /// 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 const fn shr_vartime(&self, shift: u32) -> (Self, CtChoice) { + pub const fn shr_vartime(&self, shift: u32) -> (Self, ConstChoice) { let mut limbs = [Limb::ZERO; LIMBS]; if shift >= Self::BITS { - return (Self::ZERO, CtChoice::TRUE); + return (Self::ZERO, ConstChoice::TRUE); } let shift_num = (shift / Limb::BITS) as usize; @@ -50,7 +50,7 @@ impl Uint { } if rem == 0 { - return (Self { limbs }, CtChoice::FALSE); + return (Self { limbs }, ConstChoice::FALSE); } let mut carry = Limb::ZERO; @@ -63,12 +63,12 @@ impl Uint { carry = new_carry; } - (Self { limbs }, CtChoice::FALSE) + (Self { limbs }, ConstChoice::FALSE) } /// Computes a right shift on a wide input as `(lo, hi)`. /// If `shift >= Self::BITS`, returns a tuple of zeros as the first element, - /// and `CtChoice::TRUE` as the second element. + /// and `ConstChoice::TRUE` as the second element. /// /// NOTE: this operation is variable time with respect to `shift` *ONLY*. /// @@ -78,25 +78,25 @@ impl Uint { pub const fn shr_vartime_wide( lower_upper: (Self, Self), shift: u32, - ) -> ((Self, Self), CtChoice) { + ) -> ((Self, Self), ConstChoice) { let (lower, upper) = lower_upper; if shift >= 2 * Self::BITS { - ((Self::ZERO, Self::ZERO), CtChoice::TRUE) + ((Self::ZERO, Self::ZERO), ConstChoice::TRUE) } else if shift >= Self::BITS { let (lower, _) = upper.shr_vartime(shift - Self::BITS); - ((lower, Self::ZERO), CtChoice::FALSE) + ((lower, Self::ZERO), ConstChoice::FALSE) } else { let (new_upper, _) = upper.shr_vartime(shift); let (lower_hi, _) = upper.shl_vartime(Self::BITS - shift); let (lower_lo, _) = lower.shr_vartime(shift); - ((lower_lo.bitor(&lower_hi), new_upper), CtChoice::FALSE) + ((lower_lo.bitor(&lower_hi), new_upper), ConstChoice::FALSE) } } - /// Computes `self >> 1` in constant-time, returning [`CtChoice::TRUE`] - /// if the least significant bit was set, and [`CtChoice::FALSE`] otherwise. + /// Computes `self >> 1` in constant-time, returning [`ConstChoice::TRUE`] + /// if the least significant bit was set, and [`ConstChoice::FALSE`] otherwise. #[inline(always)] - pub(crate) const fn shr1_with_carry(&self) -> (Self, CtChoice) { + pub(crate) const fn shr1_with_carry(&self) -> (Self, ConstChoice) { let mut ret = Self::ZERO; let mut i = LIMBS; let mut carry = Limb::ZERO; @@ -107,7 +107,7 @@ impl Uint { carry = new_carry; } - (ret, CtChoice::from_word_lsb(carry.0 >> Limb::HI_BIT)) + (ret, ConstChoice::from_word_lsb(carry.0 >> Limb::HI_BIT)) } /// Computes `self >> 1` in constant-time. @@ -146,7 +146,7 @@ impl ShrAssign for Uint { #[cfg(test)] mod tests { - use crate::{CtChoice, Uint, U128, U256}; + use crate::{ConstChoice, Uint, U128, U256}; const N: U256 = U256::from_be_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); @@ -162,8 +162,8 @@ mod tests { #[test] fn shr256_const() { - assert_eq!(N.shr(256), (U256::ZERO, CtChoice::TRUE)); - assert_eq!(N.shr_vartime(256), (U256::ZERO, CtChoice::TRUE)); + assert_eq!(N.shr(256), (U256::ZERO, ConstChoice::TRUE)); + assert_eq!(N.shr_vartime(256), (U256::ZERO, ConstChoice::TRUE)); } #[test] @@ -176,7 +176,7 @@ mod tests { fn shr_wide_1_1_128() { assert_eq!( Uint::shr_vartime_wide((U128::ONE, U128::ONE), 128), - ((U128::ONE, U128::ZERO), CtChoice::FALSE) + ((U128::ONE, U128::ZERO), ConstChoice::FALSE) ); } @@ -184,7 +184,7 @@ mod tests { fn shr_wide_0_max_1() { assert_eq!( Uint::shr_vartime_wide((U128::ZERO, U128::MAX), 1), - ((U128::ONE << 127, U128::MAX >> 1), CtChoice::FALSE) + ((U128::ONE << 127, U128::MAX >> 1), ConstChoice::FALSE) ); } @@ -192,7 +192,7 @@ mod tests { fn shr_wide_max_max_256() { assert_eq!( Uint::shr_vartime_wide((U128::MAX, U128::MAX), 256), - ((U128::ZERO, U128::ZERO), CtChoice::TRUE) + ((U128::ZERO, U128::ZERO), ConstChoice::TRUE) ); } } diff --git a/src/uint/sqrt.rs b/src/uint/sqrt.rs index b06b2eac6..5dfdb0715 100644 --- a/src/uint/sqrt.rs +++ b/src/uint/sqrt.rs @@ -33,7 +33,7 @@ impl Uint { let (q, _) = self.div_rem(&nz_x); // A protection in case `self == 0`, which will make `x == 0` - let q = Self::ct_select(&Self::ZERO, &q, is_some); + let q = Self::select(&Self::ZERO, &q, is_some); x = x.wrapping_add(&q).shr1(); i += 1; @@ -42,7 +42,7 @@ impl Uint { // At this point `x_prev == x_{n}` and `x == x_{n+1}` // where `n == i - 1 == LOG2_BITS + 1 == floor(log2(BITS)) + 1`. // Thus, according to Hast, `sqrt(self) = min(x_n, x_{n+1})`. - Self::ct_select(&x_prev, &x, Uint::ct_gt(&x_prev, &x)) + Self::select(&x_prev, &x, Uint::gt(&x_prev, &x)) } /// Computes √(`self`) @@ -72,7 +72,7 @@ impl Uint { x = next_x; } - if self.ct_is_nonzero().is_true_vartime() { + if self.is_nonzero().is_true_vartime() { x } else { Self::ZERO diff --git a/src/uint/sub.rs b/src/uint/sub.rs index 000a4f8c1..5048e81a7 100644 --- a/src/uint/sub.rs +++ b/src/uint/sub.rs @@ -1,7 +1,7 @@ //! [`Uint`] addition operations. use super::Uint; -use crate::{Checked, CheckedSub, CtChoice, Limb, Wrapping, Zero}; +use crate::{Checked, CheckedSub, ConstChoice, Limb, Wrapping, Zero}; use core::ops::{Sub, SubAssign}; use subtle::CtOption; @@ -25,7 +25,7 @@ impl Uint { /// Perform saturating subtraction, returning `ZERO` on underflow. pub const fn saturating_sub(&self, rhs: &Self) -> Self { let (res, underflow) = self.sbb(rhs, Limb::ZERO); - Self::ct_select(&res, &Self::ZERO, CtChoice::from_word_mask(underflow.0)) + Self::select(&res, &Self::ZERO, ConstChoice::from_word_mask(underflow.0)) } /// Perform wrapping subtraction, discarding underflow and wrapping around @@ -39,11 +39,11 @@ impl Uint { pub(crate) const fn conditional_wrapping_sub( &self, rhs: &Self, - choice: CtChoice, - ) -> (Self, CtChoice) { - let actual_rhs = Uint::ct_select(&Uint::ZERO, rhs, choice); + choice: ConstChoice, + ) -> (Self, ConstChoice) { + let actual_rhs = Uint::select(&Uint::ZERO, rhs, choice); let (res, borrow) = self.sbb(&actual_rhs, Limb::ZERO); - (res, CtChoice::from_word_mask(borrow.0)) + (res, ConstChoice::from_word_mask(borrow.0)) } } diff --git a/tests/uint_proptests.rs b/tests/uint_proptests.rs index e643f1d10..2430c70a9 100644 --- a/tests/uint_proptests.rs +++ b/tests/uint_proptests.rs @@ -2,7 +2,7 @@ use crypto_bigint::{ modular::{DynResidue, DynResidueParams}, - CtChoice, Encoding, Limb, NonZero, Word, U256, + ConstChoice, Encoding, Limb, NonZero, Word, U256, }; use num_bigint::BigUint; use num_integer::Integer; @@ -69,7 +69,7 @@ proptest! { assert_eq!(expected, actual); if shift >= U256::BITS { assert_eq!(actual, U256::ZERO); - assert_eq!(overflow, CtChoice::TRUE); + assert_eq!(overflow, ConstChoice::TRUE); } } @@ -86,7 +86,7 @@ proptest! { assert_eq!(expected, actual); if shift >= U256::BITS { assert_eq!(actual, U256::ZERO); - assert_eq!(overflow, CtChoice::TRUE); + assert_eq!(overflow, ConstChoice::TRUE); } } @@ -103,7 +103,7 @@ proptest! { assert_eq!(expected, actual); if shift >= U256::BITS { assert_eq!(actual, U256::ZERO); - assert_eq!(overflow, CtChoice::TRUE); + assert_eq!(overflow, ConstChoice::TRUE); } } @@ -120,7 +120,7 @@ proptest! { assert_eq!(expected, actual); if shift >= U256::BITS { assert_eq!(actual, U256::ZERO); - assert_eq!(overflow, CtChoice::TRUE); + assert_eq!(overflow, ConstChoice::TRUE); } } @@ -281,8 +281,8 @@ proptest! { let (actual, is_some) = a.inv_mod2k(k); let (actual_vartime, is_some_vartime) = a.inv_mod2k_vartime(k); assert_eq!(actual, actual_vartime); - assert_eq!(is_some, CtChoice::TRUE); - assert_eq!(is_some_vartime, CtChoice::TRUE); + assert_eq!(is_some, ConstChoice::TRUE); + assert_eq!(is_some_vartime, ConstChoice::TRUE); if k == 0 { assert_eq!(actual, U256::ZERO); @@ -299,7 +299,7 @@ proptest! { let a_bi = to_biguint(&a); let b_bi = to_biguint(&b); - let expected_is_some = if a_bi.gcd(&b_bi) == BigUint::one() { CtChoice::TRUE } else { CtChoice::FALSE }; + let expected_is_some = if a_bi.gcd(&b_bi) == BigUint::one() { ConstChoice::TRUE } else { ConstChoice::FALSE }; let (actual, actual_is_some) = a.inv_mod(&b); assert_eq!(bool::from(expected_is_some), bool::from(actual_is_some));