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