crypto_bigint/
traits.rs

1//! Traits provided by this crate
2
3mod sealed;
4
5pub use num_traits::{
6    ConstZero, WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
7};
8
9pub(crate) use sealed::PrecomputeInverterWithAdjuster;
10
11use crate::{Limb, NonZero, Odd, Reciprocal, modular::Retrieve};
12use core::fmt::{self, Debug};
13use core::ops::{
14    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
15    Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
16};
17use subtle::{
18    Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
19    CtOption,
20};
21
22#[cfg(feature = "rand_core")]
23use rand_core::{RngCore, TryRngCore};
24
25/// Integers whose representation takes a bounded amount of space.
26pub trait Bounded {
27    /// Size of this integer in bits.
28    const BITS: u32;
29
30    /// Size of this integer in bytes.
31    const BYTES: usize;
32}
33
34/// Trait for types which are conditionally selectable in constant time.
35///
36/// Similar to (and blanket impl'd for) `subtle`'s [`ConditionallySelectable`] trait, but without
37/// the `Copy` bound which allows it to be impl'd for heap allocated types such as `BoxedUint`.
38///
39/// It also provides generic implementations of conditional assignment and conditional swaps.
40pub trait ConstantTimeSelect: Clone {
41    /// Select `a` or `b` according to `choice`.
42    ///
43    /// # Returns
44    /// - `a` if `choice == Choice(0)`;
45    /// - `b` if `choice == Choice(1)`.
46    fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self;
47
48    /// Conditionally assign `other` to `self`, according to `choice`.
49    #[inline]
50    fn ct_assign(&mut self, other: &Self, choice: Choice) {
51        *self = Self::ct_select(self, other, choice);
52    }
53
54    /// Conditionally swap `self` and `other` if `choice == 1`; otherwise, reassign both unto themselves.
55    #[inline]
56    fn ct_swap(a: &mut Self, b: &mut Self, choice: Choice) {
57        let t: Self = a.clone();
58        a.ct_assign(b, choice);
59        b.ct_assign(&t, choice);
60    }
61}
62
63impl<T: ConditionallySelectable> ConstantTimeSelect for T {
64    #[inline(always)]
65    fn ct_select(a: &Self, b: &Self, choice: Choice) -> Self {
66        T::conditional_select(a, b, choice)
67    }
68
69    #[inline(always)]
70    fn ct_assign(&mut self, other: &Self, choice: Choice) {
71        self.conditional_assign(other, choice)
72    }
73
74    #[inline(always)]
75    fn ct_swap(a: &mut Self, b: &mut Self, choice: Choice) {
76        T::conditional_swap(a, b, choice)
77    }
78}
79
80/// Integer trait: represents common functionality of integer types provided by this crate.
81pub trait Integer:
82    'static
83    + Add<Output = Self>
84    + for<'a> Add<&'a Self, Output = Self>
85    + AddAssign<Self>
86    + for<'a> AddAssign<&'a Self>
87    + AddMod<Output = Self>
88    + AsRef<[Limb]>
89    + BitAnd<Output = Self>
90    + for<'a> BitAnd<&'a Self, Output = Self>
91    + BitAndAssign
92    + for<'a> BitAndAssign<&'a Self>
93    + BitOr<Output = Self>
94    + for<'a> BitOr<&'a Self, Output = Self>
95    + BitOrAssign
96    + for<'a> BitOrAssign<&'a Self>
97    + BitXor<Output = Self>
98    + for<'a> BitXor<&'a Self, Output = Self>
99    + BitXorAssign
100    + for<'a> BitXorAssign<&'a Self>
101    + BitOps
102    + CheckedAdd
103    + CheckedSub
104    + CheckedMul
105    + CheckedDiv
106    + Clone
107    + ConstantTimeEq
108    + ConstantTimeGreater
109    + ConstantTimeLess
110    + ConstantTimeSelect
111    + Debug
112    + Default
113    + Div<NonZero<Self>, Output = Self>
114    + for<'a> Div<&'a NonZero<Self>, Output = Self>
115    + DivAssign<NonZero<Self>>
116    + for<'a> DivAssign<&'a NonZero<Self>>
117    + DivRemLimb
118    + Eq
119    + fmt::LowerHex
120    + fmt::UpperHex
121    + fmt::Binary
122    + From<u8>
123    + From<u16>
124    + From<u32>
125    + From<u64>
126    + From<Limb>
127    + Mul<Output = Self>
128    + for<'a> Mul<&'a Self, Output = Self>
129    + MulAssign<Self>
130    + for<'a> MulAssign<&'a Self>
131    + MulMod<Output = Self>
132    + NegMod<Output = Self>
133    + Not<Output = Self>
134    + Ord
135    + Rem<NonZero<Self>, Output = Self>
136    + for<'a> Rem<&'a NonZero<Self>, Output = Self>
137    + RemAssign<NonZero<Self>>
138    + for<'a> RemAssign<&'a NonZero<Self>>
139    + RemLimb
140    + Send
141    + Sized
142    + Shl<u32, Output = Self>
143    + ShlAssign<u32>
144    + ShlVartime
145    + Shr<u32, Output = Self>
146    + ShrAssign<u32>
147    + ShrVartime
148    + Sub<Output = Self>
149    + for<'a> Sub<&'a Self, Output = Self>
150    + SubAssign<Self>
151    + for<'a> SubAssign<&'a Self>
152    + SubMod<Output = Self>
153    + Sync
154    + SquareRoot
155    + WrappingAdd
156    + WrappingSub
157    + WrappingMul
158    + WrappingNeg
159    + WrappingShl
160    + WrappingShr
161    + Zero
162{
163    /// The corresponding Montgomery representation,
164    /// optimized for the performance of modular operations at the price of a conversion overhead.
165    type Monty: Monty<Integer = Self>;
166
167    /// The value `1`.
168    fn one() -> Self;
169
170    /// The value `1` with the same precision as `other`.
171    fn one_like(other: &Self) -> Self {
172        Self::from_limb_like(Limb::ONE, other)
173    }
174
175    /// Returns an integer with the first limb set to `limb`, and the same precision as `other`.
176    fn from_limb_like(limb: Limb, other: &Self) -> Self;
177
178    /// Number of limbs in this integer.
179    fn nlimbs(&self) -> usize;
180
181    /// Is this integer value an odd number?
182    ///
183    /// # Returns
184    ///
185    /// If odd, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
186    fn is_odd(&self) -> Choice {
187        self.as_ref()
188            .first()
189            .map(|limb| limb.is_odd())
190            .unwrap_or_else(|| Choice::from(0))
191    }
192
193    /// Is this integer value an even number?
194    ///
195    /// # Returns
196    ///
197    /// If even, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
198    fn is_even(&self) -> Choice {
199        !self.is_odd()
200    }
201}
202
203/// Fixed-width integers.
204pub trait FixedInteger: Bounded + ConditionallySelectable + Constants + Copy + Integer {
205    /// The number of limbs used on this platform.
206    const LIMBS: usize;
207}
208
209/// Compute the greatest common divisor of two integers.
210pub trait Gcd<Rhs = Self>: Sized {
211    /// Output type.
212    type Output;
213
214    /// Compute the greatest common divisor of `self` and `rhs`.
215    fn gcd(&self, rhs: &Rhs) -> Self::Output;
216
217    /// Compute the greatest common divisor of `self` and `rhs` in variable time.
218    fn gcd_vartime(&self, rhs: &Rhs) -> Self::Output;
219}
220
221/// Trait impl'd by precomputed modular inverters obtained via the [`PrecomputeInverter`] trait.
222pub trait Inverter {
223    /// Output of an inversion.
224    type Output;
225
226    /// Compute a modular inversion, returning `None` if the result is undefined (i.e. if `value` is
227    /// zero or isn't prime relative to the modulus).
228    fn invert(&self, value: &Self::Output) -> CtOption<Self::Output>;
229
230    /// Compute a modular inversion, returning `None` if the result is undefined (i.e. if `value` is
231    /// zero or isn't prime relative to the modulus).
232    ///
233    /// This version is variable-time with respect to `value`.
234    fn invert_vartime(&self, value: &Self::Output) -> CtOption<Self::Output>;
235}
236
237/// Obtain a precomputed inverter for efficiently computing modular inversions for a given modulus.
238pub trait PrecomputeInverter {
239    /// Inverter type for integers of this size.
240    type Inverter: Inverter<Output = Self::Output> + Sized;
241
242    /// Output produced by the inverter.
243    type Output;
244
245    /// Obtain a precomputed inverter for `&self` as the modulus, using `Self::one()` as an adjusting parameter.
246    ///
247    /// Returns `None` if `self` is even.
248    fn precompute_inverter(&self) -> Self::Inverter;
249}
250
251/// Zero values.
252pub trait Zero: ConstantTimeEq + Sized {
253    /// The value `0`.
254    fn zero() -> Self;
255
256    /// Determine if this value is equal to zero.
257    ///
258    /// # Returns
259    ///
260    /// If zero, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
261    #[inline]
262    fn is_zero(&self) -> Choice {
263        self.ct_eq(&Self::zero())
264    }
265
266    /// Set `self` to its additive identity, i.e. `Self::zero`.
267    #[inline]
268    fn set_zero(&mut self) {
269        *self = Zero::zero();
270    }
271
272    /// Return the value `0` with the same precision as `other`.
273    fn zero_like(other: &Self) -> Self
274    where
275        Self: Clone,
276    {
277        let mut ret = other.clone();
278        ret.set_zero();
279        ret
280    }
281}
282
283impl<T: ConstZero + ConstantTimeEq> Zero for T {
284    #[inline(always)]
285    fn zero() -> T {
286        Self::ZERO
287    }
288}
289
290/// Trait for associating constant values with a type.
291pub trait Constants: ConstZero {
292    /// The value `1`.
293    const ONE: Self;
294
295    /// Maximum value this integer can express.
296    const MAX: Self;
297}
298
299/// Random number generation support.
300#[cfg(feature = "rand_core")]
301pub trait Random: Sized {
302    /// Generate a random value.
303    ///
304    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
305    fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
306        let Ok(out) = Self::try_random(rng);
307        out
308    }
309
310    /// Generate a random value.
311    ///
312    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
313    fn try_random<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
314}
315
316/// Possible errors of the methods in [`RandomBits`] trait.
317#[cfg(feature = "rand_core")]
318#[derive(Debug)]
319pub enum RandomBitsError<T> {
320    /// An error of the internal RNG library.
321    RandCore(T),
322    /// The requested `bits_precision` does not match the size of the integer
323    /// corresponding to the type (in the cases where this is set in compile time).
324    BitsPrecisionMismatch {
325        /// The requested precision.
326        bits_precision: u32,
327        /// The compile-time size of the integer.
328        integer_bits: u32,
329    },
330    /// The requested `bit_length` is larger than `bits_precision`.
331    BitLengthTooLarge {
332        /// The requested bit length of the random number.
333        bit_length: u32,
334        /// The requested precision.
335        bits_precision: u32,
336    },
337}
338
339#[cfg(feature = "rand_core")]
340impl<T> fmt::Display for RandomBitsError<T>
341where
342    T: fmt::Display,
343{
344    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345        match self {
346            Self::RandCore(err) => write!(f, "{}", err),
347            Self::BitsPrecisionMismatch {
348                bits_precision,
349                integer_bits,
350            } => write!(
351                f,
352                concat![
353                    "The requested `bits_precision` ({}) does not match ",
354                    "the size of the integer corresponding to the type ({})"
355                ],
356                bits_precision, integer_bits
357            ),
358            Self::BitLengthTooLarge {
359                bit_length,
360                bits_precision,
361            } => write!(
362                f,
363                "The requested `bit_length` ({}) is larger than `bits_precision` ({}).",
364                bit_length, bits_precision
365            ),
366        }
367    }
368}
369
370#[cfg(feature = "rand_core")]
371impl<T> core::error::Error for RandomBitsError<T> where T: Debug + fmt::Display {}
372
373/// Random bits generation support.
374#[cfg(feature = "rand_core")]
375pub trait RandomBits: Sized {
376    /// Generate a random value in range `[0, 2^bit_length)`.
377    ///
378    /// A wrapper for [`RandomBits::try_random_bits`] that panics on error.
379    fn random_bits<R: TryRngCore + ?Sized>(rng: &mut R, bit_length: u32) -> Self {
380        Self::try_random_bits(rng, bit_length).expect("try_random_bits() failed")
381    }
382
383    /// Generate a random value in range `[0, 2^bit_length)`.
384    ///
385    /// This method is variable time wrt `bit_length`.
386    ///
387    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
388    fn try_random_bits<R: TryRngCore + ?Sized>(
389        rng: &mut R,
390        bit_length: u32,
391    ) -> Result<Self, RandomBitsError<R::Error>>;
392
393    /// Generate a random value in range `[0, 2^bit_length)`,
394    /// returning an integer with the closest available size to `bits_precision`
395    /// (if the implementing type supports runtime sizing).
396    ///
397    /// A wrapper for [`RandomBits::try_random_bits_with_precision`] that panics on error.
398    fn random_bits_with_precision<R: TryRngCore + ?Sized>(
399        rng: &mut R,
400        bit_length: u32,
401        bits_precision: u32,
402    ) -> Self {
403        Self::try_random_bits_with_precision(rng, bit_length, bits_precision)
404            .expect("try_random_bits_with_precision() failed")
405    }
406
407    /// Generate a random value in range `[0, 2^bit_length)`,
408    /// returning an integer with the closest available size to `bits_precision`
409    /// (if the implementing type supports runtime sizing).
410    ///
411    /// This method is variable time wrt `bit_length`.
412    ///
413    /// If `rng` is a CSRNG, the generation is cryptographically secure as well.
414    fn try_random_bits_with_precision<R: TryRngCore + ?Sized>(
415        rng: &mut R,
416        bit_length: u32,
417        bits_precision: u32,
418    ) -> Result<Self, RandomBitsError<R::Error>>;
419}
420
421/// Modular random number generation support.
422#[cfg(feature = "rand_core")]
423pub trait RandomMod: Sized + Zero {
424    /// Generate a random number which is less than a given `modulus`.
425    ///
426    /// This uses rejection sampling.
427    ///
428    /// As a result, it runs in variable time that depends in part on
429    /// `modulus`. If the generator `rng` is cryptographically secure (for
430    /// example, it implements `CryptoRng`), then this is guaranteed not to
431    /// leak anything about the output value aside from it being less than
432    /// `modulus`.
433    fn random_mod<R: RngCore + ?Sized>(rng: &mut R, modulus: &NonZero<Self>) -> Self {
434        let Ok(out) = Self::try_random_mod(rng, modulus);
435        out
436    }
437
438    /// Generate a random number which is less than a given `modulus`.
439    ///
440    /// This uses rejection sampling.
441    ///
442    /// As a result, it runs in variable time that depends in part on
443    /// `modulus`. If the generator `rng` is cryptographically secure (for
444    /// example, it implements `CryptoRng`), then this is guaranteed not to
445    /// leak anything about the output value aside from it being less than
446    /// `modulus`.
447    fn try_random_mod<R: TryRngCore + ?Sized>(
448        rng: &mut R,
449        modulus: &NonZero<Self>,
450    ) -> Result<Self, R::Error>;
451}
452
453/// Compute `self + rhs mod p`.
454pub trait AddMod<Rhs = Self> {
455    /// Output type.
456    type Output;
457
458    /// Compute `self + rhs mod p`.
459    ///
460    /// Assumes `self` and `rhs` are `< p`.
461    fn add_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
462}
463
464/// Compute `self - rhs mod p`.
465pub trait SubMod<Rhs = Self> {
466    /// Output type.
467    type Output;
468
469    /// Compute `self - rhs mod p`.
470    ///
471    /// Assumes `self` and `rhs` are `< p`.
472    fn sub_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
473}
474
475/// Compute `-self mod p`.
476pub trait NegMod {
477    /// Output type.
478    type Output;
479
480    /// Compute `-self mod p`.
481    #[must_use]
482    fn neg_mod(&self, p: &Self) -> Self::Output;
483}
484
485/// Compute `self * rhs mod p`.
486pub trait MulMod<Rhs = Self> {
487    /// Output type.
488    type Output;
489
490    /// Compute `self * rhs mod p`.
491    fn mul_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
492}
493
494/// Compute `1 / self mod p`.
495#[deprecated(since = "0.7.0", note = "please use `InvertMod` instead")]
496pub trait InvMod<Rhs = Self>: Sized {
497    /// Output type.
498    type Output;
499
500    /// Compute `1 / self mod p`.
501    fn inv_mod(&self, p: &Rhs) -> CtOption<Self::Output>;
502}
503
504#[allow(deprecated)]
505impl<T, Rhs> InvMod<Rhs> for T
506where
507    T: InvertMod<Rhs>,
508{
509    type Output = <T as InvertMod<Rhs>>::Output;
510
511    fn inv_mod(&self, p: &Rhs) -> CtOption<Self::Output> {
512        self.invert_mod(p)
513    }
514}
515
516/// Compute `1 / self mod p`.
517pub trait InvertMod<Rhs = Self>: Sized {
518    /// Output type.
519    type Output;
520
521    /// Compute `1 / self mod p`.
522    fn invert_mod(&self, p: &Rhs) -> CtOption<Self::Output>;
523}
524
525/// Checked addition.
526pub trait CheckedAdd<Rhs = Self>: Sized {
527    /// Perform checked addition, returning a [`CtOption`] which `is_some` only if the operation
528    /// did not overflow.
529    fn checked_add(&self, rhs: &Rhs) -> CtOption<Self>;
530}
531
532/// Checked division.
533pub trait CheckedDiv<Rhs = Self>: Sized {
534    /// Perform checked division, returning a [`CtOption`] which `is_some` only if the divisor is
535    /// non-zero.
536    fn checked_div(&self, rhs: &Rhs) -> CtOption<Self>;
537}
538
539/// Checked multiplication.
540pub trait CheckedMul<Rhs = Self>: Sized {
541    /// Perform checked multiplication, returning a [`CtOption`] which `is_some`
542    /// only if the operation did not overflow.
543    fn checked_mul(&self, rhs: &Rhs) -> CtOption<Self>;
544}
545
546/// Checked subtraction.
547pub trait CheckedSub<Rhs = Self>: Sized {
548    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
549    /// only if the operation did not underflow.
550    fn checked_sub(&self, rhs: &Rhs) -> CtOption<Self>;
551}
552
553/// Concatenate two numbers into a "wide" double-width value, using the `hi` value as the most
554/// significant portion of the resulting value.
555pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
556    /// Concatenated output: twice the width of `Self`.
557    type Output: Integer;
558
559    /// Concatenate the two halves, with `self` as least significant and `hi` as the most significant.
560    fn concat(&self, hi: &Self) -> Self::Output {
561        self.concat_mixed(hi)
562    }
563}
564
565/// Concatenate two numbers into a "wide" combined-width value, using the `hi` value as the most
566/// significant value.
567pub trait ConcatMixed<Hi: ?Sized = Self> {
568    /// Concatenated output: combination of `Self` and `Hi`.
569    type MixedOutput: Integer;
570
571    /// Concatenate the two values, with `self` as least significant and `hi` as the most
572    /// significant.
573    fn concat_mixed(&self, hi: &Hi) -> Self::MixedOutput;
574}
575
576/// Split a number in half, returning the least significant half followed by the most significant.
577pub trait Split: SplitMixed<Self::Output, Self::Output> {
578    /// Split output: low/high components of the value.
579    type Output;
580
581    /// Split this number in half, returning its low and high components respectively.
582    fn split(&self) -> (Self::Output, Self::Output) {
583        self.split_mixed()
584    }
585}
586
587/// Split a number into parts, returning the least significant part followed by the most
588/// significant.
589pub trait SplitMixed<Lo, Hi> {
590    /// Split this number into parts, returning its low and high components respectively.
591    fn split_mixed(&self) -> (Lo, Hi);
592}
593
594/// Encoding support.
595pub trait Encoding: Sized {
596    /// Byte array representation.
597    type Repr: AsRef<[u8]>
598        + AsMut<[u8]>
599        + Copy
600        + Clone
601        + Sized
602        + for<'a> TryFrom<&'a [u8], Error = core::array::TryFromSliceError>;
603
604    /// Decode from big endian bytes.
605    fn from_be_bytes(bytes: Self::Repr) -> Self;
606
607    /// Decode from little endian bytes.
608    fn from_le_bytes(bytes: Self::Repr) -> Self;
609
610    /// Encode to big endian bytes.
611    fn to_be_bytes(&self) -> Self::Repr;
612
613    /// Encode to little endian bytes.
614    fn to_le_bytes(&self) -> Self::Repr;
615}
616
617/// Possible errors in variable-time integer decoding methods.
618#[derive(Clone, Copy, Debug, Eq, PartialEq)]
619pub enum DecodeError {
620    /// The input value was empty.
621    Empty,
622
623    /// The input was not consistent with the format restrictions.
624    InvalidDigit,
625
626    /// Input size is too small to fit in the given precision.
627    InputSize,
628
629    /// The deserialized number is larger than the given precision.
630    Precision,
631}
632
633impl fmt::Display for DecodeError {
634    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
635        match self {
636            Self::Empty => write!(f, "empty value provided"),
637            Self::InvalidDigit => {
638                write!(f, "invalid digit character")
639            }
640            Self::InputSize => write!(f, "input size is too small to fit in the given precision"),
641            Self::Precision => write!(
642                f,
643                "the deserialized number is larger than the given precision"
644            ),
645        }
646    }
647}
648
649impl core::error::Error for DecodeError {}
650
651/// Support for optimized squaring
652pub trait Square {
653    /// Computes the same as `self * self`, but may be more efficient.
654    fn square(&self) -> Self;
655}
656
657/// Support for optimized squaring in-place
658pub trait SquareAssign {
659    /// Computes the same as `self * self`, but may be more efficient.
660    /// Writes the result in `self`.
661    fn square_assign(&mut self);
662}
663
664/// Support for calucaling square roots.
665pub trait SquareRoot {
666    /// Computes `floor(sqrt(self))`.
667    fn sqrt(&self) -> Self;
668
669    /// Computes `floor(sqrt(self))`, variable time in `self`.
670    fn sqrt_vartime(&self) -> Self;
671}
672
673/// Support for optimized division by a single limb.
674pub trait DivRemLimb: Sized {
675    /// Computes `self / rhs` using a pre-made reciprocal,
676    /// returns the quotient (q) and remainder (r).
677    fn div_rem_limb(&self, rhs: NonZero<Limb>) -> (Self, Limb) {
678        self.div_rem_limb_with_reciprocal(&Reciprocal::new(rhs))
679    }
680
681    /// Computes `self / rhs`, returns the quotient (q) and remainder (r).
682    fn div_rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> (Self, Limb);
683}
684
685/// Support for calculating the remainder of two differently sized integers.
686pub trait RemMixed<Reductor>: Sized {
687    /// Calculate the remainder of `self` by the `reductor`.
688    fn rem_mixed(&self, reductor: &NonZero<Reductor>) -> Reductor;
689}
690
691/// Division in variable time.
692pub trait DivVartime: Sized {
693    /// Computes `self / rhs` in variable time.
694    fn div_vartime(&self, rhs: &NonZero<Self>) -> Self;
695}
696
697/// Support for optimized division by a single limb.
698pub trait RemLimb: Sized {
699    /// Computes `self % rhs` using a pre-made reciprocal.
700    fn rem_limb(&self, rhs: NonZero<Limb>) -> Limb {
701        self.rem_limb_with_reciprocal(&Reciprocal::new(rhs))
702    }
703
704    /// Computes `self % rhs`.
705    fn rem_limb_with_reciprocal(&self, reciprocal: &Reciprocal) -> Limb;
706}
707
708/// Bit counting and bit operations.
709pub trait BitOps {
710    /// Precision of this integer in bits.
711    fn bits_precision(&self) -> u32;
712
713    /// `floor(log2(self.bits_precision()))`.
714    fn log2_bits(&self) -> u32 {
715        u32::BITS - self.bits_precision().leading_zeros() - 1
716    }
717
718    /// Precision of this integer in bytes.
719    fn bytes_precision(&self) -> usize;
720
721    /// Get the value of the bit at position `index`, as a truthy or falsy `Choice`.
722    /// Returns the falsy value for indices out of range.
723    fn bit(&self, index: u32) -> Choice;
724
725    /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`.
726    fn set_bit(&mut self, index: u32, bit_value: Choice);
727
728    /// Calculate the number of bits required to represent a given number.
729    fn bits(&self) -> u32 {
730        self.bits_precision() - self.leading_zeros()
731    }
732
733    /// Calculate the number of trailing zeros in the binary representation of this number.
734    fn trailing_zeros(&self) -> u32;
735
736    /// Calculate the number of trailing ones in the binary representation of this number.
737    fn trailing_ones(&self) -> u32;
738
739    /// Calculate the number of leading zeros in the binary representation of this number.
740    fn leading_zeros(&self) -> u32;
741
742    /// Returns `true` if the bit at position `index` is set, `false` otherwise.
743    ///
744    /// # Remarks
745    /// This operation is variable time with respect to `index` only.
746    fn bit_vartime(&self, index: u32) -> bool;
747
748    /// Calculate the number of bits required to represent a given number in variable-time with
749    /// respect to `self`.
750    fn bits_vartime(&self) -> u32;
751
752    /// Sets the bit at `index` to 0 or 1 depending on the value of `bit_value`,
753    /// variable time in `self`.
754    fn set_bit_vartime(&mut self, index: u32, bit_value: bool);
755
756    /// Calculate the number of leading zeros in the binary representation of this number.
757    fn leading_zeros_vartime(&self) -> u32 {
758        self.bits_precision() - self.bits_vartime()
759    }
760
761    /// Calculate the number of trailing zeros in the binary representation of this number in
762    /// variable-time with respect to `self`.
763    fn trailing_zeros_vartime(&self) -> u32;
764
765    /// Calculate the number of trailing ones in the binary representation of this number,
766    /// variable time in `self`.
767    fn trailing_ones_vartime(&self) -> u32;
768}
769
770/// Constant-time exponentiation.
771pub trait Pow<Exponent> {
772    /// Raises to the `exponent` power.
773    fn pow(&self, exponent: &Exponent) -> Self;
774}
775
776impl<T: PowBoundedExp<Exponent>, Exponent: Bounded> Pow<Exponent> for T {
777    fn pow(&self, exponent: &Exponent) -> Self {
778        self.pow_bounded_exp(exponent, Exponent::BITS)
779    }
780}
781
782/// Constant-time exponentiation with exponent of a bounded bit size.
783pub trait PowBoundedExp<Exponent> {
784    /// Raises to the `exponent` power,
785    /// with `exponent_bits` representing the number of (least significant) bits
786    /// to take into account for the exponent.
787    ///
788    /// NOTE: `exponent_bits` may be leaked in the time pattern.
789    fn pow_bounded_exp(&self, exponent: &Exponent, exponent_bits: u32) -> Self;
790}
791
792/// Performs modular multi-exponentiation using Montgomery's ladder.
793///
794/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
795pub trait MultiExponentiate<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
796where
797    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
798{
799    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
800    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self;
801}
802
803impl<T, Exponent, BasesAndExponents> MultiExponentiate<Exponent, BasesAndExponents> for T
804where
805    T: MultiExponentiateBoundedExp<Exponent, BasesAndExponents>,
806    Exponent: Bounded,
807    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
808{
809    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self {
810        Self::multi_exponentiate_bounded_exp(bases_and_exponents, Exponent::BITS)
811    }
812}
813
814/// Performs modular multi-exponentiation using Montgomery's ladder.
815/// `exponent_bits` represents the number of bits to take into account for the exponent.
816///
817/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
818///
819/// NOTE: this value is leaked in the time pattern.
820pub trait MultiExponentiateBoundedExp<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
821where
822    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
823{
824    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
825    fn multi_exponentiate_bounded_exp(
826        bases_and_exponents: &BasesAndExponents,
827        exponent_bits: u32,
828    ) -> Self;
829}
830
831/// Constant-time inversion.
832pub trait Invert {
833    /// Output of the inversion.
834    type Output;
835
836    /// Computes the inverse.
837    fn invert(&self) -> Self::Output;
838
839    /// Computes the inverse in variable-time.
840    fn invert_vartime(&self) -> Self::Output {
841        self.invert()
842    }
843}
844
845/// Widening multiply: returns a value with a number of limbs equal to the sum of the inputs.
846#[deprecated(since = "0.7.0", note = "please use `ConcatenatingMul` instead")]
847pub trait WideningMul<Rhs = Self>: Sized {
848    /// Output of the widening multiplication.
849    type Output: Integer;
850
851    /// Perform widening multiplication.
852    fn widening_mul(&self, rhs: Rhs) -> Self::Output;
853}
854
855#[allow(deprecated)]
856impl<T, Rhs> WideningMul<Rhs> for T
857where
858    T: ConcatenatingMul<Rhs>,
859{
860    type Output = <T as ConcatenatingMul<Rhs>>::Output;
861
862    fn widening_mul(&self, rhs: Rhs) -> Self::Output {
863        self.concatenating_mul(rhs)
864    }
865}
866
867/// Widening multiply: returns a value with a number of limbs equal to the sum of the inputs.
868pub trait ConcatenatingMul<Rhs = Self>: Sized {
869    /// Output of the widening multiplication.
870    type Output: Integer;
871
872    /// Perform widening multiplication.
873    fn concatenating_mul(&self, rhs: Rhs) -> Self::Output;
874}
875
876/// Left shifts, variable time in `shift`.
877pub trait ShlVartime: Sized {
878    /// Computes `self << shift`.
879    ///
880    /// Returns `None` if `shift >= self.bits_precision()`.
881    fn overflowing_shl_vartime(&self, shift: u32) -> CtOption<Self>;
882
883    /// Computes `self << shift` in a panic-free manner, masking off bits of `shift`
884    /// which would cause the shift to exceed the type's width.
885    fn wrapping_shl_vartime(&self, shift: u32) -> Self;
886}
887
888/// Right shifts, variable time in `shift`.
889pub trait ShrVartime: Sized {
890    /// Computes `self >> shift`.
891    ///
892    /// Returns `None` if `shift >= self.bits_precision()`.
893    fn overflowing_shr_vartime(&self, shift: u32) -> CtOption<Self>;
894
895    /// Computes `self >> shift` in a panic-free manner, masking off bits of `shift`
896    /// which would cause the shift to exceed the type's width.
897    fn wrapping_shr_vartime(&self, shift: u32) -> Self;
898}
899
900/// Methods for resizing the allocated storage.
901pub trait Resize: Sized {
902    /// The result of the resizing.
903    type Output;
904
905    /// Resizes to the minimum storage that fits `at_least_bits_precision`
906    /// without checking if the bit size of `self` is larger than `at_least_bits_precision`.
907    ///
908    /// Variable-time w.r.t. `at_least_bits_precision`.
909    fn resize_unchecked(self, at_least_bits_precision: u32) -> Self::Output;
910
911    /// Resizes to the minimum storage that fits `at_least_bits_precision`
912    /// returning `None` if the bit size of `self` is larger than `at_least_bits_precision`.
913    ///
914    /// Variable-time w.r.t. `at_least_bits_precision`.
915    fn try_resize(self, at_least_bits_precision: u32) -> Option<Self::Output>;
916
917    /// Resizes to the minimum storage that fits `at_least_bits_precision`
918    /// panicking if the bit size of `self` is larger than `at_least_bits_precision`.
919    ///
920    /// Variable-time w.r.t. `at_least_bits_precision`.
921    fn resize(self, at_least_bits_precision: u32) -> Self::Output {
922        self.try_resize(at_least_bits_precision).unwrap_or_else(|| {
923            panic!("The bit size of `self` is larger than `at_least_bits_precision`")
924        })
925    }
926}
927
928/// A representation of an integer optimized for the performance of modular operations.
929pub trait Monty:
930    'static
931    + Clone
932    + Debug
933    + Eq
934    + Sized
935    + Send
936    + Sync
937    + Add<Output = Self>
938    + for<'a> Add<&'a Self, Output = Self>
939    + AddAssign
940    + for<'a> AddAssign<&'a Self>
941    + Sub<Output = Self>
942    + for<'a> Sub<&'a Self, Output = Self>
943    + SubAssign
944    + for<'a> SubAssign<&'a Self>
945    + Mul<Output = Self>
946    + for<'a> Mul<&'a Self, Output = Self>
947    + MulAssign
948    + for<'a> MulAssign<&'a Self>
949    + Neg<Output = Self>
950    + PowBoundedExp<Self::Integer>
951    + Retrieve<Output = Self::Integer>
952    + Square
953    + SquareAssign
954{
955    /// The original integer type.
956    type Integer: Integer<Monty = Self>;
957
958    /// Prepared Montgomery multiplier for tight loops.
959    type Multiplier<'a>: Debug + Clone + MontyMultiplier<'a, Monty = Self>;
960
961    /// The precomputed data needed for this representation.
962    type Params: 'static + Clone + Debug + Eq + Sized + Send + Sync;
963
964    /// Create the precomputed data for Montgomery representation of integers modulo `modulus`,
965    /// variable time in `modulus`.
966    fn new_params_vartime(modulus: Odd<Self::Integer>) -> Self::Params;
967
968    /// Convert the value into the representation using precomputed data.
969    fn new(value: Self::Integer, params: Self::Params) -> Self;
970
971    /// Returns zero in this representation.
972    fn zero(params: Self::Params) -> Self;
973
974    /// Returns one in this representation.
975    fn one(params: Self::Params) -> Self;
976
977    /// Returns the parameter struct used to initialize this object.
978    fn params(&self) -> &Self::Params;
979
980    /// Access the value in Montgomery form.
981    fn as_montgomery(&self) -> &Self::Integer;
982
983    /// Copy the Montgomery representation from `other` into `self`.
984    /// NOTE: the parameters remain unchanged.
985    fn copy_montgomery_from(&mut self, other: &Self);
986
987    /// Performs doubling, returning `self + self`.
988    fn double(&self) -> Self;
989
990    /// Performs division by 2, that is returns `x` such that `x + x = self`.
991    fn div_by_2(&self) -> Self;
992
993    /// Performs division by 2 inplace, that is finds `x` such that `x + x = self`
994    /// and writes it into `self`.
995    fn div_by_2_assign(&mut self) {
996        *self = self.div_by_2()
997    }
998
999    /// Calculate the sum of products of pairs `(a, b)` in `products`.
1000    ///
1001    /// This method is variable time only with the value of the modulus.
1002    /// For a modulus with leading zeros, this method is more efficient than a naive sum of products.
1003    ///
1004    /// This method will panic if `products` is empty. All terms must be associated with equivalent
1005    /// Montgomery parameters.
1006    fn lincomb_vartime(products: &[(&Self, &Self)]) -> Self;
1007}
1008
1009/// Prepared Montgomery multiplier for tight loops.
1010///
1011/// Allows one to perform inplace multiplication without allocations
1012/// (important for the `BoxedUint` case).
1013///
1014/// NOTE: You will be operating with Montgomery representations directly,
1015/// make sure they all correspond to the same set of parameters.
1016pub trait MontyMultiplier<'a>: From<&'a <Self::Monty as Monty>::Params> {
1017    /// The associated Montgomery-representation integer.
1018    type Monty: Monty;
1019
1020    /// Performs a Montgomery multiplication, assigning a fully reduced result to `lhs`.
1021    fn mul_assign(&mut self, lhs: &mut Self::Monty, rhs: &Self::Monty);
1022
1023    /// Performs a Montgomery squaring, assigning a fully reduced result to `lhs`.
1024    fn square_assign(&mut self, lhs: &mut Self::Monty);
1025}