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