crypto_bigint/
traits.rs

1//! Traits provided by this crate
2
3use crate::{Limb, NonZero};
4use core::fmt::Debug;
5use core::ops::{BitAnd, BitOr, BitXor, Div, Not, Rem, Shl, Shr};
6use subtle::{
7    Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
8    CtOption,
9};
10
11#[cfg(feature = "rand_core")]
12use rand_core::{CryptoRng, RngCore};
13
14/// Integer type.
15pub trait Integer:
16    'static
17    + AsRef<[Limb]>
18    + BitAnd<Output = Self>
19    + BitOr<Output = Self>
20    + BitXor<Output = Self>
21    + for<'a> CheckedAdd<&'a Self, Output = Self>
22    + for<'a> CheckedSub<&'a Self, Output = Self>
23    + for<'a> CheckedMul<&'a Self, Output = Self>
24    + Copy
25    + ConditionallySelectable
26    + ConstantTimeEq
27    + ConstantTimeGreater
28    + ConstantTimeLess
29    + Debug
30    + Default
31    + Div<NonZero<Self>, Output = Self>
32    + Eq
33    + From<u64>
34    + Not
35    + Ord
36    + Rem<NonZero<Self>, Output = Self>
37    + Send
38    + Sized
39    + Shl<usize, Output = Self>
40    + Shr<usize, Output = Self>
41    + Sync
42    + Zero
43{
44    /// The value `1`.
45    const ONE: Self;
46
47    /// Maximum value this integer can express.
48    const MAX: Self;
49
50    /// Is this integer value an odd number?
51    ///
52    /// # Returns
53    ///
54    /// If odd, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
55    fn is_odd(&self) -> Choice;
56
57    /// Is this integer value an even number?
58    ///
59    /// # Returns
60    ///
61    /// If even, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
62    fn is_even(&self) -> Choice {
63        !self.is_odd()
64    }
65}
66
67/// Zero values.
68pub trait Zero: ConstantTimeEq + Sized {
69    /// The value `0`.
70    const ZERO: Self;
71
72    /// Determine if this value is equal to zero.
73    ///
74    /// # Returns
75    ///
76    /// If zero, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
77    fn is_zero(&self) -> Choice {
78        self.ct_eq(&Self::ZERO)
79    }
80}
81
82/// Random number generation support.
83#[cfg(feature = "rand_core")]
84#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
85pub trait Random: Sized {
86    /// Generate a cryptographically secure random value.
87    fn random(rng: impl CryptoRng + RngCore) -> Self;
88}
89
90/// Modular random number generation support.
91#[cfg(feature = "rand_core")]
92#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
93pub trait RandomMod: Sized + Zero {
94    /// Generate a cryptographically secure random number which is less than
95    /// a given `modulus`.
96    ///
97    /// This function uses rejection sampling, a method which produces an
98    /// unbiased distribution of in-range values provided the underlying
99    /// [`CryptoRng`] is unbiased, but runs in variable-time.
100    ///
101    /// The variable-time nature of the algorithm should not pose a security
102    /// issue so long as the underlying random number generator is truly a
103    /// [`CryptoRng`], where previous outputs are unrelated to subsequent
104    /// outputs and do not reveal information about the RNG's internal state.
105    fn random_mod(rng: impl CryptoRng + RngCore, modulus: &NonZero<Self>) -> Self;
106}
107
108/// Compute `self + rhs mod p`.
109pub trait AddMod<Rhs = Self> {
110    /// Output type.
111    type Output;
112
113    /// Compute `self + rhs mod p`.
114    ///
115    /// Assumes `self` and `rhs` are `< p`.
116    fn add_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
117}
118
119/// Compute `self - rhs mod p`.
120pub trait SubMod<Rhs = Self> {
121    /// Output type.
122    type Output;
123
124    /// Compute `self - rhs mod p`.
125    ///
126    /// Assumes `self` and `rhs` are `< p`.
127    fn sub_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
128}
129
130/// Compute `-self mod p`.
131pub trait NegMod {
132    /// Output type.
133    type Output;
134
135    /// Compute `-self mod p`.
136    #[must_use]
137    fn neg_mod(&self, p: &Self) -> Self::Output;
138}
139
140/// Compute `self * rhs mod p`.
141///
142/// Requires `p_inv = -(p^{-1} mod 2^{BITS}) mod 2^{BITS}` to be provided for efficiency.
143pub trait MulMod<Rhs = Self> {
144    /// Output type.
145    type Output;
146
147    /// Compute `self * rhs mod p`.
148    ///
149    /// Requires `p_inv = -(p^{-1} mod 2^{BITS}) mod 2^{BITS}` to be provided for efficiency.
150    fn mul_mod(&self, rhs: &Rhs, p: &Self, p_inv: Limb) -> Self::Output;
151}
152
153/// Checked addition.
154pub trait CheckedAdd<Rhs = Self>: Sized {
155    /// Output type.
156    type Output;
157
158    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
159    /// only if the operation did not overflow.
160    fn checked_add(&self, rhs: Rhs) -> CtOption<Self>;
161}
162
163/// Checked multiplication.
164pub trait CheckedMul<Rhs = Self>: Sized {
165    /// Output type.
166    type Output;
167
168    /// Perform checked multiplication, returning a [`CtOption`] which `is_some`
169    /// only if the operation did not overflow.
170    fn checked_mul(&self, rhs: Rhs) -> CtOption<Self>;
171}
172
173/// Checked substraction.
174pub trait CheckedSub<Rhs = Self>: Sized {
175    /// Output type.
176    type Output;
177
178    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
179    /// only if the operation did not underflow.
180    fn checked_sub(&self, rhs: Rhs) -> CtOption<Self>;
181}
182
183/// Concatenate two numbers into a "wide" twice-width value, using the `rhs`
184/// value as the least significant value.
185pub trait Concat<Rhs = Self> {
186    /// Concatenated output: twice the width of `Self`.
187    type Output;
188
189    /// Concatenate the two values, with `self` as most significant and `rhs`
190    /// as the least significant.
191    fn concat(&self, rhs: &Self) -> Self::Output;
192}
193
194/// Split a number in half, returning the most significant half followed by
195/// the least significant.
196pub trait Split<Rhs = Self> {
197    /// Split output: high/low components of the value.
198    type Output;
199
200    /// Split this number in half, returning its high and low components
201    /// respectively.
202    fn split(&self) -> (Self::Output, Self::Output);
203}
204
205/// Encoding support.
206pub trait Encoding: Sized {
207    /// Size of this integer in bits.
208    const BIT_SIZE: usize;
209
210    /// Size of this integer in bytes.
211    const BYTE_SIZE: usize;
212
213    /// Byte array representation.
214    type Repr: AsRef<[u8]> + AsMut<[u8]> + Copy + Clone + Sized;
215
216    /// Decode from big endian bytes.
217    fn from_be_bytes(bytes: Self::Repr) -> Self;
218
219    /// Decode from little endian bytes.
220    fn from_le_bytes(bytes: Self::Repr) -> Self;
221
222    /// Encode to big endian bytes.
223    fn to_be_bytes(&self) -> Self::Repr;
224
225    /// Encode to little endian bytes.
226    fn to_le_bytes(&self) -> Self::Repr;
227}