diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/crypto-bigint/src/uint/cmp.rs | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/crypto-bigint/src/uint/cmp.rs')
-rw-r--r-- | vendor/crypto-bigint/src/uint/cmp.rs | 95 |
1 files changed, 85 insertions, 10 deletions
diff --git a/vendor/crypto-bigint/src/uint/cmp.rs b/vendor/crypto-bigint/src/uint/cmp.rs index 8815369e3..b513242e4 100644 --- a/vendor/crypto-bigint/src/uint/cmp.rs +++ b/vendor/crypto-bigint/src/uint/cmp.rs @@ -72,12 +72,52 @@ impl<const LIMBS: usize> Uint<LIMBS> { CtChoice::from_mask(borrow.0) } - /// Returns the truthy value if `self <= rhs` and the falsy value otherwise. + /// Returns the truthy value if `self >= rhs` and the falsy value otherwise. #[inline] pub(crate) const fn ct_gt(lhs: &Self, rhs: &Self) -> CtChoice { let (_res, borrow) = rhs.sbb(lhs, Limb::ZERO); CtChoice::from_mask(borrow.0) } + + /// Returns the ordering between `self` and `rhs` as an i8. + /// Values correspond to the Ordering enum: + /// -1 is Less + /// 0 is Equal + /// 1 is Greater + #[inline] + pub(crate) const fn ct_cmp(lhs: &Self, rhs: &Self) -> i8 { + let mut i = 0; + let mut borrow = Limb::ZERO; + let mut diff = Limb::ZERO; + + while i < LIMBS { + let (w, b) = rhs.limbs[i].sbb(lhs.limbs[i], borrow); + diff = diff.bitor(w); + borrow = b; + i += 1; + } + let sgn = ((borrow.0 & 2) as i8) - 1; + (diff.ct_is_nonzero().to_u8() as i8) * sgn + } + + /// Returns the Ordering between `self` and `rhs` in variable time. + pub const fn cmp_vartime(&self, rhs: &Self) -> Ordering { + let mut i = LIMBS - 1; + loop { + let (val, borrow) = self.limbs[i].sbb(rhs.limbs[i], Limb::ZERO); + if val.0 != 0 { + return if borrow.0 != 0 { + Ordering::Less + } else { + Ordering::Greater + }; + } + if i == 0 { + return Ordering::Equal; + } + i -= 1; + } + } } impl<const LIMBS: usize> ConstantTimeEq for Uint<LIMBS> { @@ -105,15 +145,11 @@ impl<const LIMBS: usize> Eq for Uint<LIMBS> {} impl<const LIMBS: usize> Ord for Uint<LIMBS> { fn cmp(&self, other: &Self) -> Ordering { - let is_lt = self.ct_lt(other); - let is_eq = self.ct_eq(other); - - if is_lt.into() { - Ordering::Less - } else if is_eq.into() { - Ordering::Equal - } else { - Ordering::Greater + let c = Self::ct_cmp(self, other); + match c { + -1 => Ordering::Less, + 0 => Ordering::Equal, + _ => Ordering::Greater, } } } @@ -133,6 +169,7 @@ impl<const LIMBS: usize> PartialEq for Uint<LIMBS> { #[cfg(test)] mod tests { use crate::{Integer, Zero, U128}; + use core::cmp::Ordering; use subtle::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess}; #[test] @@ -197,4 +234,42 @@ mod tests { assert!(!bool::from(c.ct_lt(&a))); assert!(!bool::from(c.ct_lt(&b))); } + + #[test] + fn cmp() { + let a = U128::ZERO; + let b = U128::ONE; + let c = U128::MAX; + + assert_eq!(a.cmp(&b), Ordering::Less); + assert_eq!(a.cmp(&c), Ordering::Less); + assert_eq!(b.cmp(&c), Ordering::Less); + + assert_eq!(a.cmp(&a), Ordering::Equal); + assert_eq!(b.cmp(&b), Ordering::Equal); + assert_eq!(c.cmp(&c), Ordering::Equal); + + assert_eq!(b.cmp(&a), Ordering::Greater); + assert_eq!(c.cmp(&a), Ordering::Greater); + assert_eq!(c.cmp(&b), Ordering::Greater); + } + + #[test] + fn cmp_vartime() { + let a = U128::ZERO; + let b = U128::ONE; + let c = U128::MAX; + + assert_eq!(a.cmp_vartime(&b), Ordering::Less); + assert_eq!(a.cmp_vartime(&c), Ordering::Less); + assert_eq!(b.cmp_vartime(&c), Ordering::Less); + + assert_eq!(a.cmp_vartime(&a), Ordering::Equal); + assert_eq!(b.cmp_vartime(&b), Ordering::Equal); + assert_eq!(c.cmp_vartime(&c), Ordering::Equal); + + assert_eq!(b.cmp_vartime(&a), Ordering::Greater); + assert_eq!(c.cmp_vartime(&a), Ordering::Greater); + assert_eq!(c.cmp_vartime(&b), Ordering::Greater); + } } |