Coverage Report

Created: 2025-06-24 06:17

/rust/registry/src/index.crates.io-6f17d22bba15001f/openssl-0.10.62/src/bn.rs
Line
Count
Source (jump to first uncovered line)
1
//! BigNum implementation
2
//!
3
//! Large numbers are important for a cryptographic library.  OpenSSL implementation
4
//! of BigNum uses dynamically assigned memory to store an array of bit chunks.  This
5
//! allows numbers of any size to be compared and mathematical functions performed.
6
//!
7
//! OpenSSL wiki describes the [`BIGNUM`] data structure.
8
//!
9
//! # Examples
10
//!
11
//! ```
12
//! use openssl::bn::BigNum;
13
//! use openssl::error::ErrorStack;
14
//!
15
//! fn main() -> Result<(), ErrorStack> {
16
//!   let a = BigNum::new()?; // a = 0
17
//!   let b = BigNum::from_dec_str("1234567890123456789012345")?;
18
//!   let c = &a * &b;
19
//!   assert_eq!(a, c);
20
//!   Ok(())
21
//! }
22
//! ```
23
//!
24
//! [`BIGNUM`]: https://wiki.openssl.org/index.php/Manual:Bn_internal(3)
25
use cfg_if::cfg_if;
26
use foreign_types::{ForeignType, ForeignTypeRef};
27
use libc::c_int;
28
use std::cmp::Ordering;
29
use std::ffi::CString;
30
use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
31
use std::{fmt, ptr};
32
33
use crate::asn1::Asn1Integer;
34
use crate::error::ErrorStack;
35
use crate::string::OpensslString;
36
use crate::{cvt, cvt_n, cvt_p, LenType};
37
use openssl_macros::corresponds;
38
39
cfg_if! {
40
    if #[cfg(any(ossl110, libressl350))] {
41
        use ffi::{
42
            BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
43
            BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
44
            BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
45
        };
46
    } else if #[cfg(boringssl)] {
47
        use ffi::BN_is_negative;
48
    } else {
49
        use ffi::{
50
            get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
51
            get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
52
            get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
53
            get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
54
            get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
55
            get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
56
            get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
57
            get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
58
        };
59
60
        #[allow(bad_style)]
61
        unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
62
            (*bn).neg
63
        }
64
    }
65
}
66
67
/// Options for the most significant bits of a randomly generated `BigNum`.
68
pub struct MsbOption(c_int);
69
70
impl MsbOption {
71
    /// The most significant bit of the number may be 0.
72
    pub const MAYBE_ZERO: MsbOption = MsbOption(-1);
73
74
    /// The most significant bit of the number must be 1.
75
    pub const ONE: MsbOption = MsbOption(0);
76
77
    /// The most significant two bits of the number must be 1.
78
    ///
79
    /// The number of bits in the product of two such numbers will always be exactly twice the
80
    /// number of bits in the original numbers.
81
    pub const TWO_ONES: MsbOption = MsbOption(1);
82
}
83
84
foreign_type_and_impl_send_sync! {
85
    type CType = ffi::BN_CTX;
86
    fn drop = ffi::BN_CTX_free;
87
88
    /// Temporary storage for BigNums on the secure heap
89
    ///
90
    /// BigNum values are stored dynamically and therefore can be expensive
91
    /// to allocate.  BigNumContext and the OpenSSL [`BN_CTX`] structure are used
92
    /// internally when passing BigNum values between subroutines.
93
    ///
94
    /// [`BN_CTX`]: https://www.openssl.org/docs/manmaster/crypto/BN_CTX_new.html
95
    pub struct BigNumContext;
96
    /// Reference to [`BigNumContext`]
97
    ///
98
    /// [`BigNumContext`]: struct.BigNumContext.html
99
    pub struct BigNumContextRef;
100
}
101
102
impl BigNumContext {
103
    /// Returns a new `BigNumContext`.
104
    #[corresponds(BN_CTX_new)]
105
0
    pub fn new() -> Result<BigNumContext, ErrorStack> {
106
0
        unsafe {
107
0
            ffi::init();
108
0
            cvt_p(ffi::BN_CTX_new()).map(BigNumContext)
109
0
        }
110
0
    }
111
112
    /// Returns a new secure `BigNumContext`.
113
    #[corresponds(BN_CTX_secure_new)]
114
    #[cfg(ossl110)]
115
0
    pub fn new_secure() -> Result<BigNumContext, ErrorStack> {
116
0
        unsafe {
117
0
            ffi::init();
118
0
            cvt_p(ffi::BN_CTX_secure_new()).map(BigNumContext)
119
0
        }
120
0
    }
121
}
122
123
foreign_type_and_impl_send_sync! {
124
    type CType = ffi::BIGNUM;
125
    fn drop = ffi::BN_free;
126
127
    /// Dynamically sized large number implementation
128
    ///
129
    /// Perform large number mathematics.  Create a new BigNum
130
    /// with [`new`].  Perform standard mathematics on large numbers using
131
    /// methods from [`Dref<Target = BigNumRef>`]
132
    ///
133
    /// OpenSSL documentation at [`BN_new`].
134
    ///
135
    /// [`new`]: struct.BigNum.html#method.new
136
    /// [`Dref<Target = BigNumRef>`]: struct.BigNum.html#deref-methods
137
    /// [`BN_new`]: https://www.openssl.org/docs/manmaster/crypto/BN_new.html
138
    ///
139
    /// # Examples
140
    /// ```
141
    /// use openssl::bn::BigNum;
142
    /// # use openssl::error::ErrorStack;
143
    /// # fn bignums() -> Result< (), ErrorStack > {
144
    /// let little_big = BigNum::from_u32(std::u32::MAX)?;
145
    /// assert_eq!(*&little_big.num_bytes(), 4);
146
    /// # Ok(())
147
    /// # }
148
    /// # fn main () { bignums(); }
149
    /// ```
150
    pub struct BigNum;
151
    /// Reference to a [`BigNum`]
152
    ///
153
    /// [`BigNum`]: struct.BigNum.html
154
    pub struct BigNumRef;
155
}
156
157
impl BigNumRef {
158
    /// Erases the memory used by this `BigNum`, resetting its value to 0.
159
    ///
160
    /// This can be used to destroy sensitive data such as keys when they are no longer needed.
161
    #[corresponds(BN_clear)]
162
0
    pub fn clear(&mut self) {
163
0
        unsafe { ffi::BN_clear(self.as_ptr()) }
164
0
    }
165
166
    /// Adds a `u32` to `self`.
167
    #[corresponds(BN_add_word)]
168
0
    pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
169
0
        unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
170
0
    }
171
172
    /// Subtracts a `u32` from `self`.
173
    #[corresponds(BN_sub_word)]
174
0
    pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
175
0
        unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
176
0
    }
177
178
    /// Multiplies a `u32` by `self`.
179
    #[corresponds(BN_mul_word)]
180
0
    pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
181
0
        unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
182
0
    }
183
184
    /// Divides `self` by a `u32`, returning the remainder.
185
    #[corresponds(BN_div_word)]
186
    #[allow(clippy::useless_conversion)]
187
0
    pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
188
0
        unsafe {
189
0
            let r = ffi::BN_div_word(self.as_ptr(), w.into());
190
0
            if r == ffi::BN_ULONG::max_value() {
191
0
                Err(ErrorStack::get())
192
            } else {
193
0
                Ok(r.into())
194
            }
195
        }
196
0
    }
197
198
    /// Returns the result of `self` modulo `w`.
199
    #[corresponds(BN_mod_word)]
200
    #[allow(clippy::useless_conversion)]
201
0
    pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
202
0
        unsafe {
203
0
            let r = ffi::BN_mod_word(self.as_ptr(), w.into());
204
0
            if r == ffi::BN_ULONG::max_value() {
205
0
                Err(ErrorStack::get())
206
            } else {
207
0
                Ok(r.into())
208
            }
209
        }
210
0
    }
211
212
    /// Places a cryptographically-secure pseudo-random nonnegative
213
    /// number less than `self` in `rnd`.
214
    #[corresponds(BN_rand_range)]
215
0
    pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
216
0
        unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
217
0
    }
218
219
    /// The cryptographically weak counterpart to `rand_in_range`.
220
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
221
    #[corresponds(BN_pseudo_rand_range)]
222
0
    pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
223
0
        unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
224
0
    }
225
226
    /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
227
    ///
228
    /// When setting a bit outside of `self`, it is expanded.
229
    #[corresponds(BN_set_bit)]
230
    #[allow(clippy::useless_conversion)]
231
0
    pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
232
0
        unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
233
0
    }
234
235
    /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
236
    ///
237
    /// When clearing a bit outside of `self`, an error is returned.
238
    #[corresponds(BN_clear_bit)]
239
    #[allow(clippy::useless_conversion)]
240
0
    pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
241
0
        unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
242
0
    }
243
244
    /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise.
245
    #[corresponds(BN_is_bit_set)]
246
    #[allow(clippy::useless_conversion)]
247
0
    pub fn is_bit_set(&self, n: i32) -> bool {
248
0
        unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
249
0
    }
250
251
    /// Truncates `self` to the lowest `n` bits.
252
    ///
253
    /// An error occurs if `self` is already shorter than `n` bits.
254
    #[corresponds(BN_mask_bits)]
255
    #[allow(clippy::useless_conversion)]
256
0
    pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
257
0
        unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
258
0
    }
259
260
    /// Places `a << 1` in `self`.  Equivalent to `self * 2`.
261
    #[corresponds(BN_lshift1)]
262
0
    pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
263
0
        unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
264
0
    }
265
266
    /// Places `a >> 1` in `self`. Equivalent to `self / 2`.
267
    #[corresponds(BN_rshift1)]
268
0
    pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
269
0
        unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
270
0
    }
271
272
    /// Places `a + b` in `self`.  [`core::ops::Add`] is also implemented for `BigNumRef`.
273
    ///
274
    /// [`core::ops::Add`]: struct.BigNumRef.html#method.add
275
    #[corresponds(BN_add)]
276
0
    pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
277
0
        unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
278
0
    }
279
280
    /// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`.
281
    ///
282
    /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub
283
    #[corresponds(BN_sub)]
284
0
    pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
285
0
        unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
286
0
    }
287
288
    /// Places `a << n` in `self`.  Equivalent to `a * 2 ^ n`.
289
    #[corresponds(BN_lshift)]
290
    #[allow(clippy::useless_conversion)]
291
0
    pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
292
0
        unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
293
0
    }
294
295
    /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`.
296
    #[corresponds(BN_rshift)]
297
    #[allow(clippy::useless_conversion)]
298
0
    pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
299
0
        unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
300
0
    }
301
302
    /// Creates a new BigNum with the same value.
303
    #[corresponds(BN_dup)]
304
0
    pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
305
0
        unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
306
0
    }
307
308
    /// Sets the sign of `self`.  Pass true to set `self` to a negative.  False sets
309
    /// `self` positive.
310
    #[corresponds(BN_set_negative)]
311
0
    pub fn set_negative(&mut self, negative: bool) {
312
0
        unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
313
0
    }
314
315
    /// Compare the absolute values of `self` and `oth`.
316
    ///
317
    /// # Examples
318
    ///
319
    /// ```
320
    /// # use openssl::bn::BigNum;
321
    /// # use std::cmp::Ordering;
322
    /// let s = -BigNum::from_u32(8).unwrap();
323
    /// let o = BigNum::from_u32(8).unwrap();
324
    ///
325
    /// assert_eq!(s.ucmp(&o), Ordering::Equal);
326
    /// ```
327
    #[corresponds(BN_ucmp)]
328
0
    pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
329
0
        unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
330
0
    }
331
332
    /// Returns `true` if `self` is negative.
333
    #[corresponds(BN_is_negative)]
334
0
    pub fn is_negative(&self) -> bool {
335
0
        unsafe { BN_is_negative(self.as_ptr()) == 1 }
336
0
    }
337
338
    /// Returns `true` is `self` is even.
339
    #[corresponds(BN_is_even)]
340
    #[cfg(any(ossl110, boringssl, libressl350))]
341
0
    pub fn is_even(&self) -> bool {
342
0
        !self.is_odd()
343
0
    }
344
345
    /// Returns `true` is `self` is odd.
346
    #[corresponds(BN_is_odd)]
347
    #[cfg(any(ossl110, boringssl, libressl350))]
348
0
    pub fn is_odd(&self) -> bool {
349
0
        unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 }
350
0
    }
351
352
    /// Returns the number of significant bits in `self`.
353
    #[corresponds(BN_num_bits)]
354
    #[allow(clippy::unnecessary_cast)]
355
0
    pub fn num_bits(&self) -> i32 {
356
0
        unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
357
0
    }
358
359
    /// Returns the size of `self` in bytes. Implemented natively.
360
0
    pub fn num_bytes(&self) -> i32 {
361
0
        (self.num_bits() + 7) / 8
362
0
    }
363
364
    /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
365
    ///
366
    /// # Parameters
367
    ///
368
    /// * `bits`: Length of the number in bits.
369
    /// * `msb`: The desired properties of the most significant bit. See [`constants`].
370
    /// * `odd`: If `true`, the generated number will be odd.
371
    ///
372
    /// # Examples
373
    ///
374
    /// ```
375
    /// use openssl::bn::{BigNum, MsbOption};
376
    /// use openssl::error::ErrorStack;
377
    ///
378
    /// fn generate_random() -> Result< BigNum, ErrorStack > {
379
    ///    let mut big = BigNum::new()?;
380
    ///
381
    ///    // Generates a 128-bit odd random number
382
    ///    big.rand(128, MsbOption::MAYBE_ZERO, true);
383
    ///    Ok((big))
384
    /// }
385
    /// ```
386
    ///
387
    /// [`constants`]: index.html#constants
388
    #[corresponds(BN_rand)]
389
    #[allow(clippy::useless_conversion)]
390
0
    pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
391
0
        unsafe {
392
0
            cvt(ffi::BN_rand(
393
0
                self.as_ptr(),
394
0
                bits.into(),
395
0
                msb.0,
396
0
                odd as c_int,
397
0
            ))
398
0
            .map(|_| ())
399
0
        }
400
0
    }
401
402
    /// The cryptographically weak counterpart to `rand`.  Not suitable for key generation.
403
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
404
    #[corresponds(BN_pseudo_rand)]
405
    #[allow(clippy::useless_conversion)]
406
0
    pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
407
0
        unsafe {
408
0
            cvt(ffi::BN_pseudo_rand(
409
0
                self.as_ptr(),
410
0
                bits.into(),
411
0
                msb.0,
412
0
                odd as c_int,
413
0
            ))
414
0
            .map(|_| ())
415
0
        }
416
0
    }
417
418
    /// Generates a prime number, placing it in `self`.
419
    ///
420
    /// # Parameters
421
    ///
422
    /// * `bits`: The length of the prime in bits (lower bound).
423
    /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
424
    /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
425
    ///   generated prime and `rem` is `1` if not specified (`None`).
426
    ///
427
    /// # Examples
428
    ///
429
    /// ```
430
    /// use openssl::bn::BigNum;
431
    /// use openssl::error::ErrorStack;
432
    ///
433
    /// fn generate_weak_prime() -> Result< BigNum, ErrorStack > {
434
    ///    let mut big = BigNum::new()?;
435
    ///
436
    ///    // Generates a 128-bit simple prime number
437
    ///    big.generate_prime(128, false, None, None);
438
    ///    Ok((big))
439
    /// }
440
    /// ```
441
    #[corresponds(BN_generate_prime_ex)]
442
0
    pub fn generate_prime(
443
0
        &mut self,
444
0
        bits: i32,
445
0
        safe: bool,
446
0
        add: Option<&BigNumRef>,
447
0
        rem: Option<&BigNumRef>,
448
0
    ) -> Result<(), ErrorStack> {
449
0
        unsafe {
450
0
            cvt(ffi::BN_generate_prime_ex(
451
0
                self.as_ptr(),
452
0
                bits as c_int,
453
0
                safe as c_int,
454
0
                add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
455
0
                rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
456
0
                ptr::null_mut(),
457
0
            ))
458
0
            .map(|_| ())
459
0
        }
460
0
    }
461
462
    /// Places the result of `a * b` in `self`.
463
    /// [`core::ops::Mul`] is also implemented for `BigNumRef`.
464
    ///
465
    /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul
466
    #[corresponds(BN_mul)]
467
0
    pub fn checked_mul(
468
0
        &mut self,
469
0
        a: &BigNumRef,
470
0
        b: &BigNumRef,
471
0
        ctx: &mut BigNumContextRef,
472
0
    ) -> Result<(), ErrorStack> {
473
0
        unsafe {
474
0
            cvt(ffi::BN_mul(
475
0
                self.as_ptr(),
476
0
                a.as_ptr(),
477
0
                b.as_ptr(),
478
0
                ctx.as_ptr(),
479
0
            ))
480
0
            .map(|_| ())
481
0
        }
482
0
    }
483
484
    /// Places the result of `a / b` in `self`. The remainder is discarded.
485
    /// [`core::ops::Div`] is also implemented for `BigNumRef`.
486
    ///
487
    /// [`core::ops::Div`]: struct.BigNumRef.html#method.div
488
    #[corresponds(BN_div)]
489
0
    pub fn checked_div(
490
0
        &mut self,
491
0
        a: &BigNumRef,
492
0
        b: &BigNumRef,
493
0
        ctx: &mut BigNumContextRef,
494
0
    ) -> Result<(), ErrorStack> {
495
0
        unsafe {
496
0
            cvt(ffi::BN_div(
497
0
                self.as_ptr(),
498
0
                ptr::null_mut(),
499
0
                a.as_ptr(),
500
0
                b.as_ptr(),
501
0
                ctx.as_ptr(),
502
0
            ))
503
0
            .map(|_| ())
504
0
        }
505
0
    }
506
507
    /// Places the result of `a % b` in `self`.
508
    #[corresponds(BN_div)]
509
0
    pub fn checked_rem(
510
0
        &mut self,
511
0
        a: &BigNumRef,
512
0
        b: &BigNumRef,
513
0
        ctx: &mut BigNumContextRef,
514
0
    ) -> Result<(), ErrorStack> {
515
0
        unsafe {
516
0
            cvt(ffi::BN_div(
517
0
                ptr::null_mut(),
518
0
                self.as_ptr(),
519
0
                a.as_ptr(),
520
0
                b.as_ptr(),
521
0
                ctx.as_ptr(),
522
0
            ))
523
0
            .map(|_| ())
524
0
        }
525
0
    }
526
527
    /// Places the result of `a / b` in `self` and `a % b` in `rem`.
528
    #[corresponds(BN_div)]
529
0
    pub fn div_rem(
530
0
        &mut self,
531
0
        rem: &mut BigNumRef,
532
0
        a: &BigNumRef,
533
0
        b: &BigNumRef,
534
0
        ctx: &mut BigNumContextRef,
535
0
    ) -> Result<(), ErrorStack> {
536
0
        unsafe {
537
0
            cvt(ffi::BN_div(
538
0
                self.as_ptr(),
539
0
                rem.as_ptr(),
540
0
                a.as_ptr(),
541
0
                b.as_ptr(),
542
0
                ctx.as_ptr(),
543
0
            ))
544
0
            .map(|_| ())
545
0
        }
546
0
    }
547
548
    /// Places the result of `a²` in `self`.
549
    #[corresponds(BN_sqr)]
550
0
    pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
551
0
        unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
552
0
    }
553
554
    /// Places the result of `a mod m` in `self`.  As opposed to `div_rem`
555
    /// the result is non-negative.
556
    #[corresponds(BN_nnmod)]
557
0
    pub fn nnmod(
558
0
        &mut self,
559
0
        a: &BigNumRef,
560
0
        m: &BigNumRef,
561
0
        ctx: &mut BigNumContextRef,
562
0
    ) -> Result<(), ErrorStack> {
563
0
        unsafe {
564
0
            cvt(ffi::BN_nnmod(
565
0
                self.as_ptr(),
566
0
                a.as_ptr(),
567
0
                m.as_ptr(),
568
0
                ctx.as_ptr(),
569
0
            ))
570
0
            .map(|_| ())
571
0
        }
572
0
    }
573
574
    /// Places the result of `(a + b) mod m` in `self`.
575
    #[corresponds(BN_mod_add)]
576
0
    pub fn mod_add(
577
0
        &mut self,
578
0
        a: &BigNumRef,
579
0
        b: &BigNumRef,
580
0
        m: &BigNumRef,
581
0
        ctx: &mut BigNumContextRef,
582
0
    ) -> Result<(), ErrorStack> {
583
0
        unsafe {
584
0
            cvt(ffi::BN_mod_add(
585
0
                self.as_ptr(),
586
0
                a.as_ptr(),
587
0
                b.as_ptr(),
588
0
                m.as_ptr(),
589
0
                ctx.as_ptr(),
590
0
            ))
591
0
            .map(|_| ())
592
0
        }
593
0
    }
594
595
    /// Places the result of `(a - b) mod m` in `self`.
596
    #[corresponds(BN_mod_sub)]
597
0
    pub fn mod_sub(
598
0
        &mut self,
599
0
        a: &BigNumRef,
600
0
        b: &BigNumRef,
601
0
        m: &BigNumRef,
602
0
        ctx: &mut BigNumContextRef,
603
0
    ) -> Result<(), ErrorStack> {
604
0
        unsafe {
605
0
            cvt(ffi::BN_mod_sub(
606
0
                self.as_ptr(),
607
0
                a.as_ptr(),
608
0
                b.as_ptr(),
609
0
                m.as_ptr(),
610
0
                ctx.as_ptr(),
611
0
            ))
612
0
            .map(|_| ())
613
0
        }
614
0
    }
615
616
    /// Places the result of `(a * b) mod m` in `self`.
617
    #[corresponds(BN_mod_mul)]
618
0
    pub fn mod_mul(
619
0
        &mut self,
620
0
        a: &BigNumRef,
621
0
        b: &BigNumRef,
622
0
        m: &BigNumRef,
623
0
        ctx: &mut BigNumContextRef,
624
0
    ) -> Result<(), ErrorStack> {
625
0
        unsafe {
626
0
            cvt(ffi::BN_mod_mul(
627
0
                self.as_ptr(),
628
0
                a.as_ptr(),
629
0
                b.as_ptr(),
630
0
                m.as_ptr(),
631
0
                ctx.as_ptr(),
632
0
            ))
633
0
            .map(|_| ())
634
0
        }
635
0
    }
636
637
    /// Places the result of `a² mod m` in `self`.
638
    #[corresponds(BN_mod_sqr)]
639
0
    pub fn mod_sqr(
640
0
        &mut self,
641
0
        a: &BigNumRef,
642
0
        m: &BigNumRef,
643
0
        ctx: &mut BigNumContextRef,
644
0
    ) -> Result<(), ErrorStack> {
645
0
        unsafe {
646
0
            cvt(ffi::BN_mod_sqr(
647
0
                self.as_ptr(),
648
0
                a.as_ptr(),
649
0
                m.as_ptr(),
650
0
                ctx.as_ptr(),
651
0
            ))
652
0
            .map(|_| ())
653
0
        }
654
0
    }
655
656
    /// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)`
657
    #[corresponds(BN_mod_sqrt)]
658
0
    pub fn mod_sqrt(
659
0
        &mut self,
660
0
        a: &BigNumRef,
661
0
        p: &BigNumRef,
662
0
        ctx: &mut BigNumContextRef,
663
0
    ) -> Result<(), ErrorStack> {
664
0
        unsafe {
665
0
            cvt_p(ffi::BN_mod_sqrt(
666
0
                self.as_ptr(),
667
0
                a.as_ptr(),
668
0
                p.as_ptr(),
669
0
                ctx.as_ptr(),
670
0
            ))
671
0
            .map(|_| ())
672
0
        }
673
0
    }
674
675
    /// Places the result of `a^p` in `self`.
676
    #[corresponds(BN_exp)]
677
0
    pub fn exp(
678
0
        &mut self,
679
0
        a: &BigNumRef,
680
0
        p: &BigNumRef,
681
0
        ctx: &mut BigNumContextRef,
682
0
    ) -> Result<(), ErrorStack> {
683
0
        unsafe {
684
0
            cvt(ffi::BN_exp(
685
0
                self.as_ptr(),
686
0
                a.as_ptr(),
687
0
                p.as_ptr(),
688
0
                ctx.as_ptr(),
689
0
            ))
690
0
            .map(|_| ())
691
0
        }
692
0
    }
693
694
    /// Places the result of `a^p mod m` in `self`.
695
    #[corresponds(BN_mod_exp)]
696
0
    pub fn mod_exp(
697
0
        &mut self,
698
0
        a: &BigNumRef,
699
0
        p: &BigNumRef,
700
0
        m: &BigNumRef,
701
0
        ctx: &mut BigNumContextRef,
702
0
    ) -> Result<(), ErrorStack> {
703
0
        unsafe {
704
0
            cvt(ffi::BN_mod_exp(
705
0
                self.as_ptr(),
706
0
                a.as_ptr(),
707
0
                p.as_ptr(),
708
0
                m.as_ptr(),
709
0
                ctx.as_ptr(),
710
0
            ))
711
0
            .map(|_| ())
712
0
        }
713
0
    }
714
715
    /// Places the inverse of `a` modulo `n` in `self`.
716
    #[corresponds(BN_mod_inverse)]
717
0
    pub fn mod_inverse(
718
0
        &mut self,
719
0
        a: &BigNumRef,
720
0
        n: &BigNumRef,
721
0
        ctx: &mut BigNumContextRef,
722
0
    ) -> Result<(), ErrorStack> {
723
0
        unsafe {
724
0
            cvt_p(ffi::BN_mod_inverse(
725
0
                self.as_ptr(),
726
0
                a.as_ptr(),
727
0
                n.as_ptr(),
728
0
                ctx.as_ptr(),
729
0
            ))
730
0
            .map(|_| ())
731
0
        }
732
0
    }
733
734
    /// Places the greatest common denominator of `a` and `b` in `self`.
735
    #[corresponds(BN_gcd)]
736
0
    pub fn gcd(
737
0
        &mut self,
738
0
        a: &BigNumRef,
739
0
        b: &BigNumRef,
740
0
        ctx: &mut BigNumContextRef,
741
0
    ) -> Result<(), ErrorStack> {
742
0
        unsafe {
743
0
            cvt(ffi::BN_gcd(
744
0
                self.as_ptr(),
745
0
                a.as_ptr(),
746
0
                b.as_ptr(),
747
0
                ctx.as_ptr(),
748
0
            ))
749
0
            .map(|_| ())
750
0
        }
751
0
    }
752
753
    /// Checks whether `self` is prime.
754
    ///
755
    /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
756
    ///
757
    /// # Return Value
758
    ///
759
    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
760
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
761
    #[corresponds(BN_is_prime_ex)]
762
    #[allow(clippy::useless_conversion)]
763
0
    pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
764
0
        unsafe {
765
0
            cvt_n(ffi::BN_is_prime_ex(
766
0
                self.as_ptr(),
767
0
                checks.into(),
768
0
                ctx.as_ptr(),
769
0
                ptr::null_mut(),
770
0
            ))
771
0
            .map(|r| r != 0)
772
0
        }
773
0
    }
774
775
    /// Checks whether `self` is prime with optional trial division.
776
    ///
777
    /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
778
    /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
779
    /// iterations.
780
    ///
781
    /// # Return Value
782
    ///
783
    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
784
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
785
    #[corresponds(BN_is_prime_fasttest_ex)]
786
    #[allow(clippy::useless_conversion)]
787
0
    pub fn is_prime_fasttest(
788
0
        &self,
789
0
        checks: i32,
790
0
        ctx: &mut BigNumContextRef,
791
0
        do_trial_division: bool,
792
0
    ) -> Result<bool, ErrorStack> {
793
0
        unsafe {
794
0
            cvt_n(ffi::BN_is_prime_fasttest_ex(
795
0
                self.as_ptr(),
796
0
                checks.into(),
797
0
                ctx.as_ptr(),
798
0
                do_trial_division as c_int,
799
0
                ptr::null_mut(),
800
0
            ))
801
0
            .map(|r| r != 0)
802
0
        }
803
0
    }
804
805
    /// Returns a big-endian byte vector representation of the absolute value of `self`.
806
    ///
807
    /// `self` can be recreated by using `from_slice`.
808
    ///
809
    /// ```
810
    /// # use openssl::bn::BigNum;
811
    /// let s = -BigNum::from_u32(4543).unwrap();
812
    /// let r = BigNum::from_u32(4543).unwrap();
813
    ///
814
    /// let s_vec = s.to_vec();
815
    /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
816
    /// ```
817
    #[corresponds(BN_bn2bin)]
818
0
    pub fn to_vec(&self) -> Vec<u8> {
819
0
        let size = self.num_bytes() as usize;
820
0
        let mut v = Vec::with_capacity(size);
821
0
        unsafe {
822
0
            ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
823
0
            v.set_len(size);
824
0
        }
825
0
        v
826
0
    }
827
828
    /// Returns a big-endian byte vector representation of the absolute value of `self` padded
829
    /// to `pad_to` bytes.
830
    ///
831
    /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
832
    ///
833
    /// `self` can be recreated by using `from_slice`.
834
    ///
835
    /// ```
836
    /// # use openssl::bn::BigNum;
837
    /// let bn = BigNum::from_u32(0x4543).unwrap();
838
    ///
839
    /// let bn_vec = bn.to_vec_padded(4).unwrap();
840
    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
841
    ///
842
    /// let r = bn.to_vec_padded(1);
843
    /// assert!(r.is_err());
844
    ///
845
    /// let bn = -BigNum::from_u32(0x4543).unwrap();
846
    /// let bn_vec = bn.to_vec_padded(4).unwrap();
847
    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
848
    /// ```
849
    #[corresponds(BN_bn2binpad)]
850
    #[cfg(any(ossl110, libressl340, boringssl))]
851
0
    pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
852
0
        let mut v = Vec::with_capacity(pad_to as usize);
853
0
        unsafe {
854
0
            cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
855
0
            v.set_len(pad_to as usize);
856
0
        }
857
0
        Ok(v)
858
0
    }
859
860
    /// Returns a decimal string representation of `self`.
861
    ///
862
    /// ```
863
    /// # use openssl::bn::BigNum;
864
    /// let s = -BigNum::from_u32(12345).unwrap();
865
    ///
866
    /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
867
    /// ```
868
    #[corresponds(BN_bn2dec)]
869
0
    pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
870
        unsafe {
871
0
            let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
872
0
            Ok(OpensslString::from_ptr(buf))
873
        }
874
0
    }
875
876
    /// Returns a hexadecimal string representation of `self`.
877
    ///
878
    /// ```
879
    /// # use openssl::bn::BigNum;
880
    /// let s = -BigNum::from_u32(0x99ff).unwrap();
881
    ///
882
    /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
883
    /// ```
884
    #[corresponds(BN_bn2hex)]
885
0
    pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
886
        unsafe {
887
0
            let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
888
0
            Ok(OpensslString::from_ptr(buf))
889
        }
890
0
    }
891
892
    /// Returns an `Asn1Integer` containing the value of `self`.
893
    #[corresponds(BN_to_ASN1_INTEGER)]
894
0
    pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
895
0
        unsafe {
896
0
            cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
897
0
                .map(|p| Asn1Integer::from_ptr(p))
898
0
        }
899
0
    }
900
901
    /// Force constant time computation on this value.
902
    #[corresponds(BN_set_flags)]
903
    #[cfg(ossl110)]
904
0
    pub fn set_const_time(&mut self) {
905
0
        unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
906
0
    }
907
908
    /// Returns true if `self` is in const time mode.
909
    #[corresponds(BN_get_flags)]
910
    #[cfg(ossl110)]
911
0
    pub fn is_const_time(&self) -> bool {
912
0
        unsafe {
913
0
            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
914
0
            ret == ffi::BN_FLG_CONSTTIME
915
0
        }
916
0
    }
917
918
    /// Returns true if `self` was created with [`BigNum::new_secure`].
919
    #[corresponds(BN_get_flags)]
920
    #[cfg(ossl110)]
921
0
    pub fn is_secure(&self) -> bool {
922
0
        unsafe {
923
0
            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
924
0
            ret == ffi::BN_FLG_SECURE
925
0
        }
926
0
    }
927
}
928
929
impl BigNum {
930
    /// Creates a new `BigNum` with the value 0.
931
    #[corresponds(BN_new)]
932
0
    pub fn new() -> Result<BigNum, ErrorStack> {
933
0
        unsafe {
934
0
            ffi::init();
935
0
            let v = cvt_p(ffi::BN_new())?;
936
0
            Ok(BigNum::from_ptr(v))
937
        }
938
0
    }
939
940
    /// Returns a new secure `BigNum`.
941
    #[corresponds(BN_secure_new)]
942
    #[cfg(ossl110)]
943
0
    pub fn new_secure() -> Result<BigNum, ErrorStack> {
944
0
        unsafe {
945
0
            ffi::init();
946
0
            let v = cvt_p(ffi::BN_secure_new())?;
947
0
            Ok(BigNum::from_ptr(v))
948
        }
949
0
    }
950
951
    /// Creates a new `BigNum` with the given value.
952
    #[corresponds(BN_set_word)]
953
0
    pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
954
0
        BigNum::new().and_then(|v| unsafe {
955
0
            cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
956
0
        })
957
0
    }
958
959
    /// Creates a `BigNum` from a decimal string.
960
    #[corresponds(BN_dec2bn)]
961
0
    pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
962
0
        unsafe {
963
0
            ffi::init();
964
0
            let c_str = CString::new(s.as_bytes()).unwrap();
965
0
            let mut bn = ptr::null_mut();
966
0
            cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?;
967
0
            Ok(BigNum::from_ptr(bn))
968
        }
969
0
    }
970
971
    /// Creates a `BigNum` from a hexadecimal string.
972
    #[corresponds(BN_hex2bn)]
973
0
    pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
974
0
        unsafe {
975
0
            ffi::init();
976
0
            let c_str = CString::new(s.as_bytes()).unwrap();
977
0
            let mut bn = ptr::null_mut();
978
0
            cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?;
979
0
            Ok(BigNum::from_ptr(bn))
980
        }
981
0
    }
982
983
    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
984
    /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
985
    /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
986
    ///
987
    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
988
    #[corresponds(BN_get_rfc2409_prime_768)]
989
    #[cfg(not(boringssl))]
990
0
    pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
991
0
        unsafe {
992
0
            ffi::init();
993
0
            cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
994
0
        }
995
0
    }
996
997
    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
998
    /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
999
    /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
1000
    ///
1001
    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
1002
    #[corresponds(BN_get_rfc2409_prime_1024)]
1003
    #[cfg(not(boringssl))]
1004
0
    pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
1005
0
        unsafe {
1006
0
            ffi::init();
1007
0
            cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
1008
0
        }
1009
0
    }
1010
1011
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1012
    /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
1013
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
1014
    ///
1015
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1016
    #[corresponds(BN_get_rfc3526_prime_1536)]
1017
    #[cfg(not(boringssl))]
1018
0
    pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
1019
0
        unsafe {
1020
0
            ffi::init();
1021
0
            cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
1022
0
        }
1023
0
    }
1024
1025
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1026
    /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
1027
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
1028
    ///
1029
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1030
    #[corresponds(BN_get_rfc3526_prime_2048)]
1031
    #[cfg(not(boringssl))]
1032
0
    pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
1033
0
        unsafe {
1034
0
            ffi::init();
1035
0
            cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
1036
0
        }
1037
0
    }
1038
1039
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1040
    /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
1041
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
1042
    ///
1043
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1044
    #[corresponds(BN_get_rfc3526_prime_3072)]
1045
    #[cfg(not(boringssl))]
1046
0
    pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
1047
0
        unsafe {
1048
0
            ffi::init();
1049
0
            cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
1050
0
        }
1051
0
    }
1052
1053
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1054
    /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
1055
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
1056
    ///
1057
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1058
    #[corresponds(BN_get_rfc3526_prime_4096)]
1059
    #[cfg(not(boringssl))]
1060
0
    pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
1061
0
        unsafe {
1062
0
            ffi::init();
1063
0
            cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum)
1064
0
        }
1065
0
    }
1066
1067
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1068
    /// of magnitude of `2 ^ 6144`.  This number is used during calculated key
1069
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 17.
1070
    ///
1071
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1072
    #[corresponds(BN_get_rfc3526_prime_6114)]
1073
    #[cfg(not(boringssl))]
1074
0
    pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
1075
0
        unsafe {
1076
0
            ffi::init();
1077
0
            cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
1078
0
        }
1079
0
    }
1080
1081
    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1082
    /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
1083
    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
1084
    ///
1085
    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1086
    #[corresponds(BN_get_rfc3526_prime_8192)]
1087
    #[cfg(not(boringssl))]
1088
0
    pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
1089
0
        unsafe {
1090
0
            ffi::init();
1091
0
            cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
1092
0
        }
1093
0
    }
1094
1095
    /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
1096
    ///
1097
    /// OpenSSL documentation at [`BN_bin2bn`]
1098
    ///
1099
    /// [`BN_bin2bn`]: https://www.openssl.org/docs/manmaster/crypto/BN_bin2bn.html
1100
    ///
1101
    /// ```
1102
    /// # use openssl::bn::BigNum;
1103
    /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
1104
    ///
1105
    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1106
    /// ```
1107
    #[corresponds(BN_bin2bn)]
1108
0
    pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
1109
0
        unsafe {
1110
0
            ffi::init();
1111
0
            assert!(n.len() <= LenType::max_value() as usize);
1112
1113
0
            cvt_p(ffi::BN_bin2bn(
1114
0
                n.as_ptr(),
1115
0
                n.len() as LenType,
1116
0
                ptr::null_mut(),
1117
0
            ))
1118
0
            .map(|p| BigNum::from_ptr(p))
1119
0
        }
1120
0
    }
1121
1122
    /// Copies data from a slice overwriting what was in the BigNum.
1123
    ///
1124
    /// This function can be used to copy data from a slice to a
1125
    /// [secure BigNum][`BigNum::new_secure`].
1126
    ///
1127
    /// # Examples
1128
    ///
1129
    /// ```
1130
    /// # use openssl::bn::BigNum;
1131
    /// let mut bignum = BigNum::new().unwrap();
1132
    /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
1133
    ///
1134
    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1135
    /// ```
1136
    #[corresponds(BN_bin2bn)]
1137
0
    pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
1138
0
        unsafe {
1139
0
            assert!(n.len() <= LenType::max_value() as usize);
1140
1141
0
            cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
1142
0
            Ok(())
1143
        }
1144
0
    }
1145
}
1146
1147
impl fmt::Debug for BigNumRef {
1148
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1149
0
        match self.to_dec_str() {
1150
0
            Ok(s) => f.write_str(&s),
1151
0
            Err(e) => Err(e.into()),
1152
        }
1153
0
    }
1154
}
1155
1156
impl fmt::Debug for BigNum {
1157
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1158
0
        match self.to_dec_str() {
1159
0
            Ok(s) => f.write_str(&s),
1160
0
            Err(e) => Err(e.into()),
1161
        }
1162
0
    }
1163
}
1164
1165
impl fmt::Display for BigNumRef {
1166
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167
0
        match self.to_dec_str() {
1168
0
            Ok(s) => f.write_str(&s),
1169
0
            Err(e) => Err(e.into()),
1170
        }
1171
0
    }
1172
}
1173
1174
impl fmt::Display for BigNum {
1175
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1176
0
        match self.to_dec_str() {
1177
0
            Ok(s) => f.write_str(&s),
1178
0
            Err(e) => Err(e.into()),
1179
        }
1180
0
    }
1181
}
1182
1183
impl PartialEq<BigNumRef> for BigNumRef {
1184
0
    fn eq(&self, oth: &BigNumRef) -> bool {
1185
0
        self.cmp(oth) == Ordering::Equal
1186
0
    }
1187
}
1188
1189
impl PartialEq<BigNum> for BigNumRef {
1190
0
    fn eq(&self, oth: &BigNum) -> bool {
1191
0
        self.eq(oth.deref())
1192
0
    }
1193
}
1194
1195
impl Eq for BigNumRef {}
1196
1197
impl PartialEq for BigNum {
1198
0
    fn eq(&self, oth: &BigNum) -> bool {
1199
0
        self.deref().eq(oth)
1200
0
    }
1201
}
1202
1203
impl PartialEq<BigNumRef> for BigNum {
1204
0
    fn eq(&self, oth: &BigNumRef) -> bool {
1205
0
        self.deref().eq(oth)
1206
0
    }
1207
}
1208
1209
impl Eq for BigNum {}
1210
1211
impl PartialOrd<BigNumRef> for BigNumRef {
1212
0
    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1213
0
        Some(self.cmp(oth))
1214
0
    }
1215
}
1216
1217
impl PartialOrd<BigNum> for BigNumRef {
1218
0
    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1219
0
        Some(self.cmp(oth.deref()))
1220
0
    }
1221
}
1222
1223
impl Ord for BigNumRef {
1224
0
    fn cmp(&self, oth: &BigNumRef) -> Ordering {
1225
0
        unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
1226
0
    }
1227
}
1228
1229
impl PartialOrd for BigNum {
1230
0
    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1231
0
        Some(self.cmp(oth))
1232
0
    }
1233
}
1234
1235
impl PartialOrd<BigNumRef> for BigNum {
1236
0
    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1237
0
        self.deref().partial_cmp(oth)
1238
0
    }
1239
}
1240
1241
impl Ord for BigNum {
1242
0
    fn cmp(&self, oth: &BigNum) -> Ordering {
1243
0
        self.deref().cmp(oth.deref())
1244
0
    }
1245
}
1246
1247
macro_rules! delegate {
1248
    ($t:ident, $m:ident) => {
1249
        impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
1250
            type Output = BigNum;
1251
1252
0
            fn $m(self, oth: &BigNum) -> BigNum {
1253
0
                $t::$m(self, oth.deref())
1254
0
            }
Unexecuted instantiation: <&openssl::bn::BigNumRef as core::ops::arith::Add<&openssl::bn::BigNum>>::add
Unexecuted instantiation: <&openssl::bn::BigNumRef as core::ops::arith::Sub<&openssl::bn::BigNum>>::sub
Unexecuted instantiation: <&openssl::bn::BigNumRef as core::ops::arith::Mul<&openssl::bn::BigNum>>::mul
Unexecuted instantiation: <&openssl::bn::BigNumRef as core::ops::arith::Div<&openssl::bn::BigNum>>::div
Unexecuted instantiation: <&openssl::bn::BigNumRef as core::ops::arith::Rem<&openssl::bn::BigNum>>::rem
1255
        }
1256
1257
        impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
1258
            type Output = BigNum;
1259
1260
0
            fn $m(self, oth: &BigNumRef) -> BigNum {
1261
0
                $t::$m(self.deref(), oth)
1262
0
            }
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Add<&openssl::bn::BigNumRef>>::add
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Sub<&openssl::bn::BigNumRef>>::sub
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Mul<&openssl::bn::BigNumRef>>::mul
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Div<&openssl::bn::BigNumRef>>::div
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Rem<&openssl::bn::BigNumRef>>::rem
1263
        }
1264
1265
        impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
1266
            type Output = BigNum;
1267
1268
0
            fn $m(self, oth: &BigNum) -> BigNum {
1269
0
                $t::$m(self.deref(), oth.deref())
1270
0
            }
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Add>::add
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Sub>::sub
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Mul>::mul
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Div>::div
Unexecuted instantiation: <&openssl::bn::BigNum as core::ops::arith::Rem>::rem
1271
        }
1272
    };
1273
}
1274
1275
impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
1276
    type Output = BigNum;
1277
1278
0
    fn add(self, oth: &BigNumRef) -> BigNum {
1279
0
        let mut r = BigNum::new().unwrap();
1280
0
        r.checked_add(self, oth).unwrap();
1281
0
        r
1282
0
    }
1283
}
1284
1285
delegate!(Add, add);
1286
1287
impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
1288
    type Output = BigNum;
1289
1290
0
    fn sub(self, oth: &BigNumRef) -> BigNum {
1291
0
        let mut r = BigNum::new().unwrap();
1292
0
        r.checked_sub(self, oth).unwrap();
1293
0
        r
1294
0
    }
1295
}
1296
1297
delegate!(Sub, sub);
1298
1299
impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
1300
    type Output = BigNum;
1301
1302
0
    fn mul(self, oth: &BigNumRef) -> BigNum {
1303
0
        let mut ctx = BigNumContext::new().unwrap();
1304
0
        let mut r = BigNum::new().unwrap();
1305
0
        r.checked_mul(self, oth, &mut ctx).unwrap();
1306
0
        r
1307
0
    }
1308
}
1309
1310
delegate!(Mul, mul);
1311
1312
impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
1313
    type Output = BigNum;
1314
1315
0
    fn div(self, oth: &'b BigNumRef) -> BigNum {
1316
0
        let mut ctx = BigNumContext::new().unwrap();
1317
0
        let mut r = BigNum::new().unwrap();
1318
0
        r.checked_div(self, oth, &mut ctx).unwrap();
1319
0
        r
1320
0
    }
1321
}
1322
1323
delegate!(Div, div);
1324
1325
impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
1326
    type Output = BigNum;
1327
1328
0
    fn rem(self, oth: &'b BigNumRef) -> BigNum {
1329
0
        let mut ctx = BigNumContext::new().unwrap();
1330
0
        let mut r = BigNum::new().unwrap();
1331
0
        r.checked_rem(self, oth, &mut ctx).unwrap();
1332
0
        r
1333
0
    }
1334
}
1335
1336
delegate!(Rem, rem);
1337
1338
impl<'a> Shl<i32> for &'a BigNumRef {
1339
    type Output = BigNum;
1340
1341
0
    fn shl(self, n: i32) -> BigNum {
1342
0
        let mut r = BigNum::new().unwrap();
1343
0
        r.lshift(self, n).unwrap();
1344
0
        r
1345
0
    }
1346
}
1347
1348
impl<'a> Shl<i32> for &'a BigNum {
1349
    type Output = BigNum;
1350
1351
0
    fn shl(self, n: i32) -> BigNum {
1352
0
        self.deref().shl(n)
1353
0
    }
1354
}
1355
1356
impl<'a> Shr<i32> for &'a BigNumRef {
1357
    type Output = BigNum;
1358
1359
0
    fn shr(self, n: i32) -> BigNum {
1360
0
        let mut r = BigNum::new().unwrap();
1361
0
        r.rshift(self, n).unwrap();
1362
0
        r
1363
0
    }
1364
}
1365
1366
impl<'a> Shr<i32> for &'a BigNum {
1367
    type Output = BigNum;
1368
1369
0
    fn shr(self, n: i32) -> BigNum {
1370
0
        self.deref().shr(n)
1371
0
    }
1372
}
1373
1374
impl<'a> Neg for &'a BigNumRef {
1375
    type Output = BigNum;
1376
1377
0
    fn neg(self) -> BigNum {
1378
0
        self.to_owned().unwrap().neg()
1379
0
    }
1380
}
1381
1382
impl<'a> Neg for &'a BigNum {
1383
    type Output = BigNum;
1384
1385
0
    fn neg(self) -> BigNum {
1386
0
        self.deref().neg()
1387
0
    }
1388
}
1389
1390
impl Neg for BigNum {
1391
    type Output = BigNum;
1392
1393
0
    fn neg(mut self) -> BigNum {
1394
0
        let negative = self.is_negative();
1395
0
        self.set_negative(!negative);
1396
0
        self
1397
0
    }
1398
}
1399
1400
#[cfg(test)]
1401
mod tests {
1402
    use crate::bn::{BigNum, BigNumContext};
1403
1404
    #[test]
1405
    fn test_to_from_slice() {
1406
        let v0 = BigNum::from_u32(10_203_004).unwrap();
1407
        let vec = v0.to_vec();
1408
        let v1 = BigNum::from_slice(&vec).unwrap();
1409
1410
        assert_eq!(v0, v1);
1411
    }
1412
1413
    #[test]
1414
    fn test_negation() {
1415
        let a = BigNum::from_u32(909_829_283).unwrap();
1416
1417
        assert!(!a.is_negative());
1418
        assert!((-a).is_negative());
1419
    }
1420
1421
    #[test]
1422
    fn test_shift() {
1423
        let a = BigNum::from_u32(909_829_283).unwrap();
1424
1425
        assert_eq!(a, &(&a << 1) >> 1);
1426
    }
1427
1428
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1429
    #[test]
1430
    fn test_rand_range() {
1431
        let range = BigNum::from_u32(909_829_283).unwrap();
1432
        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1433
        range.rand_range(&mut result).unwrap();
1434
        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1435
    }
1436
1437
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1438
    #[test]
1439
    fn test_pseudo_rand_range() {
1440
        let range = BigNum::from_u32(909_829_283).unwrap();
1441
        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1442
        range.pseudo_rand_range(&mut result).unwrap();
1443
        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1444
    }
1445
1446
    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1447
    #[test]
1448
    fn test_prime_numbers() {
1449
        let a = BigNum::from_u32(19_029_017).unwrap();
1450
        let mut p = BigNum::new().unwrap();
1451
        p.generate_prime(128, true, None, Some(&a)).unwrap();
1452
1453
        let mut ctx = BigNumContext::new().unwrap();
1454
        assert!(p.is_prime(100, &mut ctx).unwrap());
1455
        assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
1456
    }
1457
1458
    #[cfg(ossl110)]
1459
    #[test]
1460
    fn test_secure_bn_ctx() {
1461
        let mut cxt = BigNumContext::new_secure().unwrap();
1462
        let a = BigNum::from_u32(8).unwrap();
1463
        let b = BigNum::from_u32(3).unwrap();
1464
1465
        let mut remainder = BigNum::new().unwrap();
1466
        remainder.nnmod(&a, &b, &mut cxt).unwrap();
1467
1468
        assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
1469
    }
1470
1471
    #[cfg(ossl110)]
1472
    #[test]
1473
    fn test_secure_bn() {
1474
        let a = BigNum::new().unwrap();
1475
        assert!(!a.is_secure());
1476
1477
        let b = BigNum::new_secure().unwrap();
1478
        assert!(b.is_secure())
1479
    }
1480
1481
    #[cfg(ossl110)]
1482
    #[test]
1483
    fn test_const_time_bn() {
1484
        let a = BigNum::new().unwrap();
1485
        assert!(!a.is_const_time());
1486
1487
        let mut b = BigNum::new().unwrap();
1488
        b.set_const_time();
1489
        assert!(b.is_const_time())
1490
    }
1491
1492
    #[test]
1493
    fn test_mod_sqrt() {
1494
        let mut ctx = BigNumContext::new().unwrap();
1495
1496
        let s = BigNum::from_hex_str("2").unwrap();
1497
        let p = BigNum::from_hex_str("7DEB1").unwrap();
1498
        let mut sqrt = BigNum::new().unwrap();
1499
        let mut out = BigNum::new().unwrap();
1500
1501
        // Square the root because OpenSSL randomly returns one of 2E42C or 4FA85
1502
        sqrt.mod_sqrt(&s, &p, &mut ctx).unwrap();
1503
        out.mod_sqr(&sqrt, &p, &mut ctx).unwrap();
1504
        assert!(out == s);
1505
1506
        let s = BigNum::from_hex_str("3").unwrap();
1507
        let p = BigNum::from_hex_str("5").unwrap();
1508
        assert!(out.mod_sqrt(&s, &p, &mut ctx).is_err());
1509
    }
1510
1511
    #[test]
1512
    #[cfg(any(ossl110, boringssl, libressl350))]
1513
    fn test_odd_even() {
1514
        let a = BigNum::from_u32(17).unwrap();
1515
        let b = BigNum::from_u32(18).unwrap();
1516
1517
        assert!(a.is_odd());
1518
        assert!(!b.is_odd());
1519
1520
        assert!(!a.is_even());
1521
        assert!(b.is_even());
1522
    }
1523
}