summaryrefslogtreecommitdiffstats
path: root/vendor/crypto-bigint/src/boxed/uint
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/crypto-bigint/src/boxed/uint')
-rw-r--r--vendor/crypto-bigint/src/boxed/uint/add.rs62
-rw-r--r--vendor/crypto-bigint/src/boxed/uint/cmp.rs47
2 files changed, 109 insertions, 0 deletions
diff --git a/vendor/crypto-bigint/src/boxed/uint/add.rs b/vendor/crypto-bigint/src/boxed/uint/add.rs
new file mode 100644
index 000000000..b6cedc78f
--- /dev/null
+++ b/vendor/crypto-bigint/src/boxed/uint/add.rs
@@ -0,0 +1,62 @@
+//! [`BoxedUint`] addition operations.
+
+use crate::{BoxedUint, CheckedAdd, Limb, Zero};
+use subtle::CtOption;
+
+impl BoxedUint {
+ /// Computes `a + b + carry`, returning the result along with the new carry.
+ #[inline(always)]
+ pub fn adc(&self, rhs: &Self, carry: Limb) -> (Self, Limb) {
+ Self::chain(self, rhs, carry, |a, b, c| a.adc(b, c))
+ }
+
+ /// Perform wrapping addition, discarding overflow.
+ pub fn wrapping_add(&self, rhs: &Self) -> Self {
+ self.adc(rhs, Limb::ZERO).0
+ }
+}
+
+impl CheckedAdd<&BoxedUint> for BoxedUint {
+ type Output = Self;
+
+ fn checked_add(&self, rhs: &Self) -> CtOption<Self> {
+ let (result, carry) = self.adc(rhs, Limb::ZERO);
+ CtOption::new(result, carry.is_zero())
+ }
+}
+
+#[cfg(test)]
+#[allow(clippy::unwrap_used)]
+mod tests {
+ use super::{BoxedUint, CheckedAdd, Limb};
+
+ #[test]
+ fn adc_no_carry() {
+ let (res, carry) = BoxedUint::zero().adc(&BoxedUint::one(), Limb::ZERO);
+ assert_eq!(res, BoxedUint::one());
+ assert_eq!(carry, Limb::ZERO);
+ }
+
+ #[test]
+ fn adc_with_carry() {
+ let (res, carry) = BoxedUint::max(Limb::BITS)
+ .unwrap()
+ .adc(&BoxedUint::one(), Limb::ZERO);
+ assert_eq!(res, BoxedUint::zero());
+ assert_eq!(carry, Limb::ONE);
+ }
+
+ #[test]
+ fn checked_add_ok() {
+ let result = BoxedUint::zero().checked_add(&BoxedUint::one());
+ assert_eq!(result.unwrap(), BoxedUint::one());
+ }
+
+ #[test]
+ fn checked_add_overflow() {
+ let result = BoxedUint::max(Limb::BITS)
+ .unwrap()
+ .checked_add(&BoxedUint::one());
+ assert!(!bool::from(result.is_some()));
+ }
+}
diff --git a/vendor/crypto-bigint/src/boxed/uint/cmp.rs b/vendor/crypto-bigint/src/boxed/uint/cmp.rs
new file mode 100644
index 000000000..d850fc7d4
--- /dev/null
+++ b/vendor/crypto-bigint/src/boxed/uint/cmp.rs
@@ -0,0 +1,47 @@
+//! [`BoxedUint`] comparisons.
+//!
+//! By default these are all constant-time and use the `subtle` crate.
+
+use super::BoxedUint;
+use crate::Limb;
+use subtle::{Choice, ConstantTimeEq};
+
+impl ConstantTimeEq for BoxedUint {
+ #[inline]
+ fn ct_eq(&self, other: &Self) -> Choice {
+ let (shorter, longer) = Self::sort_by_precision(self, other);
+ let mut ret = Choice::from(1u8);
+
+ for i in 0..longer.limbs.len() {
+ let a = shorter.limbs.get(i).unwrap_or(&Limb::ZERO);
+ let b = longer.limbs.get(i).unwrap_or(&Limb::ZERO);
+ ret &= a.ct_eq(b);
+ }
+
+ ret
+ }
+}
+
+impl Eq for BoxedUint {}
+impl PartialEq for BoxedUint {
+ fn eq(&self, other: &Self) -> bool {
+ self.ct_eq(other).into()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::BoxedUint;
+ use subtle::ConstantTimeEq;
+
+ #[test]
+ fn ct_eq() {
+ let a = BoxedUint::zero();
+ let b = BoxedUint::one();
+
+ assert!(bool::from(a.ct_eq(&a)));
+ assert!(!bool::from(a.ct_eq(&b)));
+ assert!(!bool::from(b.ct_eq(&a)));
+ assert!(bool::from(b.ct_eq(&b)));
+ }
+}