crypto_bigint/
traits.rs

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