diff options
Diffstat (limited to 'vendor/crypto-bigint/src/uint.rs')
-rw-r--r-- | vendor/crypto-bigint/src/uint.rs | 172 |
1 files changed, 97 insertions, 75 deletions
diff --git a/vendor/crypto-bigint/src/uint.rs b/vendor/crypto-bigint/src/uint.rs index 5aac67c5a..4dd22fa61 100644 --- a/vendor/crypto-bigint/src/uint.rs +++ b/vendor/crypto-bigint/src/uint.rs @@ -20,11 +20,13 @@ mod bit_xor; mod bits; mod cmp; mod div; +pub(crate) mod div_limb; mod encoding; mod from; mod inv_mod; mod mul; mod mul_mod; +mod neg; mod neg_mod; mod resize; mod shl; @@ -33,14 +35,17 @@ mod sqrt; mod sub; mod sub_mod; +/// Implements modular arithmetic for constant moduli. +pub mod modular; + #[cfg(feature = "generic-array")] mod array; #[cfg(feature = "rand_core")] mod rand; -use crate::{Concat, Encoding, Integer, Limb, Split, Word, Zero}; -use core::{fmt, mem}; +use crate::{Bounded, Concat, Encoding, Integer, Limb, Split, Word, Zero}; +use core::fmt; use subtle::{Choice, ConditionallySelectable}; #[cfg(feature = "serde")] @@ -56,43 +61,49 @@ use zeroize::DefaultIsZeroes; /// # Encoding support /// This type supports many different types of encodings, either via the /// [`Encoding`][`crate::Encoding`] trait or various `const fn` decoding and -/// encoding functions that can be used with [`UInt`] constants. +/// encoding functions that can be used with [`Uint`] constants. /// /// Optional crate features for encoding (off-by-default): /// - `generic-array`: enables [`ArrayEncoding`][`crate::ArrayEncoding`] trait which can be used to -/// [`UInt`] as `GenericArray<u8, N>` and a [`ArrayDecoding`][`crate::ArrayDecoding`] trait which -/// can be used to `GenericArray<u8, N>` as [`UInt`]. +/// [`Uint`] as `GenericArray<u8, N>` and a [`ArrayDecoding`][`crate::ArrayDecoding`] trait which +/// can be used to `GenericArray<u8, N>` as [`Uint`]. /// - `rlp`: support for [Recursive Length Prefix (RLP)][RLP] encoding. /// /// [RLP]: https://eth.wiki/fundamentals/rlp // TODO(tarcieri): make generic around a specified number of bits. -#[derive(Copy, Clone, Debug, Hash)] -pub struct UInt<const LIMBS: usize> { +#[derive(Copy, Clone, Hash)] +pub struct Uint<const LIMBS: usize> { /// Inner limb array. Stored from least significant to most significant. limbs: [Limb; LIMBS], } -impl<const LIMBS: usize> UInt<LIMBS> { +impl<const LIMBS: usize> Uint<LIMBS> { /// The value `0`. pub const ZERO: Self = Self::from_u8(0); /// The value `1`. pub const ONE: Self = Self::from_u8(1); - /// The number of limbs used on this platform. - pub const LIMBS: usize = LIMBS; - - /// Maximum value this [`UInt`] can express. + /// Maximum value this [`Uint`] can express. pub const MAX: Self = Self { limbs: [Limb::MAX; LIMBS], }; - /// Const-friendly [`UInt`] constructor. + /// Total size of the represented integer in bits. + pub const BITS: usize = LIMBS * Limb::BITS; + + /// Total size of the represented integer in bytes. + pub const BYTES: usize = LIMBS * Limb::BYTES; + + /// The number of limbs used on this platform. + pub const LIMBS: usize = LIMBS; + + /// Const-friendly [`Uint`] constructor. pub const fn new(limbs: [Limb; LIMBS]) -> Self { Self { limbs } } - /// Create a [`UInt`] from an array of [`Word`]s (i.e. word-sized unsigned + /// Create a [`Uint`] from an array of [`Word`]s (i.e. word-sized unsigned /// integers). #[inline] pub const fn from_words(arr: [Word; LIMBS]) -> Self { @@ -108,7 +119,7 @@ impl<const LIMBS: usize> UInt<LIMBS> { } /// Create an array of [`Word`]s (i.e. word-sized unsigned integers) from - /// a [`UInt`]. + /// a [`Uint`]. #[inline] pub const fn to_words(self) -> [Word; LIMBS] { let mut arr = [0; LIMBS]; @@ -125,10 +136,9 @@ impl<const LIMBS: usize> UInt<LIMBS> { /// Borrow the inner limbs as an array of [`Word`]s. pub const fn as_words(&self) -> &[Word; LIMBS] { // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word` - #[allow(unsafe_code)] + #[allow(trivial_casts, unsafe_code)] unsafe { - // TODO(tarcieri): use &*((&self.limbs as *const _) as *const [Word; LIMBS]) - mem::transmute(&self.limbs) + &*((&self.limbs as *const _) as *const [Word; LIMBS]) } } @@ -141,70 +151,47 @@ impl<const LIMBS: usize> UInt<LIMBS> { } } - /// Deprecated: borrow the inner limbs as an array of [`Word`]s. - #[deprecated(since = "0.4.8", note = "please use `as_words` instead")] - pub const fn as_uint_array(&self) -> &[Word; LIMBS] { - self.as_words() - } - - /// Deprecated: create a [`UInt`] from an array of [`Word`]s. - #[deprecated(since = "0.4.8", note = "please use `from_words` instead")] - pub const fn from_uint_array(words: [Word; LIMBS]) -> Self { - Self::from_words(words) - } - - /// Deprecated: create an array of [`Word`]s from a [`UInt`]. - #[deprecated(since = "0.4.8", note = "please use `to_words` instead")] - pub const fn to_uint_array(self) -> [Word; LIMBS] { - self.to_words() - } - - /// Borrow the limbs of this [`UInt`]. - // TODO(tarcieri): rename to `as_limbs` for consistency with `as_words` - pub const fn limbs(&self) -> &[Limb; LIMBS] { + /// Borrow the limbs of this [`Uint`]. + pub const fn as_limbs(&self) -> &[Limb; LIMBS] { &self.limbs } - /// Borrow the limbs of this [`UInt`] mutably. - // TODO(tarcieri): rename to `as_limbs_mut` for consistency with `as_words_mut` - pub fn limbs_mut(&mut self) -> &mut [Limb; LIMBS] { + /// Borrow the limbs of this [`Uint`] mutably. + pub fn as_limbs_mut(&mut self) -> &mut [Limb; LIMBS] { &mut self.limbs } - /// Convert this [`UInt`] into its inner limbs. - // TODO(tarcieri): rename to `to_limbs` for consistency with `to_words` - pub const fn into_limbs(self) -> [Limb; LIMBS] { + /// Convert this [`Uint`] into its inner limbs. + pub const fn to_limbs(self) -> [Limb; LIMBS] { self.limbs } } -impl<const LIMBS: usize> AsRef<[Word; LIMBS]> for UInt<LIMBS> { +impl<const LIMBS: usize> AsRef<[Word; LIMBS]> for Uint<LIMBS> { fn as_ref(&self) -> &[Word; LIMBS] { self.as_words() } } -impl<const LIMBS: usize> AsMut<[Word; LIMBS]> for UInt<LIMBS> { +impl<const LIMBS: usize> AsMut<[Word; LIMBS]> for Uint<LIMBS> { fn as_mut(&mut self) -> &mut [Word; LIMBS] { self.as_words_mut() } } -// TODO(tarcieri): eventually phase this out in favor of `limbs()`? -impl<const LIMBS: usize> AsRef<[Limb]> for UInt<LIMBS> { +impl<const LIMBS: usize> AsRef<[Limb]> for Uint<LIMBS> { fn as_ref(&self) -> &[Limb] { - self.limbs() + self.as_limbs() } } -// TODO(tarcieri): eventually phase this out in favor of `limbs_mut()`? -impl<const LIMBS: usize> AsMut<[Limb]> for UInt<LIMBS> { +impl<const LIMBS: usize> AsMut<[Limb]> for Uint<LIMBS> { fn as_mut(&mut self) -> &mut [Limb] { - self.limbs_mut() + self.as_limbs_mut() } } -impl<const LIMBS: usize> ConditionallySelectable for UInt<LIMBS> { +impl<const LIMBS: usize> ConditionallySelectable for Uint<LIMBS> { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { let mut limbs = [Limb::ZERO; LIMBS]; @@ -216,15 +203,18 @@ impl<const LIMBS: usize> ConditionallySelectable for UInt<LIMBS> { } } -impl<const LIMBS: usize> Default for UInt<LIMBS> { +impl<const LIMBS: usize> Default for Uint<LIMBS> { fn default() -> Self { Self::ZERO } } -impl<const LIMBS: usize> Integer for UInt<LIMBS> { +impl<const LIMBS: usize> Integer for Uint<LIMBS> { const ONE: Self = Self::ONE; const MAX: Self = Self::MAX; + const BITS: usize = Self::BITS; + const BYTES: usize = Self::BYTES; + const LIMBS: usize = Self::LIMBS; fn is_odd(&self) -> Choice { self.limbs @@ -234,17 +224,28 @@ impl<const LIMBS: usize> Integer for UInt<LIMBS> { } } -impl<const LIMBS: usize> Zero for UInt<LIMBS> { +impl<const LIMBS: usize> Zero for Uint<LIMBS> { const ZERO: Self = Self::ZERO; } -impl<const LIMBS: usize> fmt::Display for UInt<LIMBS> { +impl<const LIMBS: usize> Bounded for Uint<LIMBS> { + const BITS: usize = Self::BITS; + const BYTES: usize = Self::BYTES; +} + +impl<const LIMBS: usize> fmt::Debug for Uint<LIMBS> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Uint(0x{self:X})") + } +} + +impl<const LIMBS: usize> fmt::Display for Uint<LIMBS> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::UpperHex::fmt(self, f) } } -impl<const LIMBS: usize> fmt::LowerHex for UInt<LIMBS> { +impl<const LIMBS: usize> fmt::LowerHex for Uint<LIMBS> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for limb in self.limbs.iter().rev() { fmt::LowerHex::fmt(limb, f)?; @@ -253,7 +254,7 @@ impl<const LIMBS: usize> fmt::LowerHex for UInt<LIMBS> { } } -impl<const LIMBS: usize> fmt::UpperHex for UInt<LIMBS> { +impl<const LIMBS: usize> fmt::UpperHex for Uint<LIMBS> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for limb in self.limbs.iter().rev() { fmt::UpperHex::fmt(limb, f)?; @@ -263,10 +264,9 @@ impl<const LIMBS: usize> fmt::UpperHex for UInt<LIMBS> { } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de, const LIMBS: usize> Deserialize<'de> for UInt<LIMBS> +impl<'de, const LIMBS: usize> Deserialize<'de> for Uint<LIMBS> where - UInt<LIMBS>: Encoding, + Uint<LIMBS>: Encoding, { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where @@ -280,10 +280,9 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] -impl<'de, const LIMBS: usize> Serialize for UInt<LIMBS> +impl<const LIMBS: usize> Serialize for Uint<LIMBS> where - UInt<LIMBS>: Encoding, + Uint<LIMBS>: Encoding, { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where @@ -294,8 +293,7 @@ where } #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -impl<const LIMBS: usize> DefaultIsZeroes for UInt<LIMBS> {} +impl<const LIMBS: usize> DefaultIsZeroes for Uint<LIMBS> {} // TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits. macro_rules! impl_uint_aliases { @@ -303,11 +301,9 @@ macro_rules! impl_uint_aliases { $( #[doc = $doc] #[doc="unsigned big integer."] - pub type $name = UInt<{nlimbs!($bits)}>; + pub type $name = Uint<{nlimbs!($bits)}>; impl Encoding for $name { - const BIT_SIZE: usize = $bits; - const BYTE_SIZE: usize = $bits / 8; type Repr = [u8; $bits / 8]; @@ -345,13 +341,16 @@ impl_uint_aliases! { (U128, 128, "128-bit"), (U192, 192, "192-bit"), (U256, 256, "256-bit"), + (U320, 320, "320-bit"), (U384, 384, "384-bit"), (U448, 448, "448-bit"), (U512, 512, "512-bit"), (U576, 576, "576-bit"), + (U640, 640, "640-bit"), (U768, 768, "768-bit"), (U896, 896, "896-bit"), (U1024, 1024, "1024-bit"), + (U1280, 1280, "1280-bit"), (U1536, 1536, "1536-bit"), (U1792, 1792, "1792-bit"), (U2048, 2048, "2048-bit"), @@ -362,15 +361,23 @@ impl_uint_aliases! { (U8192, 8192, "8192-bit") } +#[cfg(target_pointer_width = "32")] +impl_uint_aliases! { + (U224, 224, "224-bit"), // For NIST P-224 + (U544, 544, "544-bit") // For NIST P-521 +} + // TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits. impl_concat! { (U64, 64), (U128, 128), (U192, 192), (U256, 256), + (U320, 320), (U384, 384), (U448, 448), (U512, 512), + (U640, 640), (U768, 768), (U896, 896), (U1024, 1024), @@ -384,14 +391,14 @@ impl_concat! { // TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits. impl_split! { (U128, 128), - (U192, 192), (U256, 256), (U384, 384), - (U448, 448), (U512, 512), + (U640, 640), (U768, 768), (U896, 896), (U1024, 1024), + (U1280, 1280), (U1536, 1536), (U1792, 1792), (U2048, 2048), @@ -407,11 +414,26 @@ mod tests { use crate::{Encoding, U128}; use subtle::ConditionallySelectable; + #[cfg(feature = "alloc")] + use alloc::format; + #[cfg(feature = "serde")] use crate::U64; + #[cfg(feature = "alloc")] #[test] + fn debug() { + let hex = "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD"; + let n = U128::from_be_hex(hex); + + assert_eq!( + format!("{:?}", n), + "Uint(0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD)" + ); + } + #[cfg(feature = "alloc")] + #[test] fn display() { let hex = "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD"; let n = U128::from_be_hex(hex); @@ -460,8 +482,8 @@ mod tests { assert_eq!(b, select_1); } - #[test] #[cfg(feature = "serde")] + #[test] fn serde() { const TEST: U64 = U64::from_u64(0x0011223344556677); @@ -471,8 +493,8 @@ mod tests { assert_eq!(TEST, deserialized); } - #[test] #[cfg(feature = "serde")] + #[test] fn serde_owned() { const TEST: U64 = U64::from_u64(0x0011223344556677); |