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