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