crypto_bigint/
traits.rs

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