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