Coverage Report

Created: 2025-12-31 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-bigint-0.5.5/src/traits.rs
Line
Count
Source
1
//! Traits provided by this crate
2
3
use crate::{Limb, NonZero};
4
use core::fmt::Debug;
5
use core::ops::{BitAnd, BitOr, BitXor, Div, Not, Rem, Shl, Shr};
6
use subtle::{
7
    Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
8
    CtOption,
9
};
10
11
#[cfg(feature = "rand_core")]
12
use rand_core::CryptoRngCore;
13
14
/// Integer type.
15
pub 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
    /// Total size of the represented integer in bits.
51
    const BITS: usize;
52
53
    /// Total size of the represented integer in bytes.
54
    const BYTES: usize;
55
56
    /// The number of limbs used on this platform.
57
    const LIMBS: usize;
58
59
    /// Is this integer value an odd number?
60
    ///
61
    /// # Returns
62
    ///
63
    /// If odd, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
64
    fn is_odd(&self) -> Choice;
65
66
    /// Is this integer value an even number?
67
    ///
68
    /// # Returns
69
    ///
70
    /// If even, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
71
0
    fn is_even(&self) -> Choice {
72
0
        !self.is_odd()
73
0
    }
74
}
75
76
/// Zero values.
77
pub trait Zero: ConstantTimeEq + Sized {
78
    /// The value `0`.
79
    const ZERO: Self;
80
81
    /// Determine if this value is equal to zero.
82
    ///
83
    /// # Returns
84
    ///
85
    /// If zero, returns `Choice(1)`. Otherwise, returns `Choice(0)`.
86
6.18k
    fn is_zero(&self) -> Choice {
87
6.18k
        self.ct_eq(&Self::ZERO)
88
6.18k
    }
<crypto_bigint::uint::Uint<4> as crypto_bigint::traits::Zero>::is_zero
Line
Count
Source
86
6.18k
    fn is_zero(&self) -> Choice {
87
6.18k
        self.ct_eq(&Self::ZERO)
88
6.18k
    }
Unexecuted instantiation: <crypto_bigint::limb::Limb as crypto_bigint::traits::Zero>::is_zero
89
}
90
91
/// Random number generation support.
92
#[cfg(feature = "rand_core")]
93
pub trait Random: Sized {
94
    /// Generate a cryptographically secure random value.
95
    fn random(rng: &mut impl CryptoRngCore) -> Self;
96
}
97
98
/// Modular random number generation support.
99
#[cfg(feature = "rand_core")]
100
pub trait RandomMod: Sized + Zero {
101
    /// Generate a cryptographically secure random number which is less than
102
    /// a given `modulus`.
103
    ///
104
    /// This function uses rejection sampling, a method which produces an
105
    /// unbiased distribution of in-range values provided the underlying
106
    /// CSRNG is unbiased, but runs in variable-time.
107
    ///
108
    /// The variable-time nature of the algorithm should not pose a security
109
    /// issue so long as the underlying random number generator is truly a
110
    /// CSRNG, where previous outputs are unrelated to subsequent
111
    /// outputs and do not reveal information about the RNG's internal state.
112
    fn random_mod(rng: &mut impl CryptoRngCore, modulus: &NonZero<Self>) -> Self;
113
}
114
115
/// Compute `self + rhs mod p`.
116
pub trait AddMod<Rhs = Self> {
117
    /// Output type.
118
    type Output;
119
120
    /// Compute `self + rhs mod p`.
121
    ///
122
    /// Assumes `self` and `rhs` are `< p`.
123
    fn add_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
124
}
125
126
/// Compute `self - rhs mod p`.
127
pub trait SubMod<Rhs = Self> {
128
    /// Output type.
129
    type Output;
130
131
    /// Compute `self - rhs mod p`.
132
    ///
133
    /// Assumes `self` and `rhs` are `< p`.
134
    fn sub_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
135
}
136
137
/// Compute `-self mod p`.
138
pub trait NegMod {
139
    /// Output type.
140
    type Output;
141
142
    /// Compute `-self mod p`.
143
    #[must_use]
144
    fn neg_mod(&self, p: &Self) -> Self::Output;
145
}
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
pub trait MulMod<Rhs = Self> {
151
    /// Output type.
152
    type Output;
153
154
    /// Compute `self * rhs mod p`.
155
    ///
156
    /// Requires `p_inv = -(p^{-1} mod 2^{BITS}) mod 2^{BITS}` to be provided for efficiency.
157
    fn mul_mod(&self, rhs: &Rhs, p: &Self, p_inv: Limb) -> Self::Output;
158
}
159
160
/// Checked addition.
161
pub trait CheckedAdd<Rhs = Self>: Sized {
162
    /// Output type.
163
    type Output;
164
165
    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
166
    /// only if the operation did not overflow.
167
    fn checked_add(&self, rhs: Rhs) -> CtOption<Self>;
168
}
169
170
/// Checked multiplication.
171
pub trait CheckedMul<Rhs = Self>: Sized {
172
    /// Output type.
173
    type Output;
174
175
    /// Perform checked multiplication, returning a [`CtOption`] which `is_some`
176
    /// only if the operation did not overflow.
177
    fn checked_mul(&self, rhs: Rhs) -> CtOption<Self>;
178
}
179
180
/// Checked subtraction.
181
pub trait CheckedSub<Rhs = Self>: Sized {
182
    /// Output type.
183
    type Output;
184
185
    /// Perform checked subtraction, returning a [`CtOption`] which `is_some`
186
    /// only if the operation did not underflow.
187
    fn checked_sub(&self, rhs: Rhs) -> CtOption<Self>;
188
}
189
190
/// Concatenate two numbers into a "wide" double-width value, using the `lo`
191
/// value as the least significant value.
192
pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
193
    /// Concatenated output: twice the width of `Self`.
194
    type Output;
195
196
    /// Concatenate the two halves, with `self` as most significant and `lo`
197
    /// as the least significant.
198
0
    fn concat(&self, lo: &Self) -> Self::Output {
199
0
        self.concat_mixed(lo)
200
0
    }
201
}
202
203
/// Concatenate two numbers into a "wide" combined-width value, using the `lo`
204
/// value as the least significant value.
205
pub trait ConcatMixed<Lo: ?Sized = Self> {
206
    /// Concatenated output: combination of `Lo` and `Self`.
207
    type MixedOutput;
208
209
    /// Concatenate the two values, with `self` as most significant and `lo`
210
    /// as the least significant.
211
    fn concat_mixed(&self, lo: &Lo) -> Self::MixedOutput;
212
}
213
214
/// Split a number in half, returning the most significant half followed by
215
/// the least significant.
216
pub trait Split: SplitMixed<Self::Output, Self::Output> {
217
    /// Split output: high/low components of the value.
218
    type Output;
219
220
    /// Split this number in half, returning its high and low components
221
    /// respectively.
222
0
    fn split(&self) -> (Self::Output, Self::Output) {
223
0
        self.split_mixed()
224
0
    }
225
}
226
227
/// Split a number into parts, returning the most significant part followed by
228
/// the least significant.
229
pub trait SplitMixed<Hi, Lo> {
230
    /// Split this number into parts, returning its high and low components
231
    /// respectively.
232
    fn split_mixed(&self) -> (Hi, Lo);
233
}
234
235
/// Integers whose representation takes a bounded amount of space.
236
pub trait Bounded {
237
    /// Size of this integer in bits.
238
    const BITS: usize;
239
240
    /// Size of this integer in bytes.
241
    const BYTES: usize;
242
}
243
244
/// Encoding support.
245
pub trait Encoding: Sized {
246
    /// Byte array representation.
247
    type Repr: AsRef<[u8]> + AsMut<[u8]> + Copy + Clone + Sized;
248
249
    /// Decode from big endian bytes.
250
    fn from_be_bytes(bytes: Self::Repr) -> Self;
251
252
    /// Decode from little endian bytes.
253
    fn from_le_bytes(bytes: Self::Repr) -> Self;
254
255
    /// Encode to big endian bytes.
256
    fn to_be_bytes(&self) -> Self::Repr;
257
258
    /// Encode to little endian bytes.
259
    fn to_le_bytes(&self) -> Self::Repr;
260
}
261
262
/// Support for optimized squaring
263
pub trait Square: Sized
264
where
265
    for<'a> &'a Self: core::ops::Mul<&'a Self, Output = Self>,
266
{
267
    /// Computes the same as `self.mul(self)`, but may be more efficient.
268
0
    fn square(&self) -> Self {
269
0
        self * self
270
0
    }
271
}
272
273
/// Constant-time exponentiation.
274
pub trait Pow<Exponent> {
275
    /// Raises to the `exponent` power.
276
    fn pow(&self, exponent: &Exponent) -> Self;
277
}
278
279
impl<T: PowBoundedExp<Exponent>, Exponent: Bounded> Pow<Exponent> for T {
280
0
    fn pow(&self, exponent: &Exponent) -> Self {
281
0
        self.pow_bounded_exp(exponent, Exponent::BITS)
282
0
    }
283
}
284
285
/// Constant-time exponentiation with exponent of a bounded bit size.
286
pub trait PowBoundedExp<Exponent> {
287
    /// Raises to the `exponent` power,
288
    /// with `exponent_bits` representing the number of (least significant) bits
289
    /// to take into account for the exponent.
290
    ///
291
    /// NOTE: `exponent_bits` may be leaked in the time pattern.
292
    fn pow_bounded_exp(&self, exponent: &Exponent, exponent_bits: usize) -> Self;
293
}
294
295
/// Performs modular multi-exponentiation using Montgomery's ladder.
296
///
297
/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
298
pub trait MultiExponentiate<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
299
where
300
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
301
{
302
    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
303
    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self;
304
}
305
306
impl<T, Exponent, BasesAndExponents> MultiExponentiate<Exponent, BasesAndExponents> for T
307
where
308
    T: MultiExponentiateBoundedExp<Exponent, BasesAndExponents>,
309
    Exponent: Bounded,
310
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
311
{
312
0
    fn multi_exponentiate(bases_and_exponents: &BasesAndExponents) -> Self {
313
0
        Self::multi_exponentiate_bounded_exp(bases_and_exponents, Exponent::BITS)
314
0
    }
315
}
316
317
/// Performs modular multi-exponentiation using Montgomery's ladder.
318
/// `exponent_bits` represents the number of bits to take into account for the exponent.
319
///
320
/// See: Straus, E. G. Problems and solutions: Addition chains of vectors. American Mathematical Monthly 71 (1964), 806–808.
321
///
322
/// NOTE: this value is leaked in the time pattern.
323
pub trait MultiExponentiateBoundedExp<Exponent, BasesAndExponents>: Pow<Exponent> + Sized
324
where
325
    BasesAndExponents: AsRef<[(Self, Exponent)]> + ?Sized,
326
{
327
    /// Calculates `x1 ^ k1 * ... * xn ^ kn`.
328
    fn multi_exponentiate_bounded_exp(
329
        bases_and_exponents: &BasesAndExponents,
330
        exponent_bits: usize,
331
    ) -> Self;
332
}
333
334
/// Constant-time inversion.
335
pub trait Invert: Sized {
336
    /// Output of the inversion.
337
    type Output;
338
339
    /// Computes the inverse.
340
    fn invert(&self) -> Self::Output;
341
}