summaryrefslogtreecommitdiffstats
path: root/vendor/crypto-bigint/src/limb.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/crypto-bigint/src/limb.rs')
-rw-r--r--vendor/crypto-bigint/src/limb.rs176
1 files changed, 176 insertions, 0 deletions
diff --git a/vendor/crypto-bigint/src/limb.rs b/vendor/crypto-bigint/src/limb.rs
new file mode 100644
index 0000000..a5ca957
--- /dev/null
+++ b/vendor/crypto-bigint/src/limb.rs
@@ -0,0 +1,176 @@
+//! Big integers are represented as an array of smaller CPU word-size integers
+//! called "limbs".
+
+mod add;
+mod bit_and;
+mod bit_not;
+mod bit_or;
+mod bit_xor;
+mod bits;
+mod cmp;
+mod encoding;
+mod from;
+mod mul;
+mod neg;
+mod shl;
+mod shr;
+mod sub;
+
+#[cfg(feature = "rand_core")]
+mod rand;
+
+use crate::{Bounded, Zero};
+use core::fmt;
+use subtle::{Choice, ConditionallySelectable};
+
+#[cfg(feature = "serde")]
+use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
+compile_error!("this crate builds on 32-bit and 64-bit platforms only");
+
+//
+// 32-bit definitions
+//
+
+/// Inner integer type that the [`Limb`] newtype wraps.
+#[cfg(target_pointer_width = "32")]
+pub type Word = u32;
+
+/// Unsigned wide integer type: double the width of [`Word`].
+#[cfg(target_pointer_width = "32")]
+pub type WideWord = u64;
+
+//
+// 64-bit definitions
+//
+
+/// Unsigned integer type that the [`Limb`] newtype wraps.
+#[cfg(target_pointer_width = "64")]
+pub type Word = u64;
+
+/// Wide integer type: double the width of [`Word`].
+#[cfg(target_pointer_width = "64")]
+pub type WideWord = u128;
+
+/// Highest bit in a [`Limb`].
+pub(crate) const HI_BIT: usize = Limb::BITS - 1;
+
+/// Big integers are represented as an array of smaller CPU word-size integers
+/// called "limbs".
+// Our PartialEq impl only differs from the default one by being constant-time, so this is safe
+#[allow(clippy::derived_hash_with_manual_eq)]
+#[derive(Copy, Clone, Default, Hash)]
+#[repr(transparent)]
+pub struct Limb(pub Word);
+
+impl Limb {
+ /// The value `0`.
+ pub const ZERO: Self = Limb(0);
+
+ /// The value `1`.
+ pub const ONE: Self = Limb(1);
+
+ /// Maximum value this [`Limb`] can express.
+ pub const MAX: Self = Limb(Word::MAX);
+
+ // 32-bit
+
+ /// Size of the inner integer in bits.
+ #[cfg(target_pointer_width = "32")]
+ pub const BITS: usize = 32;
+ /// Size of the inner integer in bytes.
+ #[cfg(target_pointer_width = "32")]
+ pub const BYTES: usize = 4;
+
+ // 64-bit
+
+ /// Size of the inner integer in bits.
+ #[cfg(target_pointer_width = "64")]
+ pub const BITS: usize = 64;
+ /// Size of the inner integer in bytes.
+ #[cfg(target_pointer_width = "64")]
+ pub const BYTES: usize = 8;
+}
+
+impl Bounded for Limb {
+ const BITS: usize = Self::BITS;
+ const BYTES: usize = Self::BYTES;
+}
+
+impl ConditionallySelectable for Limb {
+ #[inline]
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ Self(Word::conditional_select(&a.0, &b.0, choice))
+ }
+}
+
+impl Zero for Limb {
+ const ZERO: Self = Self::ZERO;
+}
+
+impl fmt::Debug for Limb {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Limb(0x{self:X})")
+ }
+}
+
+impl fmt::Display for Limb {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::UpperHex::fmt(self, f)
+ }
+}
+
+impl fmt::LowerHex for Limb {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:0width$x}", &self.0, width = Self::BYTES * 2)
+ }
+}
+
+impl fmt::UpperHex for Limb {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:0width$X}", &self.0, width = Self::BYTES * 2)
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de> Deserialize<'de> for Limb {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Self(Word::deserialize(deserializer)?))
+ }
+}
+
+#[cfg(feature = "serde")]
+impl Serialize for Limb {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+#[cfg(feature = "zeroize")]
+impl zeroize::DefaultIsZeroes for Limb {}
+
+#[cfg(test)]
+mod tests {
+ #[cfg(feature = "alloc")]
+ use {super::Limb, alloc::format};
+
+ #[cfg(feature = "alloc")]
+ #[test]
+ fn debug() {
+ #[cfg(target_pointer_width = "32")]
+ assert_eq!(format!("{:?}", Limb(42)), "Limb(0x0000002A)");
+
+ #[cfg(target_pointer_width = "64")]
+ assert_eq!(format!("{:?}", Limb(42)), "Limb(0x000000000000002A)");
+ }
+}