crypto_bigint/
traits.rs

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