/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 | | } |