summaryrefslogtreecommitdiffstats
path: root/vendor/crypto-bigint/src/uint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/crypto-bigint/src/uint.rs')
-rw-r--r--vendor/crypto-bigint/src/uint.rs172
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);