Skip to main content

crypto_bigint/
traits.rs

1//! Traits provided by this crate
2
3pub use core::ops::{
4    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
5    Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
6};
7pub use ctutils::{CtAssign, CtEq, CtGt, CtLt, CtNeg, CtSelect};
8pub use num_traits::{
9    ConstOne, ConstZero, WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr,
10    WrappingSub,
11};
12
13use crate::{
14    Choice, CtOption, Limb, NonZero, Odd, Reciprocal, UintRef,
15    modular::{MontyParams, Retrieve},
16    primitives::u32_bits,
17};
18use core::fmt::{self, Debug};
19
20#[cfg(feature = "rand_core")]
21use rand_core::{Rng, TryRng};
22
23/// Integers whose representation takes a bounded amount of space.
24pub trait Bounded {
25    /// Size of this integer in bits.
26    const BITS: u32;
27
28    /// Size of this integer in bytes.
29    const BYTES: usize;
30}
31
32/// Integer trait: represents common functionality of integer types provided by this crate.
33pub trait Integer:
34    'static
35    + sealed::Sealed
36    + Add<Output = Self>
37    + for<'a> Add<&'a Self, Output = Self>
38    + AddAssign<Self>
39    + for<'a> AddAssign<&'a Self>
40    + AsRef<[Limb]>
41    + AsMut<[Limb]>
42    + BitAnd<Output = Self>
43    + for<'a> BitAnd<&'a Self, Output = Self>
44    + BitAndAssign
45    + for<'a> BitAndAssign<&'a Self>
46    + BitOr<Output = Self>
47    + for<'a> BitOr<&'a Self, Output = Self>
48    + BitOrAssign
49    + for<'a> BitOrAssign<&'a Self>
50    + BitXor<Output = Self>
51    + for<'a> BitXor<&'a Self, Output = Self>
52    + BitXorAssign
53    + for<'a> BitXorAssign<&'a Self>
54    + CheckedAdd
55    + CheckedSub
56    + CheckedMul
57    + CheckedDiv
58    + CheckedSquareRoot<Output = Self>
59    + Clone
60    + CtAssign
61    + CtEq
62    + CtGt
63    + CtLt
64    + CtSelect
65    + Debug
66    + Default
67    + DivAssign<NonZero<Self>>
68    + for<'a> DivAssign<&'a NonZero<Self>>
69    + Eq
70    + fmt::LowerHex
71    + fmt::UpperHex
72    + fmt::Binary
73    + Mul<Output = Self>
74    + for<'a> Mul<&'a Self, Output = Self>
75    + MulAssign<Self>
76    + for<'a> MulAssign<&'a Self>
77    + Not<Output = Self>
78    + One
79    + Ord
80    + Rem<NonZero<Self>, Output = Self>
81    + for<'a> Rem<&'a NonZero<Self>, Output = Self>
82    + RemAssign<NonZero<Self>>
83    + for<'a> RemAssign<&'a NonZero<Self>>
84    + Send
85    + Sized
86    + Shl<u32, Output = Self>
87    + ShlAssign<u32>
88    + ShlVartime
89    + Shr<u32, Output = Self>
90    + ShrAssign<u32>
91    + ShrVartime
92    + Sub<Output = Self>
93    + for<'a> Sub<&'a Self, Output = Self>
94    + SubAssign<Self>
95    + for<'a> SubAssign<&'a Self>
96    + Sync
97    + WrappingAdd
98    + WrappingSub
99    + WrappingMul
100    + WrappingNeg
101    + WrappingShl
102    + WrappingShr
103    + Zero
104{
105    /// Borrow the raw limbs used to represent this integer.
106    #[must_use]
107    fn as_limbs(&self) -> &[Limb];
108
109    /// Mutably borrow the raw limbs used to represent this integer.
110    #[must_use]
111    fn as_mut_limbs(&mut self) -> &mut [Limb];
112
113    /// Number of limbs in this integer.
114    #[must_use]
115    fn nlimbs(&self) -> usize;
116
117    /// Is this integer value an odd number?
118    ///
119    /// # Returns
120    ///
121    /// If odd, returns `Choice::FALSE`. Otherwise, returns `Choice::TRUE`.
122    #[must_use]
123    fn is_odd(&self) -> Choice {
124        self.as_ref()
125            .first()
126            .copied()
127            .map_or(Choice::FALSE, Limb::is_odd)
128    }
129
130    /// Is this integer value an even number?
131    ///
132    /// # Returns
133    ///
134    /// If even, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
135    #[must_use]
136    fn is_even(&self) -> Choice {
137        !self.is_odd()
138    }
139}
140
141/// Signed [`Integer`]s.
142pub trait Signed:
143    Div<NonZero<Self>, Output = CtOption<Self>>
144    + for<'a> Div<&'a NonZero<Self>, Output = CtOption<Self>>
145    + From<i8>
146    + From<i16>
147    + From<i32>
148    + From<i64>
149    + Integer // + CtNeg TODO(tarcieri)
150{
151    /// Corresponding unsigned integer type.
152    type Unsigned: Unsigned;
153
154    /// The sign and magnitude of this [`Signed`].
155    #[must_use]
156    fn abs_sign(&self) -> (Self::Unsigned, Choice);
157
158    /// The magnitude of this [`Signed`].
159    #[must_use]
160    fn abs(&self) -> Self::Unsigned {
161        self.abs_sign().0
162    }
163
164    /// Whether this [`Signed`] is negative (and non-zero), as a [`Choice`].
165    #[must_use]
166    fn is_negative(&self) -> Choice;
167
168    /// Whether this [`Signed`] is positive (and non-zero), as a [`Choice`].
169    #[must_use]
170    fn is_positive(&self) -> Choice;
171}
172
173/// Unsigned [`Integer`]s.
174pub trait Unsigned:
175    AsRef<UintRef>
176    + AsMut<UintRef>
177    + AddMod<Output = Self>
178    + BitOps
179    + Div<NonZero<Self>, Output = Self>
180    + for<'a> Div<&'a NonZero<Self>, Output = Self>
181    + DivRemLimb
182    + FloorSquareRoot<Output = Self>
183    + From<u8>
184    + From<u16>
185    + From<u32>
186    + From<u64>
187    + From<Limb>
188    + Integer
189    + MulMod<Output = Self>
190    + NegMod<Output = Self>
191    + RemLimb
192    + SquareMod<Output = Self>
193    + SubMod<Output = Self>
194{
195    /// Borrow the limbs of this unsigned integer as a [`UintRef`].
196    #[must_use]
197    fn as_uint_ref(&self) -> &UintRef;
198
199    /// Mutably borrow the limbs of this unsigned integer as a [`UintRef`].
200    fn as_mut_uint_ref(&mut self) -> &mut UintRef;
201
202    /// Returns an integer with the first limb set to `limb`, and the same precision as `other`.
203    #[must_use]
204    fn from_limb_like(limb: Limb, other: &Self) -> Self;
205}
206
207/// [`Unsigned`] integers with an associated [`MontyForm`].
208pub trait UnsignedWithMontyForm: Unsigned {
209    /// The corresponding Montgomery representation,
210    /// optimized for the performance of modular operations at the price of a conversion overhead.
211    type MontyForm: MontyForm<Integer = Self>;
212}
213
214/// Support for upgrading `UintRef`-compatible references into `Unsigned`.
215pub trait ToUnsigned: AsRef<UintRef> + AsMut<UintRef> {
216    /// The corresponding owned `Unsigned` type.
217    type Unsigned: Unsigned;
218
219    /// Convert from a reference into an owned instance.
220    fn to_unsigned(&self) -> Self::Unsigned;
221
222    /// Convert from a reference into an owned instance representing zero.
223    fn to_unsigned_zero(&self) -> Self::Unsigned {
224        let mut res = self.to_unsigned();
225        res.set_zero();
226        res
227    }
228}
229
230impl<T: Unsigned> ToUnsigned for T {
231    type Unsigned = T;
232
233    fn to_unsigned(&self) -> Self::Unsigned {
234        self.clone()
235    }
236
237    fn to_unsigned_zero(&self) -> Self::Unsigned {
238        T::zero_like(self)
239    }
240}
241
242/// Zero values: additive identity element for `Self`.
243pub trait Zero: CtEq + Sized {
244    /// Returns the additive identity element of `Self`, `0`.
245    #[must_use]
246    fn zero() -> Self;
247
248    /// Determine if this value is equal to `0`.
249    ///
250    /// # Returns
251    ///
252    /// If zero, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
253    #[inline]
254    #[must_use]
255    fn is_zero(&self) -> Choice {
256        self.ct_eq(&Self::zero())
257    }
258
259    /// Set `self` to its additive identity, i.e. `Self::zero`.
260    #[inline]
261    fn set_zero(&mut self) {
262        *self = Zero::zero();
263    }
264
265    /// Return the value `0` with the same precision as `other`.
266    #[must_use]
267    fn zero_like(other: &Self) -> Self
268    where
269        Self: Clone,
270    {
271        let mut ret = other.clone();
272        ret.set_zero();
273        ret
274    }
275}
276
277/// One values: multiplicative identity element for `Self`.
278pub trait One: CtEq + Sized {
279    /// Returns the multiplicative identity element of `Self`, `1`.
280    #[must_use]
281    fn one() -> Self;
282
283    /// Determine if this value is equal to `1`.
284    ///
285    /// # Returns
286    ///
287    /// If one, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
288    #[inline]
289    #[must_use]
290    fn is_one(&self) -> Choice {
291        self.ct_eq(&Self::one())
292    }
293
294    /// Set `self` to its multiplicative identity, i.e. `Self::one`.
295    #[inline]
296    fn set_one(&mut self) {
297        *self = One::one();
298    }
299
300    /// Return the value `0` with the same precision as `other`.
301    #[must_use]
302    fn one_like(_other: &Self) -> Self {
303        One::one()
304    }
305}
306
307/// Trait for associating constant values with a type.
308pub trait Constants: ConstZero + ConstOne {
309    /// Maximum value this integer can express.
310    const MAX: Self;
311}
312
313/// Fixed-width [`Integer`]s.
314pub trait FixedInteger: Bounded + Constants + Copy + Integer {
315    /// The number of limbs used on this platform.
316    const LIMBS: usize;
317}
318
319/// Compute the greatest common divisor of two integers.
320pub trait Gcd<Rhs = Self>: Sized {
321    /// Output type.
322    type Output;
323
324    /// Compute the greatest common divisor of `self` and `rhs`.
325    #[must_use]
326    fn gcd(&self, rhs: &Rhs) -> Self::Output;
327
328    /// Compute the greatest common divisor of `self` and `rhs` in variable time.
329    #[must_use]
330    fn gcd_vartime(&self, rhs: &Rhs) -> Self::Output;
331}
332
333/// Compute the extended greatest common divisor of two integers.
334pub trait Xgcd<Rhs = Self>: Sized {
335    /// Output type.
336    type Output;
337
338    /// Compute the extended greatest common divisor of `self` and `rhs`.
339    #[must_use]
340    fn xgcd(&self, rhs: &Rhs) -> Self::Output;
341
342    /// Compute the extended greatest common divisor of `self` and `rhs` in variable time.
343    #[must_use]
344    fn xgcd_vartime(&self, rhs: &Rhs) -> Self::Output;
345}
346
347/// Random number generation support.
348#[cfg(feature = "rand_core")]
349pub trait Random: Sized {
350    /// Generate a random value.
351    ///
352    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
353    ///
354    /// # Errors
355    /// - Returns `R::Error` in the event the RNG experienced an internal failure.
356    fn try_random_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
357
358    /// Generate a random value.
359    ///
360    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
361    #[must_use]
362    fn random_from_rng<R: Rng + ?Sized>(rng: &mut R) -> Self {
363        let Ok(out) = Self::try_random_from_rng(rng);
364        out
365    }
366
367    /// Randomly generate a value of this type using the system's ambient cryptographically secure
368    /// random number generator.
369    ///
370    /// # Errors
371    /// Returns [`getrandom::Error`] in the event the system's ambient RNG experiences an internal
372    /// failure.
373    #[cfg(feature = "getrandom")]
374    fn try_random() -> Result<Self, getrandom::Error> {
375        Self::try_random_from_rng(&mut getrandom::SysRng)
376    }
377
378    /// Randomly generate a value of this type using the system's ambient cryptographically secure
379    /// random number generator.
380    ///
381    /// # Panics
382    /// This method will panic in the event the system's ambient RNG experiences an internal
383    /// failure.
384    ///
385    /// This shouldn't happen on most modern operating systems.
386    #[cfg(feature = "getrandom")]
387    #[must_use]
388    fn random() -> Self {
389        Self::try_random().expect("RNG failure")
390    }
391}
392
393/// Possible errors of the methods in [`RandomBits`] trait.
394#[cfg(feature = "rand_core")]
395#[derive(Debug)]
396pub enum RandomBitsError<T> {
397    /// An error of the internal RNG library.
398    RandCore(T),
399    /// The requested `bits_precision` does not match the size of the integer
400    /// corresponding to the type (in the cases where this is set in compile time).
401    BitsPrecisionMismatch {
402        /// The requested precision.
403        bits_precision: u32,
404        /// The compile-time size of the integer.
405        integer_bits: u32,
406    },
407    /// The requested `bit_length` is larger than `bits_precision`.
408    BitLengthTooLarge {
409        /// The requested bit length of the random number.
410        bit_length: u32,
411        /// The requested precision.
412        bits_precision: u32,
413    },
414}
415
416#[cfg(feature = "rand_core")]
417impl<T> fmt::Display for RandomBitsError<T>
418where
419    T: fmt::Display,
420{
421    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422        match self {
423            Self::RandCore(err) => write!(f, "{err}"),
424            Self::BitsPrecisionMismatch {
425                bits_precision,
426                integer_bits,
427            } => write!(
428                f,
429                concat![
430                    "The requested `bits_precision` ({}) does not match ",
431                    "the size of the integer corresponding to the type ({})"
432                ],
433                bits_precision, integer_bits
434            ),
435            Self::BitLengthTooLarge {
436                bit_length,
437                bits_precision,
438            } => write!(
439                f,
440                "The requested `bit_length` ({bit_length}) is larger than `bits_precision` ({bits_precision}).",
441            ),
442        }
443    }
444}
445
446#[cfg(feature = "rand_core")]
447impl<T> core::error::Error for RandomBitsError<T> where T: Debug + fmt::Display {}
448
449/// Random bits generation support.
450#[cfg(feature = "rand_core")]
451pub trait RandomBits: Sized {
452    /// Generate a random value in range `[0, 2^bit_length)`.
453    ///
454    /// A wrapper for [`RandomBits::try_random_bits`] that panics on error.
455    #[must_use]
456    fn random_bits<R: TryRng + ?Sized>(rng: &mut R, bit_length: u32) -> Self {
457        Self::try_random_bits(rng, bit_length).expect("try_random_bits() failed")
458    }
459
460    /// Generate a random value in range `[0, 2^bit_length)`.
461    ///
462    /// This method is variable time wrt `bit_length`.
463    ///
464    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
465    ///
466    /// # Errors
467    /// - Returns `R::Error` in the event the RNG experienced an internal failure.
468    fn try_random_bits<R: TryRng + ?Sized>(
469        rng: &mut R,
470        bit_length: u32,
471    ) -> Result<Self, RandomBitsError<R::Error>>;
472
473    /// Generate a random value in range `[0, 2^bit_length)`,
474    /// returning an integer with the closest available size to `bits_precision`
475    /// (if the implementing type supports runtime sizing).
476    ///
477    /// A wrapper for [`RandomBits::try_random_bits_with_precision`] that panics on error.
478    #[must_use]
479    #[track_caller]
480    fn random_bits_with_precision<R: TryRng + ?Sized>(
481        rng: &mut R,
482        bit_length: u32,
483        bits_precision: u32,
484    ) -> Self {
485        Self::try_random_bits_with_precision(rng, bit_length, bits_precision)
486            .expect("try_random_bits_with_precision() failed")
487    }
488
489    /// Generate a random value in range `[0, 2^bit_length)`,
490    /// returning an integer with the closest available size to `bits_precision`
491    /// (if the implementing type supports runtime sizing).
492    ///
493    /// This method is variable time wrt `bit_length`.
494    ///
495    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
496    ///
497    /// # Errors
498    /// - Returns `R::Error` in the event the RNG experienced an internal failure.
499    fn try_random_bits_with_precision<R: TryRng + ?Sized>(
500        rng: &mut R,
501        bit_length: u32,
502        bits_precision: u32,
503    ) -> Result<Self, RandomBitsError<R::Error>>;
504}
505
506/// Modular random number generation support.
507#[cfg(feature = "rand_core")]
508pub trait RandomMod: Sized + Zero {
509    /// Generate a random number which is less than a given `modulus`.
510    ///
511    /// This uses rejection sampling.
512    ///
513    /// As a result, it runs in variable time that depends in part on
514    /// `modulus`. If the generator `rng` is cryptographically secure (for
515    /// example, it implements `CryptoRng`), then this is guaranteed not to
516    /// leak anything about the output value aside from it being less than
517    /// `modulus`.
518    #[must_use]
519    fn random_mod_vartime<R: Rng + ?Sized>(rng: &mut R, modulus: &NonZero<Self>) -> Self {
520        let Ok(out) = Self::try_random_mod_vartime(rng, modulus);
521        out
522    }
523
524    /// Generate a random number which is less than a given `modulus`.
525    ///
526    /// This uses rejection sampling.
527    ///
528    /// As a result, it runs in variable time that depends in part on
529    /// `modulus`. If the generator `rng` is cryptographically secure (for
530    /// example, it implements `CryptoRng`), then this is guaranteed not to
531    /// leak anything about the output value aside from it being less than
532    /// `modulus`.
533    ///
534    /// # Errors
535    /// - Returns `R::Error` in the event the RNG experienced an internal failure.
536    fn try_random_mod_vartime<R: TryRng + ?Sized>(
537        rng: &mut R,
538        modulus: &NonZero<Self>,
539    ) -> Result<Self, R::Error>;
540
541    /// Generate a random number which is less than a given `modulus`.
542    ///
543    /// This uses rejection sampling.
544    ///
545    /// As a result, it runs in variable time that depends in part on
546    /// `modulus`. If the generator `rng` is cryptographically secure (for
547    /// example, it implements `CryptoRng`), then this is guaranteed not to
548    /// leak anything about the output value aside from it being less than
549    /// `modulus`.
550    #[deprecated(since = "0.7.0", note = "please use `random_mod_vartime` instead")]
551    #[must_use]
552    fn random_mod<R: Rng + ?Sized>(rng: &mut R, modulus: &NonZero<Self>) -> Self {
553        Self::random_mod_vartime(rng, modulus)
554    }
555
556    /// Generate a random number which is less than a given `modulus`.
557    ///
558    /// This uses rejection sampling.
559    ///
560    /// As a result, it runs in variable time that depends in part on
561    /// `modulus`. If the generator `rng` is cryptographically secure (for
562    /// example, it implements `CryptoRng`), then this is guaranteed not to
563    /// leak anything about the output value aside from it being less than
564    /// `modulus`.
565    ///
566    /// # Errors
567    /// - Returns `R::Error` in the event the RNG experienced an internal failure.
568    #[deprecated(since = "0.7.0", note = "please use `try_random_mod_vartime` instead")]
569    fn try_random_mod<R: TryRng + ?Sized>(
570        rng: &mut R,
571        modulus: &NonZero<Self>,
572    ) -> Result<Self, R::Error> {
573        Self::try_random_mod_vartime(rng, modulus)
574    }
575}
576
577/// Compute `self + rhs mod p`.
578pub trait AddMod<Rhs = Self, Mod = NonZero<Self>> {
579    /// Output type.
580    type Output;
581
582    /// Compute `self + rhs mod p`.
583    ///
584    /// Assumes `self` and `rhs` are `< p`.
585    #[must_use]
586    fn add_mod(&self, rhs: &Rhs, p: &Mod) -> Self::Output;
587}
588
589/// Compute `self - rhs mod p`.
590pub trait SubMod<Rhs = Self, Mod = NonZero<Self>> {
591    /// Output type.
592    type Output;
593
594    /// Compute `self - rhs mod p`.
595    ///
596    /// Assumes `self` and `rhs` are `< p`.
597    #[must_use]
598    fn sub_mod(&self, rhs: &Rhs, p: &Mod) -> Self::Output;
599}
600
601/// Compute `-self mod p`.
602pub trait NegMod<Mod = NonZero<Self>> {
603    /// Output type.
604    type Output;
605
606    /// Compute `-self mod p`.
607    #[must_use]
608    fn neg_mod(&self, p: &Mod) -> Self::Output;
609}
610
611/// Compute `self * rhs mod p`.
612pub trait MulMod<Rhs = Self, Mod = NonZero<Self>> {
613    /// Output type.
614    type Output;
615
616    /// Compute `self * rhs mod p`.
617    #[must_use]
618    fn mul_mod(&self, rhs: &Rhs, p: &Mod) -> Self::Output;
619}
620
621/// Compute `self * self mod p`.
622pub trait SquareMod<Mod = NonZero<Self>> {
623    /// Output type.
624    type Output;
625
626    /// Compute `self * self mod p`.
627    #[must_use]
628    fn square_mod(&self, p: &Mod) -> Self::Output;
629}
630
631/// Compute `1 / self mod p`.
632#[deprecated(since = "0.7.0", note = "please use `InvertMod` instead")]
633pub trait InvMod<Rhs = Self>: Sized {
634    /// Output type.
635    type Output;
636
637    /// Compute `1 / self mod p`.
638    #[must_use]
639    fn inv_mod(&self, p: &Rhs) -> CtOption<Self::Output>;
640}
641
642#[allow(deprecated)]
643impl<T, Rhs> InvMod<Rhs> for T
644where
645    T: InvertMod<Rhs>,
646{
647    type Output = <T as InvertMod<Rhs>>::Output;
648
649    fn inv_mod(&self, p: &Rhs) -> CtOption<Self::Output> {
650        self.invert_mod(p)
651    }
652}
653
654/// Compute `1 / self mod p`.
655pub trait InvertMod<Mod = NonZero<Self>>: Sized {
656    /// Output type.
657    type Output;
658
659    /// Compute `1 / self mod p`.
660    #[must_use]
661    fn invert_mod(&self, p: &Mod) -> CtOption<Self::Output>;
662}
663
664/// Checked addition.
665pub trait CheckedAdd<Rhs = Self>: Sized {
666    /// Perform checked addition, returning a [`CtOption`] which `is_some` only if the operation
667    /// did not overflow.
668    #[must_use]
669    fn checked_add(&self, rhs: &Rhs) -> CtOption<Self>;
670}
671
672/// Checked division.
673pub trait CheckedDiv<Rhs = Self>: Sized {
674    /// Perform checked division, returning a [`CtOption`] which `is_some` only if the divisor is
675    /// non-zero.
676    #[must_use]
677    fn checked_div(&self, rhs: &Rhs) -> CtOption<Self>;
678}
679
680/// Checked multiplication.
681pub trait CheckedMul<Rhs = Self>: Sized {
682    /// Perform checked multiplication, returning a [`CtOption`] which `is_some`
683    /// only if the operation did not overflow.
684    #[must_use]
685    fn checked_mul(&self, rhs: &Rhs) -> CtOption<Self>;
686}
687
688/// Checked subtraction.
689pub trait CheckedSub<Rhs = Self>: Sized {
690    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
691    /// only if the operation did not underflow.
692    #[must_use]
693    fn checked_sub(&self, rhs: &Rhs) -> CtOption<Self>;
694}
695
696/// Define the result of concatenating two numbers into a "wide" value.
697pub trait Concat<const HI: usize> {
698    /// Concatenated output: having the width of `Self` plus `HI`.
699    type Output: Integer;
700}
701
702/// Define the result of splitting a number into two parts, with the
703/// first part having the width `LO`.
704pub trait Split<const LO: usize> {
705    /// High limbs of output: having the width of `Self` minus `LO`.
706    type Output: Integer;
707}
708
709/// Define the result of splitting a number into two parts, with
710/// each part having an equal width.
711pub trait SplitEven {
712    /// Split output: each component having half the width of `Self`.
713    type Output: Integer;
714}
715
716/// Encoding support.
717pub trait Encoding: Sized {
718    /// Byte array representation.
719    type Repr: AsRef<[u8]>
720        + AsMut<[u8]>
721        + Clone
722        + Sized
723        + for<'a> TryFrom<&'a [u8], Error: core::error::Error>;
724
725    /// Decode from big endian bytes.
726    #[must_use]
727    fn from_be_bytes(bytes: Self::Repr) -> Self;
728
729    /// Decode from little endian bytes.
730    #[must_use]
731    fn from_le_bytes(bytes: Self::Repr) -> Self;
732
733    /// Encode to big endian bytes.
734    #[must_use]
735    fn to_be_bytes(&self) -> Self::Repr;
736
737    /// Encode to little endian bytes.
738    #[must_use]
739    fn to_le_bytes(&self) -> Self::Repr;
740}
741
742/// A trait mapping between encoded representations of integers.
743pub trait EncodedSize {
744    /// The equivalent encoded representation.
745    type Target;
746}
747
748/// Possible errors in variable-time integer decoding methods.
749#[derive(Clone, Copy, Debug, Eq, PartialEq)]
750pub enum DecodeError {
751    /// The input value was empty.
752    Empty,
753
754    /// The input was not consistent with the format restrictions.
755    InvalidDigit,
756
757    /// Input size is too small to fit in the given precision.
758    InputSize,
759
760    /// The deserialized number is larger than the given precision.
761    Precision,
762}
763
764impl fmt::Display for DecodeError {
765    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766        match self {
767            Self::Empty => write!(f, "empty value provided"),
768            Self::InvalidDigit => {
769                write!(f, "invalid digit character")
770            }
771            Self::InputSize => write!(f, "input size is too small to fit in the given precision"),
772            Self::Precision => write!(
773                f,
774                "the deserialized number is larger than the given precision"
775            ),
776        }
777    }
778}
779
780impl core::error::Error for DecodeError {}
781
782/// Support for optimized squaring
783pub trait Square {
784    /// Computes the same as `self * self`, but may be more efficient.
785    #[must_use]
786    fn square(&self) -> Self;
787}
788
789/// Support for optimized squaring in-place
790pub trait SquareAssign {
791    /// Computes the same as `self * self`, but may be more efficient.
792    /// Writes the result in `self`.
793    fn square_assign(&mut self);
794}
795
796/// Support for calculating checked square roots.
797pub trait CheckedSquareRoot: Sized {
798    /// Output of the square root operation.
799    type Output;
800
801    /// Computes `sqrt(self)`, returning `none` if no root exists.
802    #[must_use]
803    fn checked_sqrt(&self) -> CtOption<Self::Output>;
804
805    /// Computes `sqrt(self)`, returning `none` if no root exists.
806    ///
807    /// Variable time with respect to `self`.
808    #[must_use]
809    fn checked_sqrt_vartime(&self) -> Option<Self::Output>;
810}
811
812/// Support for calculating floored square roots.
813pub trait FloorSquareRoot: CheckedSquareRoot {
814    /// Computes `floor(sqrt(self))`.
815    #[must_use]
816    fn floor_sqrt(&self) -> Self::Output;
817
818    /// Computes `floor(sqrt(self))`.
819    ///
820    /// Variable time with respect to `self`.
821    #[must_use]
822    fn floor_sqrt_vartime(&self) -> Self::Output;
823}
824
825/// Support for optimized division by a single limb.
826pub trait DivRemLimb: Sized {
827    /// Computes `self / rhs` using a pre-made reciprocal,
828    /// returns the quotient (q) and remainder (r).
829    #[must_use]
830    fn div_rem_limb(&self, rhs: NonZero<Limb>) -> (Self, Limb) {
831        self.div_rem_limb_with_reciprocal(&Reciprocal::new(rhs))
832    }
833
834    /// Computes `self / rhs`, returns the quotient (q) and remainder (r).
835    #[must_use]
836    fn div_rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> (Self, Limb);
837}
838
839/// Support for calculating the remainder of two differently sized integers.
840pub trait RemMixed<Reductor>: Sized {
841    /// Calculate the remainder of `self` by the `reductor`.
842    #[must_use]
843    fn rem_mixed(&self, reductor: &NonZero<Reductor>) -> Reductor;
844}
845
846/// Modular reduction from a larger value `T`.
847///
848/// This can be seen as fixed modular reduction, where the modulus is fixed at compile time
849/// by `Self`.
850///
851/// For modular reduction with a variable modulus, use [`Rem`].
852pub trait Reduce<T>: Sized {
853    /// Reduces `self` modulo `Modulus`.
854    #[must_use]
855    fn reduce(value: &T) -> Self;
856}
857
858/// Division in variable time.
859pub trait DivVartime: Sized {
860    /// Computes `self / rhs` in variable time.
861    #[must_use]
862    fn div_vartime(&self, rhs: &NonZero<Self>) -> Self;
863}
864
865/// Support for optimized division by a single limb.
866pub trait RemLimb: Sized {
867    /// Computes `self % rhs` using a pre-made reciprocal.
868    #[must_use]
869    fn rem_limb(&self, rhs: NonZero<Limb>) -> Limb {
870        self.rem_limb_with_reciprocal(&Reciprocal::new(rhs))
871    }
872
873    /// Computes `self % rhs`.
874    #[must_use]
875    fn rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> Limb;
876}
877
878/// Bit counting and bit operations.
879pub trait BitOps {
880    /// Precision of this integer in bits.
881    #[must_use]
882    fn bits_precision(&self) -> u32;
883
884    /// `floor(log2(self.bits_precision()))`.
885    #[must_use]
886    fn log2_bits(&self) -> u32 {
887        u32_bits(self.bits_precision()) - 1
888    }
889
890    /// Precision of this integer in bytes.
891    #[must_use]
892    fn bytes_precision(&self) -> usize;
893
894    /// Get the value of the bit at position `index`, as a truthy or falsy `Choice`.
895    /// Returns the falsy value for indices out of range.
896    #[must_use]
897    fn bit(&self, index: u32) -> Choice;
898
899    /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`.
900    fn set_bit(&mut self, index: u32, bit_value: Choice);
901
902    /// Calculate the number of bits required to represent a given number.
903    #[must_use]
904    fn bits(&self) -> u32 {
905        self.bits_precision() - self.leading_zeros()
906    }
907
908    /// Calculate the number of trailing zeros in the binary representation of this number.
909    #[must_use]
910    fn trailing_zeros(&self) -> u32;
911
912    /// Calculate the number of trailing ones in the binary representation of this number.
913    #[must_use]
914    fn trailing_ones(&self) -> u32;
915
916    /// Calculate the number of leading zeros in the binary representation of this number.
917    #[must_use]
918    fn leading_zeros(&self) -> u32;
919
920    /// Returns `true` if the bit at position `index` is set, `false` otherwise.
921    ///
922    /// # Remarks
923    /// This operation is variable time with respect to `index` only.
924    #[must_use]
925    fn bit_vartime(&self, index: u32) -> bool;
926
927    /// Calculate the number of bits required to represent a given number in variable-time with
928    /// respect to `self`.
929    #[must_use]
930    fn bits_vartime(&self) -> u32 {
931        self.bits()
932    }
933
934    /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`,
935    /// variable time in `self`.
936    fn set_bit_vartime(&mut self, index: u32, bit_value: bool);
937
938    /// Calculate the number of leading zeros in the binary representation of this number.
939    #[must_use]
940    fn leading_zeros_vartime(&self) -> u32 {
941        self.bits_precision() - self.bits_vartime()
942    }
943
944    /// Calculate the number of trailing zeros in the binary representation of this number in
945    /// variable-time with respect to `self`.
946    #[must_use]
947    fn trailing_zeros_vartime(&self) -> u32 {
948        self.trailing_zeros()
949    }
950
951    /// Calculate the number of trailing ones in the binary representation of this number,
952    /// variable time in `self`.
953    #[must_use]
954    fn trailing_ones_vartime(&self) -> u32 {
955        self.trailing_ones()
956    }
957}
958
959/// Constant-time exponentiation.
960pub trait Pow<Exponent> {
961    /// Raises to the `exponent` power.
962    #[must_use]
963    fn pow(&self, exponent: &Exponent) -> Self;
964}
965
966impl<T: PowBoundedExp<Exponent>, Exponent: Unsigned> Pow<Exponent> for T {
967    fn pow(&self, exponent: &Exponent) -> Self {
968        self.pow_bounded_exp(exponent, exponent.bits_precision())
969    }
970}
971
972/// Constant-time exponentiation with exponent of a bounded bit size.
973pub trait PowBoundedExp<Exponent> {
974    /// Raises to the `exponent` power,
975    /// with `exponent_bits` representing the number of (least significant) bits
976    /// to take into account for the exponent.
977    ///
978    /// NOTE: `exponent_bits` may be leaked in the time pattern.
979    #[must_use]
980    fn pow_bounded_exp(&self, exponent: &Exponent, exponent_bits: u32) -> Self;
981}
982
983/// Performs modular multi-exponentiation using Montgomery's ladder.
984///
985/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
986pub trait MultiExponentiate<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
987where
988    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
989{
990    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
991    #[must_use]
992    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self;
993}
994
995impl<T, Exponent, BasesAndExponents> MultiExponentiate<Exponent, BasesAndExponents> for T
996where
997    T: MultiExponentiateBoundedExp<Exponent, BasesAndExponents>,
998    Exponent: Bounded,
999    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
1000{
1001    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self {
1002        Self::multi_exponentiate_bounded_exp(bases_and_exponents, Exponent::BITS)
1003    }
1004}
1005
1006/// Performs modular multi-exponentiation using Montgomery's ladder.
1007/// `exponent_bits` represents the number of bits to take into account for the exponent.
1008///
1009/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
1010///
1011/// NOTE: this value is leaked in the time pattern.
1012pub trait MultiExponentiateBoundedExp<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
1013where
1014    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
1015{
1016    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
1017    #[must_use]
1018    fn multi_exponentiate_bounded_exp(
1019        bases_and_exponents: &BasesAndExponents,
1020        exponent_bits: u32,
1021    ) -> Self;
1022}
1023
1024/// Constant-time inversion.
1025pub trait Invert {
1026    /// Output of the inversion.
1027    type Output;
1028
1029    /// Computes the inverse.
1030    fn invert(&self) -> Self::Output;
1031
1032    /// Computes the inverse in variable-time.
1033    fn invert_vartime(&self) -> Self::Output {
1034        self.invert()
1035    }
1036}
1037
1038/// Widening multiply: returns a value with a number of limbs equal to the sum of the inputs.
1039pub trait ConcatenatingMul<Rhs = Self>: Sized {
1040    /// Output of the widening multiplication.
1041    type Output: Integer;
1042
1043    /// Perform widening multiplication.
1044    #[must_use]
1045    fn concatenating_mul(&self, rhs: Rhs) -> Self::Output;
1046}
1047
1048/// Widening square: returns a value with a number of limbs equal to double the sum of the input.
1049pub trait ConcatenatingSquare: Sized {
1050    /// Output of the widening multiplication.
1051    type Output: Integer;
1052
1053    /// Perform widening squaring.
1054    #[must_use]
1055    fn concatenating_square(&self) -> Self::Output;
1056}
1057
1058/// Widening multiply: returns a value with a number of limbs equal to the sum of the inputs.
1059#[deprecated(since = "0.7.0", note = "please use `ConcatenatingMul` instead")]
1060pub trait WideningMul<Rhs = Self>: Sized {
1061    /// Output of the widening multiplication.
1062    type Output: Integer;
1063
1064    /// Perform widening multiplication.
1065    #[must_use]
1066    fn widening_mul(&self, rhs: Rhs) -> Self::Output;
1067}
1068
1069#[allow(deprecated)]
1070impl<T, Rhs> WideningMul<Rhs> for T
1071where
1072    T: ConcatenatingMul<Rhs>,
1073{
1074    type Output = <T as ConcatenatingMul<Rhs>>::Output;
1075
1076    fn widening_mul(&self, rhs: Rhs) -> Self::Output {
1077        self.concatenating_mul(rhs)
1078    }
1079}
1080
1081/// Left shifts, variable time in `shift`.
1082pub trait ShlVartime: Sized {
1083    /// Computes `self << shift`.
1084    ///
1085    /// Returns `None` if `shift >= self.bits_precision()`.
1086    fn overflowing_shl_vartime(&self, shift: u32) -> Option<Self>;
1087
1088    /// Computes `self << shift`.
1089    ///
1090    /// Returns zero if `shift >= self.bits_precision()`.
1091    #[must_use]
1092    fn unbounded_shl_vartime(&self, shift: u32) -> Self;
1093
1094    /// Computes `self << shift` in a panic-free manner, masking off bits of `shift`
1095    /// which would cause the shift to exceed the type's width.
1096    #[must_use]
1097    fn wrapping_shl_vartime(&self, shift: u32) -> Self;
1098}
1099
1100/// Right shifts, variable time in `shift`.
1101pub trait ShrVartime: Sized {
1102    /// Computes `self >> shift`.
1103    ///
1104    /// Returns `None` if `shift >= self.bits_precision()`.
1105    fn overflowing_shr_vartime(&self, shift: u32) -> Option<Self>;
1106
1107    /// Computes `self >> shift`.
1108    ///
1109    /// Returns zero if `shift >= self.bits_precision()`.
1110    #[must_use]
1111    fn unbounded_shr_vartime(&self, shift: u32) -> Self;
1112
1113    /// Computes `self >> shift` in a panic-free manner, masking off bits of `shift`
1114    /// which would cause the shift to exceed the type's width.
1115    #[must_use]
1116    fn wrapping_shr_vartime(&self, shift: u32) -> Self;
1117}
1118
1119/// Methods for resizing the allocated storage.
1120pub trait Resize: Sized {
1121    /// The result of the resizing.
1122    type Output;
1123
1124    /// Resizes to the minimum storage that fits `at_least_bits_precision`
1125    /// without checking if the bit size of `self` is larger than `at_least_bits_precision`.
1126    ///
1127    /// Variable-time w.r.t. `at_least_bits_precision`.
1128    #[must_use]
1129    fn resize_unchecked(self, at_least_bits_precision: u32) -> Self::Output;
1130
1131    /// Resizes to the minimum storage that fits `at_least_bits_precision`
1132    /// returning `None` if the bit size of `self` is larger than `at_least_bits_precision`.
1133    ///
1134    /// Variable-time w.r.t. `at_least_bits_precision`.
1135    fn try_resize(self, at_least_bits_precision: u32) -> Option<Self::Output>;
1136
1137    /// Resizes to the minimum storage that fits `at_least_bits_precision`
1138    /// panicking if the bit size of `self` is larger than `at_least_bits_precision`.
1139    ///
1140    /// Variable-time w.r.t. `at_least_bits_precision`.
1141    #[must_use]
1142    #[track_caller]
1143    fn resize(self, at_least_bits_precision: u32) -> Self::Output {
1144        self.try_resize(at_least_bits_precision).unwrap_or_else(|| {
1145            panic!("The bit size of `self` is larger than `at_least_bits_precision`")
1146        })
1147    }
1148}
1149
1150/// A representation of an integer optimized for the performance of modular operations.
1151pub trait MontyForm:
1152    'static
1153    + Clone
1154    + CtEq
1155    + CtSelect
1156    + Debug
1157    + Eq
1158    + Invert<Output = CtOption<Self>>
1159    + Sized
1160    + Send
1161    + Sync
1162    + Add<Output = Self>
1163    + for<'a> Add<&'a Self, Output = Self>
1164    + AddAssign
1165    + for<'a> AddAssign<&'a Self>
1166    + Sub<Output = Self>
1167    + for<'a> Sub<&'a Self, Output = Self>
1168    + SubAssign
1169    + for<'a> SubAssign<&'a Self>
1170    + Mul<Output = Self>
1171    + for<'a> Mul<&'a Self, Output = Self>
1172    + MulAssign
1173    + for<'a> MulAssign<&'a Self>
1174    + Neg<Output = Self>
1175    + PowBoundedExp<Self::Integer>
1176    + Retrieve<Output = Self::Integer>
1177    + Square
1178    + SquareAssign
1179{
1180    /// The original integer type.
1181    type Integer: UnsignedWithMontyForm<MontyForm = Self>;
1182
1183    /// Prepared Montgomery multiplier for tight loops.
1184    type Multiplier<'a>: Debug + Clone + MontyMultiplier<'a, Monty = Self>;
1185
1186    /// The precomputed data needed for this representation.
1187    type Params: 'static
1188        + AsRef<MontyParams<Self::Integer>>
1189        + From<MontyParams<Self::Integer>>
1190        + Clone
1191        + Debug
1192        + Eq
1193        + Sized
1194        + Send
1195        + Sync;
1196
1197    /// Create the precomputed data for Montgomery representation of integers modulo `modulus`,
1198    /// variable time in `modulus`.
1199    #[must_use]
1200    fn new_params_vartime(modulus: Odd<Self::Integer>) -> Self::Params;
1201
1202    /// Convert the value into the representation using precomputed data.
1203    #[must_use]
1204    fn new(value: Self::Integer, params: &Self::Params) -> Self;
1205
1206    /// Returns zero in this representation.
1207    #[must_use]
1208    fn zero(params: &Self::Params) -> Self;
1209
1210    /// Returns one in this representation.
1211    #[must_use]
1212    fn one(params: &Self::Params) -> Self;
1213
1214    /// Returns the parameter struct used to initialize this object.
1215    #[must_use]
1216    fn params(&self) -> &Self::Params;
1217
1218    /// Access the value in Montgomery form.
1219    #[must_use]
1220    fn as_montgomery(&self) -> &Self::Integer;
1221
1222    /// Copy the Montgomery representation from `other` into `self`.
1223    /// NOTE: the parameters remain unchanged.
1224    fn copy_montgomery_from(&mut self, other: &Self);
1225
1226    /// Move the Montgomery form result out of `self` and return it.
1227    #[must_use]
1228    fn into_montgomery(self) -> Self::Integer;
1229
1230    /// Performs doubling, returning `self + self`.
1231    #[must_use]
1232    fn double(&self) -> Self;
1233
1234    /// Performs division by 2, that is returns `x` such that `x + x = self`.
1235    #[must_use]
1236    fn div_by_2(&self) -> Self;
1237
1238    /// Performs division by 2 inplace, that is finds `x` such that `x + x = self`
1239    /// and writes it into `self`.
1240    fn div_by_2_assign(&mut self) {
1241        *self = self.div_by_2();
1242    }
1243
1244    /// Calculate the sum of products of pairs `(a, b)` in `products`.
1245    ///
1246    /// This method is variable time only with the value of the modulus.
1247    /// For a modulus with leading zeros, this method is more efficient than a naive sum of products.
1248    ///
1249    /// This method will panic if `products` is empty. All terms must be associated with equivalent
1250    /// Montgomery parameters.
1251    #[must_use]
1252    fn lincomb_vartime(products: &[(&Self, &Self)]) -> Self;
1253}
1254
1255/// Prepared Montgomery multiplier for tight loops.
1256///
1257/// Allows one to perform inplace multiplication without allocations
1258/// (important for the `BoxedUint` case).
1259///
1260/// NOTE: You will be operating with Montgomery representations directly,
1261/// make sure they all correspond to the same set of parameters.
1262pub trait MontyMultiplier<'a>: From<&'a <Self::Monty as MontyForm>::Params> {
1263    /// The associated Montgomery-representation integer.
1264    type Monty: MontyForm;
1265
1266    /// Performs a Montgomery multiplication, assigning a fully reduced result to `lhs`.
1267    fn mul_assign(&mut self, lhs: &mut Self::Monty, rhs: &Self::Monty);
1268
1269    /// Performs a Montgomery squaring, assigning a fully reduced result to `lhs`.
1270    fn square_assign(&mut self, lhs: &mut Self::Monty);
1271}
1272
1273/// Prepared Montgomery multiplier for tight loops, performing "Almost Montgomery Multiplication".
1274///
1275/// NOTE: the resulting output of any of these functions will be reduced to the *bit length* of the
1276/// modulus, but not fully reduced and may exceed the modulus. A final reduction is required to
1277/// ensure AMM results are fully reduced, and should not be exposed outside the internals of this
1278/// crate.
1279pub(crate) trait AmmMultiplier<'a>: MontyMultiplier<'a> {
1280    /// Perform an "Almost Montgomery Multiplication", assigning the product to `a`.
1281    fn mul_amm_assign(
1282        &mut self,
1283        a: &mut <Self::Monty as MontyForm>::Integer,
1284        b: &<Self::Monty as MontyForm>::Integer,
1285    );
1286
1287    /// Perform a squaring using "Almost Montgomery Multiplication", assigning the result to `a`.
1288    fn square_amm_assign(&mut self, a: &mut <Self::Monty as MontyForm>::Integer);
1289}
1290
1291/// Support for sealing traits defined in this module.
1292pub(crate) mod sealed {
1293    /// Sealed trait.
1294    pub trait Sealed {}
1295}
1296
1297#[cfg(test)]
1298pub(crate) mod tests {
1299    use super::{Integer, Signed, ToUnsigned, Unsigned};
1300    use crate::{Choice, CtEq, CtSelect, Limb, NonZero, One, Zero};
1301
1302    /// Apply a suite of tests against a type implementing Integer.
1303    pub fn test_integer<T: Integer>(min: T, max: T) {
1304        let zero = T::zero_like(&min);
1305        let one = T::one_like(&min);
1306        let two = one.clone() + &one;
1307        let inputs = &[zero.clone(), one.clone(), max.clone()];
1308        let nz_one = NonZero::new(one.clone()).expect("must be non-zero");
1309        let nz_two = NonZero::new(two.clone()).expect("must be non-zero");
1310
1311        // FIXME Could use itertools combinations or an equivalent iterator
1312        let pairs = &[
1313            (zero.clone(), zero.clone()),
1314            (zero.clone(), one.clone()),
1315            (zero.clone(), max.clone()),
1316            (one.clone(), zero.clone()),
1317            (one.clone(), one.clone()),
1318            (one.clone(), max.clone()),
1319            (max.clone(), zero.clone()),
1320            (max.clone(), one.clone()),
1321            (max.clone(), max.clone()),
1322        ];
1323
1324        // Test formatting
1325        #[cfg(feature = "alloc")]
1326        for a in inputs {
1327            let _ = format!("{a:?}");
1328            let _ = format!("{a:#?}");
1329            let _ = format!("{a:b}");
1330            let _ = format!("{a:x}");
1331            let _ = format!("{a:X}");
1332        }
1333
1334        // Default must be zero
1335        assert_eq!(T::default(), zero);
1336
1337        // Sanity checks
1338        assert_eq!(zero, T::zero());
1339        assert_eq!(one, T::one());
1340        assert_ne!(zero, one);
1341        assert_ne!(zero, max);
1342        assert_ne!(min, max);
1343
1344        // Even/odd trait methods
1345        assert!(zero.is_even().to_bool());
1346        assert!(!zero.is_odd().to_bool());
1347        assert!(!one.is_even().to_bool());
1348        assert!(one.is_odd().to_bool());
1349        assert!(two.is_even().to_bool());
1350        assert!(!two.is_odd().to_bool());
1351
1352        // AsRef<[Limb]>, Eq, Ord, CtEq, CtGt, CtLt, CtNe
1353        for (a, b) in pairs {
1354            assert_eq!(a.nlimbs(), a.as_limbs().len());
1355            assert_eq!(a.as_limbs(), a.as_ref());
1356            assert_eq!(a.clone().as_mut_limbs(), a.clone().as_mut());
1357            assert_eq!(&*a.clone().as_mut_limbs(), a.as_limbs());
1358            assert_eq!(
1359                a.ct_eq(b).to_bool(),
1360                a.as_limbs().ct_eq(b.as_limbs()).to_bool()
1361            );
1362            assert_ne!(a.ct_eq(b).to_bool(), a.ct_ne(b).to_bool());
1363            if a == b {
1364                assert!(!a.ct_lt(b).to_bool());
1365                assert!(!a.ct_gt(b).to_bool());
1366            } else {
1367                assert_ne!(a.ct_lt(b).to_bool(), a.ct_gt(b).to_bool());
1368            }
1369            assert_eq!(a.ct_lt(b).to_bool(), a < b);
1370            assert_eq!(a.ct_gt(b).to_bool(), a > b);
1371        }
1372
1373        // CtAssign, CtSelect
1374        for (a, b) in pairs {
1375            let mut c = a.clone();
1376            c.ct_assign(b, Choice::FALSE);
1377            assert_eq!(&c, a);
1378            c.ct_assign(b, Choice::TRUE);
1379            assert_eq!(&c, b);
1380
1381            assert_eq!(&CtSelect::ct_select(a, b, Choice::FALSE), a);
1382            assert_eq!(&CtSelect::ct_select(a, b, Choice::TRUE), b);
1383            let (mut c, mut d) = (a.clone(), b.clone());
1384            CtSelect::ct_swap(&mut c, &mut d, Choice::FALSE);
1385            assert_eq!((&c, &d), (a, b));
1386            CtSelect::ct_swap(&mut c, &mut d, Choice::TRUE);
1387            assert_eq!((&c, &d), (b, a));
1388        }
1389
1390        // BitAnd
1391        for a in inputs {
1392            assert_eq!(a.clone().bitand(zero.clone()), zero);
1393            assert_eq!(a.clone().bitand(&zero), zero);
1394            assert_eq!(&a.clone().bitand(a), a);
1395            assert_eq!(zero.clone().bitand(a), zero);
1396            assert_eq!(a.clone().not().bitand(a), zero);
1397            // BitAndAssign ref
1398            let mut b = a.clone();
1399            b &= a.clone();
1400            assert_eq!(a, &b);
1401            // BitAndAssign owned
1402            let mut b = a.clone();
1403            b &= a;
1404            assert_eq!(a, &b);
1405        }
1406
1407        // BitOr
1408        for a in inputs {
1409            assert_eq!(&a.clone().bitor(zero.clone()), a);
1410            assert_eq!(&a.clone().bitor(&zero), a);
1411            assert_eq!(&a.clone().bitor(a), a);
1412            assert_eq!(&zero.clone().bitor(a), a);
1413            // BitOrAssign ref
1414            let mut b = a.clone();
1415            b |= a;
1416            assert_eq!(a, &b);
1417            // BitOrAssign owned
1418            let mut b = a.clone();
1419            b |= a.clone();
1420            assert_eq!(a, &b);
1421        }
1422
1423        // BitXor
1424        for a in inputs {
1425            assert_eq!(&a.clone().bitxor(zero.clone()), a);
1426            assert_eq!(&a.clone().bitor(&zero), a);
1427            assert_eq!(a.clone().bitxor(a), zero);
1428            assert_eq!(&zero.clone().bitxor(a), a);
1429            // BitXorAssign ref
1430            let mut b = a.clone();
1431            b ^= a;
1432            assert_eq!(T::zero(), b);
1433            // BitXorAssign owned
1434            let mut b = a.clone();
1435            b ^= a.clone();
1436            assert_eq!(T::zero(), b);
1437        }
1438
1439        // Shr/Shl
1440        assert_eq!(zero.clone().shr(1u32), zero);
1441        assert_eq!(one.clone().shr(1u32), zero);
1442        assert_eq!(zero.clone().shl(1u32), zero);
1443        assert_eq!(one.clone().shl(1u32), two);
1444        assert_eq!(two.clone().shr(1u32), one);
1445        assert_ne!(max.clone().shr(1u32), max);
1446        let mut expect = one.clone();
1447        expect.shl_assign(1);
1448        assert_eq!(expect, two);
1449        expect.shr_assign(1);
1450        assert_eq!(expect, one);
1451
1452        // Non-carrying Add
1453        for a in inputs {
1454            assert_eq!(&a.clone().add(zero.clone()), a);
1455            assert_eq!(&a.clone().add(&zero), a);
1456            assert_eq!(&zero.clone().add(a), a);
1457            // AddAssign ref
1458            let mut b = a.clone();
1459            b += &zero;
1460            assert_eq!(a, &b);
1461            // AddAssign owned
1462            let mut b = a.clone();
1463            b += zero.clone();
1464            assert_eq!(a, &b);
1465        }
1466
1467        // Non-borrowing Sub
1468        for a in inputs {
1469            assert_eq!(&a.clone().sub(zero.clone()), a);
1470            assert_eq!(&a.clone().sub(&zero), a);
1471            assert_eq!(a.clone().sub(a), zero);
1472            // SubAssign ref
1473            let mut b = a.clone();
1474            b -= a;
1475            assert_eq!(zero, b);
1476            // SubAssign owned
1477            let mut b = a.clone();
1478            b -= a.clone();
1479            assert_eq!(zero, b);
1480        }
1481
1482        // Non-carrying Mul
1483        for a in inputs {
1484            assert_eq!(a.clone().mul(zero.clone()), zero);
1485            assert_eq!(a.clone().mul(&zero), zero);
1486            assert_eq!(&a.clone().mul(&one), a);
1487            assert_eq!(zero.clone().mul(a), zero);
1488            assert_eq!(&one.clone().mul(a), a);
1489            // MulAssign ref
1490            let mut b = a.clone();
1491            b *= &one;
1492            assert_eq!(a, &b);
1493            // MulAssign owned
1494            let mut b = a.clone();
1495            b *= one.clone();
1496            assert_eq!(a, &b);
1497        }
1498
1499        // DivAssign ref
1500        let mut a = one.clone();
1501        a /= &nz_one;
1502        assert_eq!(a, one);
1503        // DivAssign owned
1504        let mut a = one.clone();
1505        a /= nz_one.clone();
1506        assert_eq!(a, one);
1507
1508        // Rem
1509        assert_eq!(zero.clone().rem(&nz_one), zero);
1510        assert_eq!(zero.clone().rem(nz_one.clone()), zero);
1511        assert_eq!(one.clone().rem(&nz_one), zero);
1512        assert_eq!(one.clone().rem(&nz_two), one);
1513        // RemAssign ref
1514        let mut a = one.clone();
1515        a %= &nz_one;
1516        assert_eq!(a, zero);
1517        // RemAssign owned
1518        let mut a = one.clone();
1519        a %= nz_one.clone();
1520        assert_eq!(a, zero);
1521
1522        // CheckedAdd
1523        assert_eq!(
1524            zero.clone().checked_add(&zero).into_option(),
1525            Some(zero.clone())
1526        );
1527        assert_eq!(
1528            zero.clone().checked_add(&one).into_option(),
1529            Some(one.clone())
1530        );
1531        assert_eq!(
1532            zero.clone().checked_add(&max).into_option(),
1533            Some(max.clone())
1534        );
1535        assert_eq!(max.checked_add(&one).into_option(), None);
1536        assert_eq!(max.checked_add(&max).into_option(), None);
1537
1538        // CheckedSub
1539        assert_eq!(
1540            zero.clone().checked_sub(&zero).into_option(),
1541            Some(zero.clone())
1542        );
1543        assert_eq!(min.checked_sub(&zero).into_option(), Some(min.clone()));
1544        assert_eq!(min.checked_sub(&one).into_option(), None);
1545        assert_eq!(min.checked_sub(&max).into_option(), None);
1546        assert_eq!(max.checked_sub(&zero).into_option(), Some(max.clone()));
1547        assert_eq!(max.checked_sub(&max).into_option(), Some(zero.clone()));
1548
1549        // CheckedMul
1550        assert_eq!(
1551            zero.clone().checked_mul(&zero).into_option(),
1552            Some(zero.clone())
1553        );
1554        assert_eq!(
1555            zero.clone().checked_mul(&one).into_option(),
1556            Some(zero.clone())
1557        );
1558        assert_eq!(
1559            one.clone().checked_mul(&max).into_option(),
1560            Some(max.clone())
1561        );
1562        assert_eq!(max.checked_mul(&max).into_option(), None);
1563
1564        // CheckedDiv
1565        assert_eq!(zero.clone().checked_div(&zero).into_option(), None);
1566        assert_eq!(one.clone().checked_div(&zero).into_option(), None);
1567        assert_eq!(
1568            one.clone().checked_div(&one).into_option(),
1569            Some(one.clone())
1570        );
1571        assert_eq!(max.checked_div(&max).into_option(), Some(one.clone()));
1572
1573        // CheckedSquareRoot
1574        assert_eq!(zero.checked_sqrt().into_option(), Some(zero.clone()));
1575        assert_eq!(zero.checked_sqrt_vartime(), Some(zero.clone()));
1576        assert_eq!(one.checked_sqrt().into_option(), Some(one.clone()));
1577        assert_eq!(one.checked_sqrt_vartime(), Some(one.clone()));
1578        assert_eq!(two.checked_sqrt().into_option(), None);
1579        assert_eq!(two.checked_sqrt_vartime(), None);
1580
1581        // WrappingAdd
1582        assert_eq!(zero.clone().wrapping_add(&zero), zero);
1583        assert_eq!(zero.clone().wrapping_add(&one), one);
1584        assert_eq!(one.clone().wrapping_add(&zero), one);
1585        assert_eq!(one.clone().wrapping_add(&one), two);
1586        assert_eq!(one.clone().wrapping_add(&max), min);
1587        assert_eq!(max.wrapping_add(&one), min);
1588
1589        // WrappingSub
1590        assert_eq!(zero.clone().wrapping_sub(&zero), zero);
1591        assert_eq!(one.clone().wrapping_sub(&zero), one);
1592        assert_eq!(two.wrapping_sub(&one), one);
1593        assert_eq!(min.wrapping_sub(&one), max);
1594        assert_eq!(min.wrapping_sub(&min), zero);
1595
1596        // WrappingMul
1597        assert_eq!(zero.clone().wrapping_mul(&zero), zero);
1598        assert_eq!(zero.clone().wrapping_mul(&one), zero);
1599        assert_eq!(one.clone().wrapping_mul(&zero), zero);
1600        assert_eq!(one.clone().wrapping_mul(&one), one);
1601        assert_eq!(one.clone().wrapping_mul(&max), max);
1602        assert_eq!(max.wrapping_mul(&zero), zero);
1603        assert_eq!(max.wrapping_mul(&one), max);
1604        assert_eq!(max.wrapping_mul(&two), max.clone().shl(1u32));
1605
1606        // WrappingNeg
1607        assert_eq!(zero.clone().wrapping_neg(), zero);
1608        for a in inputs {
1609            assert_eq!(a.wrapping_add(&a.wrapping_neg()), zero);
1610            assert_eq!(zero.wrapping_sub(a), a.wrapping_neg());
1611        }
1612
1613        // WrappingShr/WrappingShl
1614        assert_eq!(zero.clone().wrapping_shr(1u32), zero);
1615        assert_eq!(one.clone().wrapping_shr(1u32), zero);
1616        assert_eq!(zero.clone().wrapping_shl(1u32), zero);
1617        assert_eq!(one.clone().wrapping_shl(1u32), two);
1618        assert_eq!(two.clone().wrapping_shr(1u32), one);
1619        assert_ne!(max.clone().wrapping_shr(1u32), max);
1620    }
1621
1622    /// Apply a suite of tests against a type implementing Unsigned.
1623    pub fn test_unsigned<T: Unsigned>(min: T, max: T) {
1624        let zero = T::zero_like(&min);
1625        let one = T::one_like(&min);
1626        let two = one.clone() + &one;
1627        let nz_one = NonZero::new(one.clone()).expect("must be non-zero");
1628        let nz_two = NonZero::new(two.clone()).expect("must be non-zero");
1629        let nz_limb_one = NonZero::new(Limb::ONE).expect("must be non-zero");
1630        let nz_limb_two = NonZero::new(Limb::from(2u8)).expect("must be non-zero");
1631        let inputs = &[zero.clone(), one.clone(), max.clone()];
1632
1633        // Test Integer trait
1634        test_integer(min.clone(), max.clone());
1635
1636        // Trait methods
1637        for a in inputs {
1638            assert_eq!(a.as_uint_ref(), a.as_ref());
1639            assert_eq!(a.clone().as_mut_uint_ref(), a.clone().as_mut());
1640            assert_eq!(T::from_limb_like(Limb::ZERO, &one), zero);
1641            assert_eq!(T::from_limb_like(Limb::ONE, &one), one);
1642        }
1643
1644        // Zero trait
1645        assert!(zero.is_zero().to_bool());
1646        assert!(!one.is_zero().to_bool());
1647        let mut a = one.clone();
1648        a.set_zero();
1649        assert_eq!(a, zero);
1650
1651        // One trait
1652        assert!(!zero.is_one().to_bool());
1653        assert!(one.is_one().to_bool());
1654        let mut a = zero.clone();
1655        a.set_one();
1656        assert_eq!(a, one);
1657
1658        // From implementations
1659        assert_eq!(T::from(0u8), T::zero());
1660        assert_eq!(T::from(1u8), T::one());
1661        assert_eq!(T::from(1u16), T::one());
1662        assert_eq!(T::from(1u32), T::one());
1663        assert_eq!(T::from(1u64), T::one());
1664        assert_eq!(T::from(Limb::ONE), T::one());
1665
1666        // ToUnsigned
1667        assert_eq!(one.to_unsigned(), one);
1668        assert_eq!(one.to_unsigned_zero(), zero);
1669
1670        // FloorSquareRoot
1671        assert_eq!(zero.floor_sqrt(), zero);
1672        assert_eq!(zero.floor_sqrt_vartime(), zero);
1673        assert_eq!(one.floor_sqrt(), one);
1674        assert_eq!(one.floor_sqrt_vartime(), one);
1675        assert_eq!(two.floor_sqrt(), one);
1676        assert_eq!(two.floor_sqrt_vartime(), one);
1677
1678        // Div by ref
1679        assert_eq!(zero.clone().div(&nz_one), zero);
1680        assert_eq!(zero.clone().div(&nz_two), zero);
1681        assert_eq!(one.clone().div(&nz_one), one);
1682        assert_eq!(one.clone().div(&nz_two), zero);
1683        // Div by owned
1684        assert_eq!(zero.clone().div(nz_one.clone()), zero);
1685        assert_eq!(zero.clone().div(nz_two.clone()), zero);
1686        assert_eq!(one.clone().div(nz_one.clone()), one);
1687        assert_eq!(one.clone().div(nz_two.clone()), zero);
1688
1689        // DivRemLimb
1690        assert_eq!(zero.div_rem_limb(nz_limb_one), (zero.clone(), Limb::ZERO));
1691        assert_eq!(zero.div_rem_limb(nz_limb_two), (zero.clone(), Limb::ZERO));
1692        assert_eq!(one.div_rem_limb(nz_limb_one), (one.clone(), Limb::ZERO));
1693        assert_eq!(one.div_rem_limb(nz_limb_two), (zero.clone(), Limb::ONE));
1694
1695        // RemLimb
1696        assert_eq!(zero.rem_limb(nz_limb_one), Limb::ZERO);
1697        assert_eq!(zero.rem_limb(nz_limb_two), Limb::ZERO);
1698        assert_eq!(one.rem_limb(nz_limb_one), Limb::ZERO);
1699        assert_eq!(one.rem_limb(nz_limb_two), Limb::ONE);
1700
1701        // BitOps
1702        assert_eq!(zero.bits(), 0);
1703        assert_eq!(one.bits(), 1);
1704        assert_eq!(one.bits_vartime(), 1);
1705        assert_eq!(one.bits_precision() as usize, one.bytes_precision() * 8);
1706        assert_eq!(one.bits_precision(), 1 << one.log2_bits());
1707        // Leading/trailing zeros and ones
1708        assert_eq!(zero.leading_zeros(), zero.bits_precision());
1709        assert_eq!(zero.leading_zeros_vartime(), zero.bits_precision());
1710        assert_eq!(zero.trailing_zeros(), zero.bits_precision());
1711        assert_eq!(zero.trailing_zeros_vartime(), zero.bits_precision());
1712        assert_eq!(zero.trailing_ones(), 0);
1713        assert_eq!(zero.trailing_ones_vartime(), 0);
1714        assert_eq!(one.leading_zeros(), one.bits_precision() - 1);
1715        assert_eq!(one.leading_zeros_vartime(), one.bits_precision() - 1);
1716        assert_eq!(one.trailing_zeros(), 0);
1717        assert_eq!(one.trailing_zeros_vartime(), 0);
1718        assert_eq!(one.trailing_ones(), 1);
1719        assert_eq!(one.trailing_ones_vartime(), 1);
1720        // Bit access
1721        assert!(!zero.bit(0).to_bool());
1722        assert!(!zero.bit_vartime(0));
1723        assert!(one.bit(0).to_bool());
1724        assert!(one.bit_vartime(0));
1725        assert!(!one.bit(1).to_bool());
1726        assert!(!one.bit_vartime(1));
1727        // Bit assignment
1728        let mut a = zero.clone();
1729        a.set_bit(0, Choice::TRUE);
1730        assert_eq!(a, one);
1731        let mut a = zero.clone();
1732        a.set_bit_vartime(0, true);
1733        assert_eq!(a, one);
1734        let mut a = one.clone();
1735        a.set_bit(0, Choice::FALSE);
1736        assert_eq!(a, zero);
1737        let mut a = one.clone();
1738        a.set_bit_vartime(0, false);
1739        assert_eq!(a, zero);
1740
1741        // AddMod
1742        assert_eq!(zero.add_mod(&zero, &nz_two), zero);
1743        assert_eq!(zero.add_mod(&one, &nz_two), one);
1744        assert_eq!(one.add_mod(&zero, &nz_two), one);
1745        assert_eq!(one.add_mod(&one, &nz_two), zero);
1746
1747        // SubMod
1748        assert_eq!(zero.sub_mod(&zero, &nz_two), zero);
1749        assert_eq!(zero.sub_mod(&one, &nz_two), one);
1750        assert_eq!(one.sub_mod(&zero, &nz_two), one);
1751        assert_eq!(one.sub_mod(&one, &nz_two), zero);
1752
1753        // MulMod
1754        assert_eq!(zero.mul_mod(&zero, &nz_two), zero);
1755        assert_eq!(zero.mul_mod(&one, &nz_two), zero);
1756        assert_eq!(one.mul_mod(&zero, &nz_two), zero);
1757        assert_eq!(one.mul_mod(&one, &nz_two), one);
1758
1759        // SquareMod
1760        assert_eq!(zero.square_mod(&nz_two), zero);
1761        assert_eq!(one.square_mod(&nz_two), one);
1762
1763        // NegMod
1764        assert_eq!(zero.neg_mod(&nz_two), zero);
1765        assert_eq!(one.neg_mod(&nz_two), one);
1766    }
1767
1768    pub fn test_signed<T: Signed>(min: T, max: T) {
1769        let zero = T::zero_like(&min);
1770        let one = T::one_like(&min);
1771        let two = one.clone() + &one;
1772        let zero_unsigned = T::Unsigned::zero();
1773        let one_unsigned = T::Unsigned::one();
1774        let minus_one = T::from(-1i8);
1775        let nz_one = NonZero::new(one.clone()).expect("must be non-zero");
1776        let nz_minus_one = NonZero::new(minus_one.clone()).expect("must be non-zero");
1777        let nz_two = NonZero::new(two.clone()).expect("must be non-zero");
1778
1779        // Test Integer trait
1780        test_integer(min.clone(), max.clone());
1781
1782        // Trait sign methods
1783        assert!(!zero.is_positive().to_bool());
1784        assert!(!zero.is_negative().to_bool());
1785        assert!(one.is_positive().to_bool());
1786        assert!(!one.is_negative().to_bool());
1787        assert!(!minus_one.is_positive().to_bool());
1788        assert!(minus_one.is_negative().to_bool());
1789        // Trait abs methods
1790        assert_eq!(zero.abs(), zero_unsigned);
1791        assert_eq!(one.abs(), one_unsigned);
1792        assert_eq!(minus_one.abs(), one_unsigned);
1793        let (check, check_sign) = zero.abs_sign();
1794        assert_eq!(
1795            (check, check_sign.to_bool()),
1796            (zero_unsigned.clone(), false)
1797        );
1798        let (check, check_sign) = one.abs_sign();
1799        assert_eq!((check, check_sign.to_bool()), (one_unsigned.clone(), false));
1800        let (check, check_sign) = minus_one.abs_sign();
1801        assert_eq!((check, check_sign.to_bool()), (one_unsigned.clone(), true));
1802
1803        // From implementations
1804        assert_eq!(T::from(0i8), T::zero());
1805        assert_eq!(T::from(1i8), T::one());
1806        assert_eq!(T::from(1i16), T::one());
1807        assert_eq!(T::from(1i32), T::one());
1808        assert_eq!(T::from(1i64), T::one());
1809        assert_eq!(T::from(-1i64), T::zero() - T::one());
1810
1811        // Div by ref
1812        assert_eq!(zero.clone().div(&nz_one).into_option(), Some(zero.clone()));
1813        assert_eq!(
1814            zero.clone().div(&nz_minus_one).into_option(),
1815            Some(zero.clone())
1816        );
1817        assert_eq!(zero.clone().div(&nz_two).into_option(), Some(zero.clone()));
1818        assert_eq!(one.clone().div(&nz_one).into_option(), Some(one.clone()));
1819        assert_eq!(
1820            one.clone().div(&nz_minus_one).into_option(),
1821            Some(minus_one.clone())
1822        );
1823        assert_eq!(one.clone().div(&nz_two).into_option(), Some(zero.clone()));
1824        // Div by owned
1825        assert_eq!(
1826            zero.clone().div(nz_one.clone()).into_option(),
1827            Some(zero.clone())
1828        );
1829        assert_eq!(
1830            zero.clone().div(nz_minus_one.clone()).into_option(),
1831            Some(zero.clone())
1832        );
1833        assert_eq!(
1834            zero.clone().div(nz_two.clone()).into_option(),
1835            Some(zero.clone())
1836        );
1837        assert_eq!(
1838            one.clone().div(nz_one.clone()).into_option(),
1839            Some(one.clone())
1840        );
1841        assert_eq!(
1842            one.clone().div(nz_minus_one.clone()).into_option(),
1843            Some(minus_one.clone())
1844        );
1845        assert_eq!(
1846            one.clone().div(nz_two.clone()).into_option(),
1847            Some(zero.clone())
1848        );
1849    }
1850}