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