rboring/
bn.rs

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