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