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)
25use cfg_if::cfg_if;
26use foreign_types::{ForeignType, ForeignTypeRef};
27use libc::c_int;
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::string::OpensslString;
36use crate::{cvt, cvt_n, cvt_p, LenType};
37use openssl_macros::corresponds;
38
39cfg_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`.
68pub struct MsbOption(c_int);
69
70impl 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
84foreign_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
102impl BigNumContext {
103    /// Returns a new `BigNumContext`.
104    #[corresponds(BN_CTX_new)]
105    pub fn new() -> Result<BigNumContext, ErrorStack> {
106        unsafe {
107            ffi::init();
108            cvt_p(ffi::BN_CTX_new()).map(BigNumContext)
109        }
110    }
111
112    /// Returns a new secure `BigNumContext`.
113    #[corresponds(BN_CTX_secure_new)]
114    #[cfg(ossl110)]
115    pub fn new_secure() -> Result<BigNumContext, ErrorStack> {
116        unsafe {
117            ffi::init();
118            cvt_p(ffi::BN_CTX_secure_new()).map(BigNumContext)
119        }
120    }
121}
122
123foreign_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
157impl 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    pub fn clear(&mut self) {
163        unsafe { ffi::BN_clear(self.as_ptr()) }
164    }
165
166    /// Adds a `u32` to `self`.
167    #[corresponds(BN_add_word)]
168    pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
169        unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
170    }
171
172    /// Subtracts a `u32` from `self`.
173    #[corresponds(BN_sub_word)]
174    pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
175        unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
176    }
177
178    /// Multiplies a `u32` by `self`.
179    #[corresponds(BN_mul_word)]
180    pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
181        unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
182    }
183
184    /// Divides `self` by a `u32`, returning the remainder.
185    #[corresponds(BN_div_word)]
186    #[allow(clippy::useless_conversion)]
187    pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
188        unsafe {
189            let r = ffi::BN_div_word(self.as_ptr(), w.into());
190            if r == ffi::BN_ULONG::max_value() {
191                Err(ErrorStack::get())
192            } else {
193                Ok(r.into())
194            }
195        }
196    }
197
198    /// Returns the result of `self` modulo `w`.
199    #[corresponds(BN_mod_word)]
200    #[allow(clippy::useless_conversion)]
201    pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
202        unsafe {
203            let r = ffi::BN_mod_word(self.as_ptr(), w.into());
204            if r == ffi::BN_ULONG::max_value() {
205                Err(ErrorStack::get())
206            } else {
207                Ok(r.into())
208            }
209        }
210    }
211
212    /// Places a cryptographically-secure pseudo-random nonnegative
213    /// number less than `self` in `rnd`.
214    #[corresponds(BN_rand_range)]
215    pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
216        unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
217    }
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    pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
223        unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
224    }
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    pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
232        unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
233    }
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    pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
241        unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
242    }
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    pub fn is_bit_set(&self, n: i32) -> bool {
248        unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
249    }
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    pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
257        unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
258    }
259
260    /// Places `a << 1` in `self`.  Equivalent to `self * 2`.
261    #[corresponds(BN_lshift1)]
262    pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
263        unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
264    }
265
266    /// Places `a >> 1` in `self`. Equivalent to `self / 2`.
267    #[corresponds(BN_rshift1)]
268    pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
269        unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
270    }
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    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    /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub
283    #[corresponds(BN_sub)]
284    pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
285        unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
286    }
287
288    /// Places `a << n` in `self`.  Equivalent to `a * 2 ^ n`.
289    #[corresponds(BN_lshift)]
290    #[allow(clippy::useless_conversion)]
291    pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
292        unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
293    }
294
295    /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`.
296    #[corresponds(BN_rshift)]
297    #[allow(clippy::useless_conversion)]
298    pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
299        unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
300    }
301
302    /// Creates a new BigNum with the same value.
303    #[corresponds(BN_dup)]
304    pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
305        unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
306    }
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    pub fn set_negative(&mut self, negative: bool) {
312        unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
313    }
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    pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
329        unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
330    }
331
332    /// Returns `true` if `self` is negative.
333    #[corresponds(BN_is_negative)]
334    pub fn is_negative(&self) -> bool {
335        unsafe { BN_is_negative(self.as_ptr()) == 1 }
336    }
337
338    /// Returns `true` is `self` is even.
339    #[corresponds(BN_is_even)]
340    #[cfg(any(ossl110, boringssl, libressl350))]
341    pub fn is_even(&self) -> bool {
342        !self.is_odd()
343    }
344
345    /// Returns `true` is `self` is odd.
346    #[corresponds(BN_is_odd)]
347    #[cfg(any(ossl110, boringssl, libressl350))]
348    pub fn is_odd(&self) -> bool {
349        unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 }
350    }
351
352    /// Returns the number of significant bits in `self`.
353    #[corresponds(BN_num_bits)]
354    #[allow(clippy::unnecessary_cast)]
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 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    pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
391        unsafe {
392            cvt(ffi::BN_rand(
393                self.as_ptr(),
394                bits.into(),
395                msb.0,
396                odd as c_int,
397            ))
398            .map(|_| ())
399        }
400    }
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    pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
407        unsafe {
408            cvt(ffi::BN_pseudo_rand(
409                self.as_ptr(),
410                bits.into(),
411                msb.0,
412                odd as c_int,
413            ))
414            .map(|_| ())
415        }
416    }
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    pub fn generate_prime(
443        &mut self,
444        bits: i32,
445        safe: bool,
446        add: Option<&BigNumRef>,
447        rem: Option<&BigNumRef>,
448    ) -> Result<(), ErrorStack> {
449        unsafe {
450            cvt(ffi::BN_generate_prime_ex(
451                self.as_ptr(),
452                bits as c_int,
453                safe as c_int,
454                add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
455                rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
456                ptr::null_mut(),
457            ))
458            .map(|_| ())
459        }
460    }
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    pub fn checked_mul(
468        &mut self,
469        a: &BigNumRef,
470        b: &BigNumRef,
471        ctx: &mut BigNumContextRef,
472    ) -> Result<(), ErrorStack> {
473        unsafe {
474            cvt(ffi::BN_mul(
475                self.as_ptr(),
476                a.as_ptr(),
477                b.as_ptr(),
478                ctx.as_ptr(),
479            ))
480            .map(|_| ())
481        }
482    }
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    pub fn checked_div(
490        &mut self,
491        a: &BigNumRef,
492        b: &BigNumRef,
493        ctx: &mut BigNumContextRef,
494    ) -> Result<(), ErrorStack> {
495        unsafe {
496            cvt(ffi::BN_div(
497                self.as_ptr(),
498                ptr::null_mut(),
499                a.as_ptr(),
500                b.as_ptr(),
501                ctx.as_ptr(),
502            ))
503            .map(|_| ())
504        }
505    }
506
507    /// Places the result of `a % b` in `self`.
508    #[corresponds(BN_div)]
509    pub fn checked_rem(
510        &mut self,
511        a: &BigNumRef,
512        b: &BigNumRef,
513        ctx: &mut BigNumContextRef,
514    ) -> Result<(), ErrorStack> {
515        unsafe {
516            cvt(ffi::BN_div(
517                ptr::null_mut(),
518                self.as_ptr(),
519                a.as_ptr(),
520                b.as_ptr(),
521                ctx.as_ptr(),
522            ))
523            .map(|_| ())
524        }
525    }
526
527    /// Places the result of `a / b` in `self` and `a % b` in `rem`.
528    #[corresponds(BN_div)]
529    pub fn div_rem(
530        &mut self,
531        rem: &mut BigNumRef,
532        a: &BigNumRef,
533        b: &BigNumRef,
534        ctx: &mut BigNumContextRef,
535    ) -> Result<(), ErrorStack> {
536        unsafe {
537            cvt(ffi::BN_div(
538                self.as_ptr(),
539                rem.as_ptr(),
540                a.as_ptr(),
541                b.as_ptr(),
542                ctx.as_ptr(),
543            ))
544            .map(|_| ())
545        }
546    }
547
548    /// Places the result of `a²` in `self`.
549    #[corresponds(BN_sqr)]
550    pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
551        unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
552    }
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    pub fn nnmod(
558        &mut self,
559        a: &BigNumRef,
560        m: &BigNumRef,
561        ctx: &mut BigNumContextRef,
562    ) -> Result<(), ErrorStack> {
563        unsafe {
564            cvt(ffi::BN_nnmod(
565                self.as_ptr(),
566                a.as_ptr(),
567                m.as_ptr(),
568                ctx.as_ptr(),
569            ))
570            .map(|_| ())
571        }
572    }
573
574    /// Places the result of `(a + b) mod m` in `self`.
575    #[corresponds(BN_mod_add)]
576    pub fn mod_add(
577        &mut self,
578        a: &BigNumRef,
579        b: &BigNumRef,
580        m: &BigNumRef,
581        ctx: &mut BigNumContextRef,
582    ) -> Result<(), ErrorStack> {
583        unsafe {
584            cvt(ffi::BN_mod_add(
585                self.as_ptr(),
586                a.as_ptr(),
587                b.as_ptr(),
588                m.as_ptr(),
589                ctx.as_ptr(),
590            ))
591            .map(|_| ())
592        }
593    }
594
595    /// Places the result of `(a - b) mod m` in `self`.
596    #[corresponds(BN_mod_sub)]
597    pub fn mod_sub(
598        &mut self,
599        a: &BigNumRef,
600        b: &BigNumRef,
601        m: &BigNumRef,
602        ctx: &mut BigNumContextRef,
603    ) -> Result<(), ErrorStack> {
604        unsafe {
605            cvt(ffi::BN_mod_sub(
606                self.as_ptr(),
607                a.as_ptr(),
608                b.as_ptr(),
609                m.as_ptr(),
610                ctx.as_ptr(),
611            ))
612            .map(|_| ())
613        }
614    }
615
616    /// Places the result of `(a * b) mod m` in `self`.
617    #[corresponds(BN_mod_mul)]
618    pub fn mod_mul(
619        &mut self,
620        a: &BigNumRef,
621        b: &BigNumRef,
622        m: &BigNumRef,
623        ctx: &mut BigNumContextRef,
624    ) -> Result<(), ErrorStack> {
625        unsafe {
626            cvt(ffi::BN_mod_mul(
627                self.as_ptr(),
628                a.as_ptr(),
629                b.as_ptr(),
630                m.as_ptr(),
631                ctx.as_ptr(),
632            ))
633            .map(|_| ())
634        }
635    }
636
637    /// Places the result of `a² mod m` in `self`.
638    #[corresponds(BN_mod_sqr)]
639    pub fn mod_sqr(
640        &mut self,
641        a: &BigNumRef,
642        m: &BigNumRef,
643        ctx: &mut BigNumContextRef,
644    ) -> Result<(), ErrorStack> {
645        unsafe {
646            cvt(ffi::BN_mod_sqr(
647                self.as_ptr(),
648                a.as_ptr(),
649                m.as_ptr(),
650                ctx.as_ptr(),
651            ))
652            .map(|_| ())
653        }
654    }
655
656    /// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)`
657    #[corresponds(BN_mod_sqrt)]
658    #[cfg(ossl110)]
659    pub fn mod_sqrt(
660        &mut self,
661        a: &BigNumRef,
662        p: &BigNumRef,
663        ctx: &mut BigNumContextRef,
664    ) -> Result<(), ErrorStack> {
665        unsafe {
666            cvt_p(ffi::BN_mod_sqrt(
667                self.as_ptr(),
668                a.as_ptr(),
669                p.as_ptr(),
670                ctx.as_ptr(),
671            ))
672            .map(|_| ())
673        }
674    }
675
676    /// Places the result of `a^p` in `self`.
677    #[corresponds(BN_exp)]
678    pub fn exp(
679        &mut self,
680        a: &BigNumRef,
681        p: &BigNumRef,
682        ctx: &mut BigNumContextRef,
683    ) -> Result<(), ErrorStack> {
684        unsafe {
685            cvt(ffi::BN_exp(
686                self.as_ptr(),
687                a.as_ptr(),
688                p.as_ptr(),
689                ctx.as_ptr(),
690            ))
691            .map(|_| ())
692        }
693    }
694
695    /// Places the result of `a^p mod m` in `self`.
696    #[corresponds(BN_mod_exp)]
697    pub fn mod_exp(
698        &mut self,
699        a: &BigNumRef,
700        p: &BigNumRef,
701        m: &BigNumRef,
702        ctx: &mut BigNumContextRef,
703    ) -> Result<(), ErrorStack> {
704        unsafe {
705            cvt(ffi::BN_mod_exp(
706                self.as_ptr(),
707                a.as_ptr(),
708                p.as_ptr(),
709                m.as_ptr(),
710                ctx.as_ptr(),
711            ))
712            .map(|_| ())
713        }
714    }
715
716    /// Places the inverse of `a` modulo `n` in `self`.
717    #[corresponds(BN_mod_inverse)]
718    pub fn mod_inverse(
719        &mut self,
720        a: &BigNumRef,
721        n: &BigNumRef,
722        ctx: &mut BigNumContextRef,
723    ) -> Result<(), ErrorStack> {
724        unsafe {
725            cvt_p(ffi::BN_mod_inverse(
726                self.as_ptr(),
727                a.as_ptr(),
728                n.as_ptr(),
729                ctx.as_ptr(),
730            ))
731            .map(|_| ())
732        }
733    }
734
735    /// Places the greatest common denominator of `a` and `b` in `self`.
736    #[corresponds(BN_gcd)]
737    pub fn gcd(
738        &mut self,
739        a: &BigNumRef,
740        b: &BigNumRef,
741        ctx: &mut BigNumContextRef,
742    ) -> Result<(), ErrorStack> {
743        unsafe {
744            cvt(ffi::BN_gcd(
745                self.as_ptr(),
746                a.as_ptr(),
747                b.as_ptr(),
748                ctx.as_ptr(),
749            ))
750            .map(|_| ())
751        }
752    }
753
754    /// Checks whether `self` is prime.
755    ///
756    /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
757    ///
758    /// # Return Value
759    ///
760    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
761    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
762    #[corresponds(BN_is_prime_ex)]
763    #[allow(clippy::useless_conversion)]
764    pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
765        unsafe {
766            cvt_n(ffi::BN_is_prime_ex(
767                self.as_ptr(),
768                checks.into(),
769                ctx.as_ptr(),
770                ptr::null_mut(),
771            ))
772            .map(|r| r != 0)
773        }
774    }
775
776    /// Checks whether `self` is prime with optional trial division.
777    ///
778    /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
779    /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
780    /// iterations.
781    ///
782    /// # Return Value
783    ///
784    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
785    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
786    #[corresponds(BN_is_prime_fasttest_ex)]
787    #[allow(clippy::useless_conversion)]
788    pub fn is_prime_fasttest(
789        &self,
790        checks: i32,
791        ctx: &mut BigNumContextRef,
792        do_trial_division: bool,
793    ) -> Result<bool, ErrorStack> {
794        unsafe {
795            cvt_n(ffi::BN_is_prime_fasttest_ex(
796                self.as_ptr(),
797                checks.into(),
798                ctx.as_ptr(),
799                do_trial_division as c_int,
800                ptr::null_mut(),
801            ))
802            .map(|r| r != 0)
803        }
804    }
805
806    /// Returns a big-endian byte vector representation of the absolute value of `self`.
807    ///
808    /// `self` can be recreated by using `from_slice`.
809    ///
810    /// ```
811    /// # use openssl::bn::BigNum;
812    /// let s = -BigNum::from_u32(4543).unwrap();
813    /// let r = BigNum::from_u32(4543).unwrap();
814    ///
815    /// let s_vec = s.to_vec();
816    /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
817    /// ```
818    #[corresponds(BN_bn2bin)]
819    pub fn to_vec(&self) -> Vec<u8> {
820        let size = self.num_bytes() as usize;
821        let mut v = Vec::with_capacity(size);
822        unsafe {
823            ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
824            v.set_len(size);
825        }
826        v
827    }
828
829    /// Returns a big-endian byte vector representation of the absolute value of `self` padded
830    /// to `pad_to` bytes.
831    ///
832    /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
833    ///
834    /// `self` can be recreated by using `from_slice`.
835    ///
836    /// ```
837    /// # use openssl::bn::BigNum;
838    /// let bn = BigNum::from_u32(0x4543).unwrap();
839    ///
840    /// let bn_vec = bn.to_vec_padded(4).unwrap();
841    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
842    ///
843    /// let r = bn.to_vec_padded(1);
844    /// assert!(r.is_err());
845    ///
846    /// let bn = -BigNum::from_u32(0x4543).unwrap();
847    /// let bn_vec = bn.to_vec_padded(4).unwrap();
848    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
849    /// ```
850    #[corresponds(BN_bn2binpad)]
851    #[cfg(any(ossl110, libressl340, boringssl))]
852    pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
853        let mut v = Vec::with_capacity(pad_to as usize);
854        unsafe {
855            cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
856            v.set_len(pad_to as usize);
857        }
858        Ok(v)
859    }
860
861    /// Returns a decimal string representation of `self`.
862    ///
863    /// ```
864    /// # use openssl::bn::BigNum;
865    /// let s = -BigNum::from_u32(12345).unwrap();
866    ///
867    /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
868    /// ```
869    #[corresponds(BN_bn2dec)]
870    pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
871        unsafe {
872            let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
873            Ok(OpensslString::from_ptr(buf))
874        }
875    }
876
877    /// Returns a hexadecimal string representation of `self`.
878    ///
879    /// ```
880    /// # use openssl::bn::BigNum;
881    /// let s = -BigNum::from_u32(0x99ff).unwrap();
882    ///
883    /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
884    /// ```
885    #[corresponds(BN_bn2hex)]
886    pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
887        unsafe {
888            let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
889            Ok(OpensslString::from_ptr(buf))
890        }
891    }
892
893    /// Returns an `Asn1Integer` containing the value of `self`.
894    #[corresponds(BN_to_ASN1_INTEGER)]
895    pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
896        unsafe {
897            cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
898                .map(|p| Asn1Integer::from_ptr(p))
899        }
900    }
901
902    /// Force constant time computation on this value.
903    #[corresponds(BN_set_flags)]
904    #[cfg(ossl110)]
905    pub fn set_const_time(&mut self) {
906        unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
907    }
908
909    /// Returns true if `self` is in const time mode.
910    #[corresponds(BN_get_flags)]
911    #[cfg(ossl110)]
912    pub fn is_const_time(&self) -> bool {
913        unsafe {
914            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
915            ret == ffi::BN_FLG_CONSTTIME
916        }
917    }
918
919    /// Returns true if `self` was created with [`BigNum::new_secure`].
920    #[corresponds(BN_get_flags)]
921    #[cfg(ossl110)]
922    pub fn is_secure(&self) -> bool {
923        unsafe {
924            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
925            ret == ffi::BN_FLG_SECURE
926        }
927    }
928}
929
930impl BigNum {
931    /// Creates a new `BigNum` with the value 0.
932    #[corresponds(BN_new)]
933    pub fn new() -> Result<BigNum, ErrorStack> {
934        unsafe {
935            ffi::init();
936            let v = cvt_p(ffi::BN_new())?;
937            Ok(BigNum::from_ptr(v))
938        }
939    }
940
941    /// Returns a new secure `BigNum`.
942    #[corresponds(BN_secure_new)]
943    #[cfg(ossl110)]
944    pub fn new_secure() -> Result<BigNum, ErrorStack> {
945        unsafe {
946            ffi::init();
947            let v = cvt_p(ffi::BN_secure_new())?;
948            Ok(BigNum::from_ptr(v))
949        }
950    }
951
952    /// Creates a new `BigNum` with the given value.
953    #[corresponds(BN_set_word)]
954    pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
955        BigNum::new().and_then(|v| unsafe {
956            cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
957        })
958    }
959
960    /// Creates a `BigNum` from a decimal string.
961    #[corresponds(BN_dec2bn)]
962    pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
963        unsafe {
964            ffi::init();
965            let c_str = CString::new(s.as_bytes()).unwrap();
966            let mut bn = ptr::null_mut();
967            cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?;
968            Ok(BigNum::from_ptr(bn))
969        }
970    }
971
972    /// Creates a `BigNum` from a hexadecimal string.
973    #[corresponds(BN_hex2bn)]
974    pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
975        unsafe {
976            ffi::init();
977            let c_str = CString::new(s.as_bytes()).unwrap();
978            let mut bn = ptr::null_mut();
979            cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?;
980            Ok(BigNum::from_ptr(bn))
981        }
982    }
983
984    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
985    /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
986    /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
987    ///
988    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
989    #[corresponds(BN_get_rfc2409_prime_768)]
990    #[cfg(not(boringssl))]
991    pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
992        unsafe {
993            ffi::init();
994            cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
995        }
996    }
997
998    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
999    /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
1000    /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
1001    ///
1002    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
1003    #[corresponds(BN_get_rfc2409_prime_1024)]
1004    #[cfg(not(boringssl))]
1005    pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
1006        unsafe {
1007            ffi::init();
1008            cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
1009        }
1010    }
1011
1012    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1013    /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
1014    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
1015    ///
1016    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1017    #[corresponds(BN_get_rfc3526_prime_1536)]
1018    #[cfg(not(boringssl))]
1019    pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
1020        unsafe {
1021            ffi::init();
1022            cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
1023        }
1024    }
1025
1026    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1027    /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
1028    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
1029    ///
1030    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1031    #[corresponds(BN_get_rfc3526_prime_2048)]
1032    #[cfg(not(boringssl))]
1033    pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
1034        unsafe {
1035            ffi::init();
1036            cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
1037        }
1038    }
1039
1040    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1041    /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
1042    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
1043    ///
1044    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1045    #[corresponds(BN_get_rfc3526_prime_3072)]
1046    #[cfg(not(boringssl))]
1047    pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
1048        unsafe {
1049            ffi::init();
1050            cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
1051        }
1052    }
1053
1054    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1055    /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
1056    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
1057    ///
1058    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1059    #[corresponds(BN_get_rfc3526_prime_4096)]
1060    #[cfg(not(boringssl))]
1061    pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
1062        unsafe {
1063            ffi::init();
1064            cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum)
1065        }
1066    }
1067
1068    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1069    /// of magnitude of `2 ^ 6144`.  This number is used during calculated key
1070    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 17.
1071    ///
1072    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1073    #[corresponds(BN_get_rfc3526_prime_6114)]
1074    #[cfg(not(boringssl))]
1075    pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
1076        unsafe {
1077            ffi::init();
1078            cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
1079        }
1080    }
1081
1082    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1083    /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
1084    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
1085    ///
1086    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1087    #[corresponds(BN_get_rfc3526_prime_8192)]
1088    #[cfg(not(boringssl))]
1089    pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
1090        unsafe {
1091            ffi::init();
1092            cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
1093        }
1094    }
1095
1096    /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
1097    ///
1098    /// OpenSSL documentation at [`BN_bin2bn`]
1099    ///
1100    /// [`BN_bin2bn`]: https://www.openssl.org/docs/manmaster/crypto/BN_bin2bn.html
1101    ///
1102    /// ```
1103    /// # use openssl::bn::BigNum;
1104    /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
1105    ///
1106    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1107    /// ```
1108    #[corresponds(BN_bin2bn)]
1109    pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
1110        unsafe {
1111            ffi::init();
1112            assert!(n.len() <= LenType::max_value() as usize);
1113
1114            cvt_p(ffi::BN_bin2bn(
1115                n.as_ptr(),
1116                n.len() as LenType,
1117                ptr::null_mut(),
1118            ))
1119            .map(|p| BigNum::from_ptr(p))
1120        }
1121    }
1122
1123    /// Copies data from a slice overwriting what was in the BigNum.
1124    ///
1125    /// This function can be used to copy data from a slice to a
1126    /// [secure BigNum][`BigNum::new_secure`].
1127    ///
1128    /// # Examples
1129    ///
1130    /// ```
1131    /// # use openssl::bn::BigNum;
1132    /// let mut bignum = BigNum::new().unwrap();
1133    /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
1134    ///
1135    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1136    /// ```
1137    #[corresponds(BN_bin2bn)]
1138    pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
1139        unsafe {
1140            assert!(n.len() <= LenType::max_value() as usize);
1141
1142            cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
1143            Ok(())
1144        }
1145    }
1146}
1147
1148impl fmt::Debug for BigNumRef {
1149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150        match self.to_dec_str() {
1151            Ok(s) => f.write_str(&s),
1152            Err(e) => Err(e.into()),
1153        }
1154    }
1155}
1156
1157impl fmt::Debug for BigNum {
1158    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1159        match self.to_dec_str() {
1160            Ok(s) => f.write_str(&s),
1161            Err(e) => Err(e.into()),
1162        }
1163    }
1164}
1165
1166impl fmt::Display for BigNumRef {
1167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1168        match self.to_dec_str() {
1169            Ok(s) => f.write_str(&s),
1170            Err(e) => Err(e.into()),
1171        }
1172    }
1173}
1174
1175impl fmt::Display for BigNum {
1176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1177        match self.to_dec_str() {
1178            Ok(s) => f.write_str(&s),
1179            Err(e) => Err(e.into()),
1180        }
1181    }
1182}
1183
1184impl PartialEq<BigNumRef> for BigNumRef {
1185    fn eq(&self, oth: &BigNumRef) -> bool {
1186        self.cmp(oth) == Ordering::Equal
1187    }
1188}
1189
1190impl PartialEq<BigNum> for BigNumRef {
1191    fn eq(&self, oth: &BigNum) -> bool {
1192        self.eq(oth.deref())
1193    }
1194}
1195
1196impl Eq for BigNumRef {}
1197
1198impl PartialEq for BigNum {
1199    fn eq(&self, oth: &BigNum) -> bool {
1200        self.deref().eq(oth)
1201    }
1202}
1203
1204impl PartialEq<BigNumRef> for BigNum {
1205    fn eq(&self, oth: &BigNumRef) -> bool {
1206        self.deref().eq(oth)
1207    }
1208}
1209
1210impl Eq for BigNum {}
1211
1212impl PartialOrd<BigNumRef> for BigNumRef {
1213    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1214        Some(self.cmp(oth))
1215    }
1216}
1217
1218impl PartialOrd<BigNum> for BigNumRef {
1219    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1220        Some(self.cmp(oth.deref()))
1221    }
1222}
1223
1224impl Ord for BigNumRef {
1225    fn cmp(&self, oth: &BigNumRef) -> Ordering {
1226        unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
1227    }
1228}
1229
1230impl PartialOrd for BigNum {
1231    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1232        self.deref().partial_cmp(oth.deref())
1233    }
1234}
1235
1236impl PartialOrd<BigNumRef> for BigNum {
1237    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1238        self.deref().partial_cmp(oth)
1239    }
1240}
1241
1242impl Ord for BigNum {
1243    fn cmp(&self, oth: &BigNum) -> Ordering {
1244        self.deref().cmp(oth.deref())
1245    }
1246}
1247
1248macro_rules! delegate {
1249    ($t:ident, $m:ident) => {
1250        impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
1251            type Output = BigNum;
1252
1253            fn $m(self, oth: &BigNum) -> BigNum {
1254                $t::$m(self, oth.deref())
1255            }
1256        }
1257
1258        impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
1259            type Output = BigNum;
1260
1261            fn $m(self, oth: &BigNumRef) -> BigNum {
1262                $t::$m(self.deref(), oth)
1263            }
1264        }
1265
1266        impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
1267            type Output = BigNum;
1268
1269            fn $m(self, oth: &BigNum) -> BigNum {
1270                $t::$m(self.deref(), oth.deref())
1271            }
1272        }
1273    };
1274}
1275
1276impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
1277    type Output = BigNum;
1278
1279    fn add(self, oth: &BigNumRef) -> BigNum {
1280        let mut r = BigNum::new().unwrap();
1281        r.checked_add(self, oth).unwrap();
1282        r
1283    }
1284}
1285
1286delegate!(Add, add);
1287
1288impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
1289    type Output = BigNum;
1290
1291    fn sub(self, oth: &BigNumRef) -> BigNum {
1292        let mut r = BigNum::new().unwrap();
1293        r.checked_sub(self, oth).unwrap();
1294        r
1295    }
1296}
1297
1298delegate!(Sub, sub);
1299
1300impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
1301    type Output = BigNum;
1302
1303    fn mul(self, oth: &BigNumRef) -> BigNum {
1304        let mut ctx = BigNumContext::new().unwrap();
1305        let mut r = BigNum::new().unwrap();
1306        r.checked_mul(self, oth, &mut ctx).unwrap();
1307        r
1308    }
1309}
1310
1311delegate!(Mul, mul);
1312
1313impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
1314    type Output = BigNum;
1315
1316    fn div(self, oth: &'b BigNumRef) -> BigNum {
1317        let mut ctx = BigNumContext::new().unwrap();
1318        let mut r = BigNum::new().unwrap();
1319        r.checked_div(self, oth, &mut ctx).unwrap();
1320        r
1321    }
1322}
1323
1324delegate!(Div, div);
1325
1326impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
1327    type Output = BigNum;
1328
1329    fn rem(self, oth: &'b BigNumRef) -> BigNum {
1330        let mut ctx = BigNumContext::new().unwrap();
1331        let mut r = BigNum::new().unwrap();
1332        r.checked_rem(self, oth, &mut ctx).unwrap();
1333        r
1334    }
1335}
1336
1337delegate!(Rem, rem);
1338
1339impl<'a> Shl<i32> for &'a BigNumRef {
1340    type Output = BigNum;
1341
1342    fn shl(self, n: i32) -> BigNum {
1343        let mut r = BigNum::new().unwrap();
1344        r.lshift(self, n).unwrap();
1345        r
1346    }
1347}
1348
1349impl<'a> Shl<i32> for &'a BigNum {
1350    type Output = BigNum;
1351
1352    fn shl(self, n: i32) -> BigNum {
1353        self.deref().shl(n)
1354    }
1355}
1356
1357impl<'a> Shr<i32> for &'a BigNumRef {
1358    type Output = BigNum;
1359
1360    fn shr(self, n: i32) -> BigNum {
1361        let mut r = BigNum::new().unwrap();
1362        r.rshift(self, n).unwrap();
1363        r
1364    }
1365}
1366
1367impl<'a> Shr<i32> for &'a BigNum {
1368    type Output = BigNum;
1369
1370    fn shr(self, n: i32) -> BigNum {
1371        self.deref().shr(n)
1372    }
1373}
1374
1375impl<'a> Neg for &'a BigNumRef {
1376    type Output = BigNum;
1377
1378    fn neg(self) -> BigNum {
1379        self.to_owned().unwrap().neg()
1380    }
1381}
1382
1383impl<'a> Neg for &'a BigNum {
1384    type Output = BigNum;
1385
1386    fn neg(self) -> BigNum {
1387        self.deref().neg()
1388    }
1389}
1390
1391impl Neg for BigNum {
1392    type Output = BigNum;
1393
1394    fn neg(mut self) -> BigNum {
1395        let negative = self.is_negative();
1396        self.set_negative(!negative);
1397        self
1398    }
1399}
1400
1401#[cfg(test)]
1402mod tests {
1403    use crate::bn::{BigNum, BigNumContext};
1404
1405    #[test]
1406    fn test_to_from_slice() {
1407        let v0 = BigNum::from_u32(10_203_004).unwrap();
1408        let vec = v0.to_vec();
1409        let v1 = BigNum::from_slice(&vec).unwrap();
1410
1411        assert_eq!(v0, v1);
1412    }
1413
1414    #[test]
1415    fn test_negation() {
1416        let a = BigNum::from_u32(909_829_283).unwrap();
1417
1418        assert!(!a.is_negative());
1419        assert!((-a).is_negative());
1420    }
1421
1422    #[test]
1423    fn test_shift() {
1424        let a = BigNum::from_u32(909_829_283).unwrap();
1425
1426        assert_eq!(a, &(&a << 1) >> 1);
1427    }
1428
1429    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1430    #[test]
1431    fn test_rand_range() {
1432        let range = BigNum::from_u32(909_829_283).unwrap();
1433        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1434        range.rand_range(&mut result).unwrap();
1435        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1436    }
1437
1438    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1439    #[test]
1440    fn test_pseudo_rand_range() {
1441        let range = BigNum::from_u32(909_829_283).unwrap();
1442        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1443        range.pseudo_rand_range(&mut result).unwrap();
1444        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1445    }
1446
1447    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1448    #[test]
1449    fn test_prime_numbers() {
1450        let a = BigNum::from_u32(19_029_017).unwrap();
1451        let mut p = BigNum::new().unwrap();
1452        p.generate_prime(128, true, None, Some(&a)).unwrap();
1453
1454        let mut ctx = BigNumContext::new().unwrap();
1455        assert!(p.is_prime(100, &mut ctx).unwrap());
1456        assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
1457    }
1458
1459    #[cfg(ossl110)]
1460    #[test]
1461    fn test_secure_bn_ctx() {
1462        let mut cxt = BigNumContext::new_secure().unwrap();
1463        let a = BigNum::from_u32(8).unwrap();
1464        let b = BigNum::from_u32(3).unwrap();
1465
1466        let mut remainder = BigNum::new().unwrap();
1467        remainder.nnmod(&a, &b, &mut cxt).unwrap();
1468
1469        assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
1470    }
1471
1472    #[cfg(ossl110)]
1473    #[test]
1474    fn test_secure_bn() {
1475        let a = BigNum::new().unwrap();
1476        assert!(!a.is_secure());
1477
1478        let b = BigNum::new_secure().unwrap();
1479        assert!(b.is_secure())
1480    }
1481
1482    #[cfg(ossl110)]
1483    #[test]
1484    fn test_const_time_bn() {
1485        let a = BigNum::new().unwrap();
1486        assert!(!a.is_const_time());
1487
1488        let mut b = BigNum::new().unwrap();
1489        b.set_const_time();
1490        assert!(b.is_const_time())
1491    }
1492
1493    #[cfg(ossl110)]
1494    #[test]
1495    fn test_mod_sqrt() {
1496        let mut ctx = BigNumContext::new().unwrap();
1497
1498        let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap();
1499        let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap();
1500        let mut out = BigNum::new().unwrap();
1501
1502        out.mod_sqrt(&s, &p, &mut ctx).unwrap();
1503        assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap());
1504    }
1505
1506    #[test]
1507    #[cfg(any(ossl110, boringssl, libressl350))]
1508    fn test_odd_even() {
1509        let a = BigNum::from_u32(17).unwrap();
1510        let b = BigNum::from_u32(18).unwrap();
1511
1512        assert!(a.is_odd());
1513        assert!(!b.is_odd());
1514
1515        assert!(!a.is_even());
1516        assert!(b.is_even());
1517    }
1518}
1519