192f3ab15Sopenharmony_ci//! BigNum implementation
292f3ab15Sopenharmony_ci//!
392f3ab15Sopenharmony_ci//! Large numbers are important for a cryptographic library.  OpenSSL implementation
492f3ab15Sopenharmony_ci//! of BigNum uses dynamically assigned memory to store an array of bit chunks.  This
592f3ab15Sopenharmony_ci//! allows numbers of any size to be compared and mathematical functions performed.
692f3ab15Sopenharmony_ci//!
792f3ab15Sopenharmony_ci//! OpenSSL wiki describes the [`BIGNUM`] data structure.
892f3ab15Sopenharmony_ci//!
992f3ab15Sopenharmony_ci//! # Examples
1092f3ab15Sopenharmony_ci//!
1192f3ab15Sopenharmony_ci//! ```
1292f3ab15Sopenharmony_ci//! use openssl::bn::BigNum;
1392f3ab15Sopenharmony_ci//! use openssl::error::ErrorStack;
1492f3ab15Sopenharmony_ci//!
1592f3ab15Sopenharmony_ci//! fn main() -> Result<(), ErrorStack> {
1692f3ab15Sopenharmony_ci//!   let a = BigNum::new()?; // a = 0
1792f3ab15Sopenharmony_ci//!   let b = BigNum::from_dec_str("1234567890123456789012345")?;
1892f3ab15Sopenharmony_ci//!   let c = &a * &b;
1992f3ab15Sopenharmony_ci//!   assert_eq!(a, c);
2092f3ab15Sopenharmony_ci//!   Ok(())
2192f3ab15Sopenharmony_ci//! }
2292f3ab15Sopenharmony_ci//! ```
2392f3ab15Sopenharmony_ci//!
2492f3ab15Sopenharmony_ci//! [`BIGNUM`]: https://wiki.openssl.org/index.php/Manual:Bn_internal(3)
2592f3ab15Sopenharmony_ciuse cfg_if::cfg_if;
2692f3ab15Sopenharmony_ciuse foreign_types::{ForeignType, ForeignTypeRef};
2792f3ab15Sopenharmony_ciuse libc::c_int;
2892f3ab15Sopenharmony_ciuse std::cmp::Ordering;
2992f3ab15Sopenharmony_ciuse std::ffi::CString;
3092f3ab15Sopenharmony_ciuse std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub};
3192f3ab15Sopenharmony_ciuse std::{fmt, ptr};
3292f3ab15Sopenharmony_ci
3392f3ab15Sopenharmony_ciuse crate::asn1::Asn1Integer;
3492f3ab15Sopenharmony_ciuse crate::error::ErrorStack;
3592f3ab15Sopenharmony_ciuse crate::string::OpensslString;
3692f3ab15Sopenharmony_ciuse crate::{cvt, cvt_n, cvt_p, LenType};
3792f3ab15Sopenharmony_ciuse openssl_macros::corresponds;
3892f3ab15Sopenharmony_ci
3992f3ab15Sopenharmony_cicfg_if! {
4092f3ab15Sopenharmony_ci    if #[cfg(any(ossl110, libressl350))] {
4192f3ab15Sopenharmony_ci        use ffi::{
4292f3ab15Sopenharmony_ci            BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536,
4392f3ab15Sopenharmony_ci            BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096,
4492f3ab15Sopenharmony_ci            BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative,
4592f3ab15Sopenharmony_ci        };
4692f3ab15Sopenharmony_ci    } else if #[cfg(boringssl)] {
4792f3ab15Sopenharmony_ci        use ffi::BN_is_negative;
4892f3ab15Sopenharmony_ci    } else {
4992f3ab15Sopenharmony_ci        use ffi::{
5092f3ab15Sopenharmony_ci            get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024,
5192f3ab15Sopenharmony_ci            get_rfc2409_prime_768 as BN_get_rfc2409_prime_768,
5292f3ab15Sopenharmony_ci            get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536,
5392f3ab15Sopenharmony_ci            get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048,
5492f3ab15Sopenharmony_ci            get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072,
5592f3ab15Sopenharmony_ci            get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096,
5692f3ab15Sopenharmony_ci            get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144,
5792f3ab15Sopenharmony_ci            get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192,
5892f3ab15Sopenharmony_ci        };
5992f3ab15Sopenharmony_ci
6092f3ab15Sopenharmony_ci        #[allow(bad_style)]
6192f3ab15Sopenharmony_ci        unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int {
6292f3ab15Sopenharmony_ci            (*bn).neg
6392f3ab15Sopenharmony_ci        }
6492f3ab15Sopenharmony_ci    }
6592f3ab15Sopenharmony_ci}
6692f3ab15Sopenharmony_ci
6792f3ab15Sopenharmony_ci/// Options for the most significant bits of a randomly generated `BigNum`.
6892f3ab15Sopenharmony_cipub struct MsbOption(c_int);
6992f3ab15Sopenharmony_ci
7092f3ab15Sopenharmony_ciimpl MsbOption {
7192f3ab15Sopenharmony_ci    /// The most significant bit of the number may be 0.
7292f3ab15Sopenharmony_ci    pub const MAYBE_ZERO: MsbOption = MsbOption(-1);
7392f3ab15Sopenharmony_ci
7492f3ab15Sopenharmony_ci    /// The most significant bit of the number must be 1.
7592f3ab15Sopenharmony_ci    pub const ONE: MsbOption = MsbOption(0);
7692f3ab15Sopenharmony_ci
7792f3ab15Sopenharmony_ci    /// The most significant two bits of the number must be 1.
7892f3ab15Sopenharmony_ci    ///
7992f3ab15Sopenharmony_ci    /// The number of bits in the product of two such numbers will always be exactly twice the
8092f3ab15Sopenharmony_ci    /// number of bits in the original numbers.
8192f3ab15Sopenharmony_ci    pub const TWO_ONES: MsbOption = MsbOption(1);
8292f3ab15Sopenharmony_ci}
8392f3ab15Sopenharmony_ci
8492f3ab15Sopenharmony_ciforeign_type_and_impl_send_sync! {
8592f3ab15Sopenharmony_ci    type CType = ffi::BN_CTX;
8692f3ab15Sopenharmony_ci    fn drop = ffi::BN_CTX_free;
8792f3ab15Sopenharmony_ci
8892f3ab15Sopenharmony_ci    /// Temporary storage for BigNums on the secure heap
8992f3ab15Sopenharmony_ci    ///
9092f3ab15Sopenharmony_ci    /// BigNum values are stored dynamically and therefore can be expensive
9192f3ab15Sopenharmony_ci    /// to allocate.  BigNumContext and the OpenSSL [`BN_CTX`] structure are used
9292f3ab15Sopenharmony_ci    /// internally when passing BigNum values between subroutines.
9392f3ab15Sopenharmony_ci    ///
9492f3ab15Sopenharmony_ci    /// [`BN_CTX`]: https://www.openssl.org/docs/manmaster/crypto/BN_CTX_new.html
9592f3ab15Sopenharmony_ci    pub struct BigNumContext;
9692f3ab15Sopenharmony_ci    /// Reference to [`BigNumContext`]
9792f3ab15Sopenharmony_ci    ///
9892f3ab15Sopenharmony_ci    /// [`BigNumContext`]: struct.BigNumContext.html
9992f3ab15Sopenharmony_ci    pub struct BigNumContextRef;
10092f3ab15Sopenharmony_ci}
10192f3ab15Sopenharmony_ci
10292f3ab15Sopenharmony_ciimpl BigNumContext {
10392f3ab15Sopenharmony_ci    /// Returns a new `BigNumContext`.
10492f3ab15Sopenharmony_ci    #[corresponds(BN_CTX_new)]
10592f3ab15Sopenharmony_ci    pub fn new() -> Result<BigNumContext, ErrorStack> {
10692f3ab15Sopenharmony_ci        unsafe {
10792f3ab15Sopenharmony_ci            ffi::init();
10892f3ab15Sopenharmony_ci            cvt_p(ffi::BN_CTX_new()).map(BigNumContext)
10992f3ab15Sopenharmony_ci        }
11092f3ab15Sopenharmony_ci    }
11192f3ab15Sopenharmony_ci
11292f3ab15Sopenharmony_ci    /// Returns a new secure `BigNumContext`.
11392f3ab15Sopenharmony_ci    #[corresponds(BN_CTX_secure_new)]
11492f3ab15Sopenharmony_ci    #[cfg(ossl110)]
11592f3ab15Sopenharmony_ci    pub fn new_secure() -> Result<BigNumContext, ErrorStack> {
11692f3ab15Sopenharmony_ci        unsafe {
11792f3ab15Sopenharmony_ci            ffi::init();
11892f3ab15Sopenharmony_ci            cvt_p(ffi::BN_CTX_secure_new()).map(BigNumContext)
11992f3ab15Sopenharmony_ci        }
12092f3ab15Sopenharmony_ci    }
12192f3ab15Sopenharmony_ci}
12292f3ab15Sopenharmony_ci
12392f3ab15Sopenharmony_ciforeign_type_and_impl_send_sync! {
12492f3ab15Sopenharmony_ci    type CType = ffi::BIGNUM;
12592f3ab15Sopenharmony_ci    fn drop = ffi::BN_free;
12692f3ab15Sopenharmony_ci
12792f3ab15Sopenharmony_ci    /// Dynamically sized large number implementation
12892f3ab15Sopenharmony_ci    ///
12992f3ab15Sopenharmony_ci    /// Perform large number mathematics.  Create a new BigNum
13092f3ab15Sopenharmony_ci    /// with [`new`].  Perform standard mathematics on large numbers using
13192f3ab15Sopenharmony_ci    /// methods from [`Dref<Target = BigNumRef>`]
13292f3ab15Sopenharmony_ci    ///
13392f3ab15Sopenharmony_ci    /// OpenSSL documentation at [`BN_new`].
13492f3ab15Sopenharmony_ci    ///
13592f3ab15Sopenharmony_ci    /// [`new`]: struct.BigNum.html#method.new
13692f3ab15Sopenharmony_ci    /// [`Dref<Target = BigNumRef>`]: struct.BigNum.html#deref-methods
13792f3ab15Sopenharmony_ci    /// [`BN_new`]: https://www.openssl.org/docs/manmaster/crypto/BN_new.html
13892f3ab15Sopenharmony_ci    ///
13992f3ab15Sopenharmony_ci    /// # Examples
14092f3ab15Sopenharmony_ci    /// ```
14192f3ab15Sopenharmony_ci    /// use openssl::bn::BigNum;
14292f3ab15Sopenharmony_ci    /// # use openssl::error::ErrorStack;
14392f3ab15Sopenharmony_ci    /// # fn bignums() -> Result< (), ErrorStack > {
14492f3ab15Sopenharmony_ci    /// let little_big = BigNum::from_u32(std::u32::MAX)?;
14592f3ab15Sopenharmony_ci    /// assert_eq!(*&little_big.num_bytes(), 4);
14692f3ab15Sopenharmony_ci    /// # Ok(())
14792f3ab15Sopenharmony_ci    /// # }
14892f3ab15Sopenharmony_ci    /// # fn main () { bignums(); }
14992f3ab15Sopenharmony_ci    /// ```
15092f3ab15Sopenharmony_ci    pub struct BigNum;
15192f3ab15Sopenharmony_ci    /// Reference to a [`BigNum`]
15292f3ab15Sopenharmony_ci    ///
15392f3ab15Sopenharmony_ci    /// [`BigNum`]: struct.BigNum.html
15492f3ab15Sopenharmony_ci    pub struct BigNumRef;
15592f3ab15Sopenharmony_ci}
15692f3ab15Sopenharmony_ci
15792f3ab15Sopenharmony_ciimpl BigNumRef {
15892f3ab15Sopenharmony_ci    /// Erases the memory used by this `BigNum`, resetting its value to 0.
15992f3ab15Sopenharmony_ci    ///
16092f3ab15Sopenharmony_ci    /// This can be used to destroy sensitive data such as keys when they are no longer needed.
16192f3ab15Sopenharmony_ci    #[corresponds(BN_clear)]
16292f3ab15Sopenharmony_ci    pub fn clear(&mut self) {
16392f3ab15Sopenharmony_ci        unsafe { ffi::BN_clear(self.as_ptr()) }
16492f3ab15Sopenharmony_ci    }
16592f3ab15Sopenharmony_ci
16692f3ab15Sopenharmony_ci    /// Adds a `u32` to `self`.
16792f3ab15Sopenharmony_ci    #[corresponds(BN_add_word)]
16892f3ab15Sopenharmony_ci    pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> {
16992f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
17092f3ab15Sopenharmony_ci    }
17192f3ab15Sopenharmony_ci
17292f3ab15Sopenharmony_ci    /// Subtracts a `u32` from `self`.
17392f3ab15Sopenharmony_ci    #[corresponds(BN_sub_word)]
17492f3ab15Sopenharmony_ci    pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> {
17592f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
17692f3ab15Sopenharmony_ci    }
17792f3ab15Sopenharmony_ci
17892f3ab15Sopenharmony_ci    /// Multiplies a `u32` by `self`.
17992f3ab15Sopenharmony_ci    #[corresponds(BN_mul_word)]
18092f3ab15Sopenharmony_ci    pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> {
18192f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
18292f3ab15Sopenharmony_ci    }
18392f3ab15Sopenharmony_ci
18492f3ab15Sopenharmony_ci    /// Divides `self` by a `u32`, returning the remainder.
18592f3ab15Sopenharmony_ci    #[corresponds(BN_div_word)]
18692f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
18792f3ab15Sopenharmony_ci    pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
18892f3ab15Sopenharmony_ci        unsafe {
18992f3ab15Sopenharmony_ci            let r = ffi::BN_div_word(self.as_ptr(), w.into());
19092f3ab15Sopenharmony_ci            if r == ffi::BN_ULONG::max_value() {
19192f3ab15Sopenharmony_ci                Err(ErrorStack::get())
19292f3ab15Sopenharmony_ci            } else {
19392f3ab15Sopenharmony_ci                Ok(r.into())
19492f3ab15Sopenharmony_ci            }
19592f3ab15Sopenharmony_ci        }
19692f3ab15Sopenharmony_ci    }
19792f3ab15Sopenharmony_ci
19892f3ab15Sopenharmony_ci    /// Returns the result of `self` modulo `w`.
19992f3ab15Sopenharmony_ci    #[corresponds(BN_mod_word)]
20092f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
20192f3ab15Sopenharmony_ci    pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
20292f3ab15Sopenharmony_ci        unsafe {
20392f3ab15Sopenharmony_ci            let r = ffi::BN_mod_word(self.as_ptr(), w.into());
20492f3ab15Sopenharmony_ci            if r == ffi::BN_ULONG::max_value() {
20592f3ab15Sopenharmony_ci                Err(ErrorStack::get())
20692f3ab15Sopenharmony_ci            } else {
20792f3ab15Sopenharmony_ci                Ok(r.into())
20892f3ab15Sopenharmony_ci            }
20992f3ab15Sopenharmony_ci        }
21092f3ab15Sopenharmony_ci    }
21192f3ab15Sopenharmony_ci
21292f3ab15Sopenharmony_ci    /// Places a cryptographically-secure pseudo-random nonnegative
21392f3ab15Sopenharmony_ci    /// number less than `self` in `rnd`.
21492f3ab15Sopenharmony_ci    #[corresponds(BN_rand_range)]
21592f3ab15Sopenharmony_ci    pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
21692f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
21792f3ab15Sopenharmony_ci    }
21892f3ab15Sopenharmony_ci
21992f3ab15Sopenharmony_ci    /// The cryptographically weak counterpart to `rand_in_range`.
22092f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
22192f3ab15Sopenharmony_ci    #[corresponds(BN_pseudo_rand_range)]
22292f3ab15Sopenharmony_ci    pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
22392f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
22492f3ab15Sopenharmony_ci    }
22592f3ab15Sopenharmony_ci
22692f3ab15Sopenharmony_ci    /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
22792f3ab15Sopenharmony_ci    ///
22892f3ab15Sopenharmony_ci    /// When setting a bit outside of `self`, it is expanded.
22992f3ab15Sopenharmony_ci    #[corresponds(BN_set_bit)]
23092f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
23192f3ab15Sopenharmony_ci    pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
23292f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
23392f3ab15Sopenharmony_ci    }
23492f3ab15Sopenharmony_ci
23592f3ab15Sopenharmony_ci    /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
23692f3ab15Sopenharmony_ci    ///
23792f3ab15Sopenharmony_ci    /// When clearing a bit outside of `self`, an error is returned.
23892f3ab15Sopenharmony_ci    #[corresponds(BN_clear_bit)]
23992f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
24092f3ab15Sopenharmony_ci    pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
24192f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
24292f3ab15Sopenharmony_ci    }
24392f3ab15Sopenharmony_ci
24492f3ab15Sopenharmony_ci    /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise.
24592f3ab15Sopenharmony_ci    #[corresponds(BN_is_bit_set)]
24692f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
24792f3ab15Sopenharmony_ci    pub fn is_bit_set(&self, n: i32) -> bool {
24892f3ab15Sopenharmony_ci        unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
24992f3ab15Sopenharmony_ci    }
25092f3ab15Sopenharmony_ci
25192f3ab15Sopenharmony_ci    /// Truncates `self` to the lowest `n` bits.
25292f3ab15Sopenharmony_ci    ///
25392f3ab15Sopenharmony_ci    /// An error occurs if `self` is already shorter than `n` bits.
25492f3ab15Sopenharmony_ci    #[corresponds(BN_mask_bits)]
25592f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
25692f3ab15Sopenharmony_ci    pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
25792f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
25892f3ab15Sopenharmony_ci    }
25992f3ab15Sopenharmony_ci
26092f3ab15Sopenharmony_ci    /// Places `a << 1` in `self`.  Equivalent to `self * 2`.
26192f3ab15Sopenharmony_ci    #[corresponds(BN_lshift1)]
26292f3ab15Sopenharmony_ci    pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
26392f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
26492f3ab15Sopenharmony_ci    }
26592f3ab15Sopenharmony_ci
26692f3ab15Sopenharmony_ci    /// Places `a >> 1` in `self`. Equivalent to `self / 2`.
26792f3ab15Sopenharmony_ci    #[corresponds(BN_rshift1)]
26892f3ab15Sopenharmony_ci    pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> {
26992f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
27092f3ab15Sopenharmony_ci    }
27192f3ab15Sopenharmony_ci
27292f3ab15Sopenharmony_ci    /// Places `a + b` in `self`.  [`core::ops::Add`] is also implemented for `BigNumRef`.
27392f3ab15Sopenharmony_ci    ///
27492f3ab15Sopenharmony_ci    /// [`core::ops::Add`]: struct.BigNumRef.html#method.add
27592f3ab15Sopenharmony_ci    #[corresponds(BN_add)]
27692f3ab15Sopenharmony_ci    pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
27792f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
27892f3ab15Sopenharmony_ci    }
27992f3ab15Sopenharmony_ci
28092f3ab15Sopenharmony_ci    /// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`.
28192f3ab15Sopenharmony_ci    ///
28292f3ab15Sopenharmony_ci    /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub
28392f3ab15Sopenharmony_ci    #[corresponds(BN_sub)]
28492f3ab15Sopenharmony_ci    pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
28592f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
28692f3ab15Sopenharmony_ci    }
28792f3ab15Sopenharmony_ci
28892f3ab15Sopenharmony_ci    /// Places `a << n` in `self`.  Equivalent to `a * 2 ^ n`.
28992f3ab15Sopenharmony_ci    #[corresponds(BN_lshift)]
29092f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
29192f3ab15Sopenharmony_ci    pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
29292f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
29392f3ab15Sopenharmony_ci    }
29492f3ab15Sopenharmony_ci
29592f3ab15Sopenharmony_ci    /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`.
29692f3ab15Sopenharmony_ci    #[corresponds(BN_rshift)]
29792f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
29892f3ab15Sopenharmony_ci    pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> {
29992f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
30092f3ab15Sopenharmony_ci    }
30192f3ab15Sopenharmony_ci
30292f3ab15Sopenharmony_ci    /// Creates a new BigNum with the same value.
30392f3ab15Sopenharmony_ci    #[corresponds(BN_dup)]
30492f3ab15Sopenharmony_ci    pub fn to_owned(&self) -> Result<BigNum, ErrorStack> {
30592f3ab15Sopenharmony_ci        unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
30692f3ab15Sopenharmony_ci    }
30792f3ab15Sopenharmony_ci
30892f3ab15Sopenharmony_ci    /// Sets the sign of `self`.  Pass true to set `self` to a negative.  False sets
30992f3ab15Sopenharmony_ci    /// `self` positive.
31092f3ab15Sopenharmony_ci    #[corresponds(BN_set_negative)]
31192f3ab15Sopenharmony_ci    pub fn set_negative(&mut self, negative: bool) {
31292f3ab15Sopenharmony_ci        unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
31392f3ab15Sopenharmony_ci    }
31492f3ab15Sopenharmony_ci
31592f3ab15Sopenharmony_ci    /// Compare the absolute values of `self` and `oth`.
31692f3ab15Sopenharmony_ci    ///
31792f3ab15Sopenharmony_ci    /// # Examples
31892f3ab15Sopenharmony_ci    ///
31992f3ab15Sopenharmony_ci    /// ```
32092f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
32192f3ab15Sopenharmony_ci    /// # use std::cmp::Ordering;
32292f3ab15Sopenharmony_ci    /// let s = -BigNum::from_u32(8).unwrap();
32392f3ab15Sopenharmony_ci    /// let o = BigNum::from_u32(8).unwrap();
32492f3ab15Sopenharmony_ci    ///
32592f3ab15Sopenharmony_ci    /// assert_eq!(s.ucmp(&o), Ordering::Equal);
32692f3ab15Sopenharmony_ci    /// ```
32792f3ab15Sopenharmony_ci    #[corresponds(BN_ucmp)]
32892f3ab15Sopenharmony_ci    pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
32992f3ab15Sopenharmony_ci        unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
33092f3ab15Sopenharmony_ci    }
33192f3ab15Sopenharmony_ci
33292f3ab15Sopenharmony_ci    /// Returns `true` if `self` is negative.
33392f3ab15Sopenharmony_ci    #[corresponds(BN_is_negative)]
33492f3ab15Sopenharmony_ci    pub fn is_negative(&self) -> bool {
33592f3ab15Sopenharmony_ci        unsafe { BN_is_negative(self.as_ptr()) == 1 }
33692f3ab15Sopenharmony_ci    }
33792f3ab15Sopenharmony_ci
33892f3ab15Sopenharmony_ci    /// Returns `true` is `self` is even.
33992f3ab15Sopenharmony_ci    #[corresponds(BN_is_even)]
34092f3ab15Sopenharmony_ci    #[cfg(any(ossl110, boringssl, libressl350))]
34192f3ab15Sopenharmony_ci    pub fn is_even(&self) -> bool {
34292f3ab15Sopenharmony_ci        !self.is_odd()
34392f3ab15Sopenharmony_ci    }
34492f3ab15Sopenharmony_ci
34592f3ab15Sopenharmony_ci    /// Returns `true` is `self` is odd.
34692f3ab15Sopenharmony_ci    #[corresponds(BN_is_odd)]
34792f3ab15Sopenharmony_ci    #[cfg(any(ossl110, boringssl, libressl350))]
34892f3ab15Sopenharmony_ci    pub fn is_odd(&self) -> bool {
34992f3ab15Sopenharmony_ci        unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 }
35092f3ab15Sopenharmony_ci    }
35192f3ab15Sopenharmony_ci
35292f3ab15Sopenharmony_ci    /// Returns the number of significant bits in `self`.
35392f3ab15Sopenharmony_ci    #[corresponds(BN_num_bits)]
35492f3ab15Sopenharmony_ci    #[allow(clippy::unnecessary_cast)]
35592f3ab15Sopenharmony_ci    pub fn num_bits(&self) -> i32 {
35692f3ab15Sopenharmony_ci        unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
35792f3ab15Sopenharmony_ci    }
35892f3ab15Sopenharmony_ci
35992f3ab15Sopenharmony_ci    /// Returns the size of `self` in bytes. Implemented natively.
36092f3ab15Sopenharmony_ci    pub fn num_bytes(&self) -> i32 {
36192f3ab15Sopenharmony_ci        (self.num_bits() + 7) / 8
36292f3ab15Sopenharmony_ci    }
36392f3ab15Sopenharmony_ci
36492f3ab15Sopenharmony_ci    /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
36592f3ab15Sopenharmony_ci    ///
36692f3ab15Sopenharmony_ci    /// # Parameters
36792f3ab15Sopenharmony_ci    ///
36892f3ab15Sopenharmony_ci    /// * `bits`: Length of the number in bits.
36992f3ab15Sopenharmony_ci    /// * `msb`: The desired properties of the most significant bit. See [`constants`].
37092f3ab15Sopenharmony_ci    /// * `odd`: If `true`, the generated number will be odd.
37192f3ab15Sopenharmony_ci    ///
37292f3ab15Sopenharmony_ci    /// # Examples
37392f3ab15Sopenharmony_ci    ///
37492f3ab15Sopenharmony_ci    /// ```
37592f3ab15Sopenharmony_ci    /// use openssl::bn::{BigNum, MsbOption};
37692f3ab15Sopenharmony_ci    /// use openssl::error::ErrorStack;
37792f3ab15Sopenharmony_ci    ///
37892f3ab15Sopenharmony_ci    /// fn generate_random() -> Result< BigNum, ErrorStack > {
37992f3ab15Sopenharmony_ci    ///    let mut big = BigNum::new()?;
38092f3ab15Sopenharmony_ci    ///
38192f3ab15Sopenharmony_ci    ///    // Generates a 128-bit odd random number
38292f3ab15Sopenharmony_ci    ///    big.rand(128, MsbOption::MAYBE_ZERO, true);
38392f3ab15Sopenharmony_ci    ///    Ok((big))
38492f3ab15Sopenharmony_ci    /// }
38592f3ab15Sopenharmony_ci    /// ```
38692f3ab15Sopenharmony_ci    ///
38792f3ab15Sopenharmony_ci    /// [`constants`]: index.html#constants
38892f3ab15Sopenharmony_ci    #[corresponds(BN_rand)]
38992f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
39092f3ab15Sopenharmony_ci    pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
39192f3ab15Sopenharmony_ci        unsafe {
39292f3ab15Sopenharmony_ci            cvt(ffi::BN_rand(
39392f3ab15Sopenharmony_ci                self.as_ptr(),
39492f3ab15Sopenharmony_ci                bits.into(),
39592f3ab15Sopenharmony_ci                msb.0,
39692f3ab15Sopenharmony_ci                odd as c_int,
39792f3ab15Sopenharmony_ci            ))
39892f3ab15Sopenharmony_ci            .map(|_| ())
39992f3ab15Sopenharmony_ci        }
40092f3ab15Sopenharmony_ci    }
40192f3ab15Sopenharmony_ci
40292f3ab15Sopenharmony_ci    /// The cryptographically weak counterpart to `rand`.  Not suitable for key generation.
40392f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
40492f3ab15Sopenharmony_ci    #[corresponds(BN_pseudo_rand)]
40592f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
40692f3ab15Sopenharmony_ci    pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
40792f3ab15Sopenharmony_ci        unsafe {
40892f3ab15Sopenharmony_ci            cvt(ffi::BN_pseudo_rand(
40992f3ab15Sopenharmony_ci                self.as_ptr(),
41092f3ab15Sopenharmony_ci                bits.into(),
41192f3ab15Sopenharmony_ci                msb.0,
41292f3ab15Sopenharmony_ci                odd as c_int,
41392f3ab15Sopenharmony_ci            ))
41492f3ab15Sopenharmony_ci            .map(|_| ())
41592f3ab15Sopenharmony_ci        }
41692f3ab15Sopenharmony_ci    }
41792f3ab15Sopenharmony_ci
41892f3ab15Sopenharmony_ci    /// Generates a prime number, placing it in `self`.
41992f3ab15Sopenharmony_ci    ///
42092f3ab15Sopenharmony_ci    /// # Parameters
42192f3ab15Sopenharmony_ci    ///
42292f3ab15Sopenharmony_ci    /// * `bits`: The length of the prime in bits (lower bound).
42392f3ab15Sopenharmony_ci    /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
42492f3ab15Sopenharmony_ci    /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
42592f3ab15Sopenharmony_ci    ///   generated prime and `rem` is `1` if not specified (`None`).
42692f3ab15Sopenharmony_ci    ///
42792f3ab15Sopenharmony_ci    /// # Examples
42892f3ab15Sopenharmony_ci    ///
42992f3ab15Sopenharmony_ci    /// ```
43092f3ab15Sopenharmony_ci    /// use openssl::bn::BigNum;
43192f3ab15Sopenharmony_ci    /// use openssl::error::ErrorStack;
43292f3ab15Sopenharmony_ci    ///
43392f3ab15Sopenharmony_ci    /// fn generate_weak_prime() -> Result< BigNum, ErrorStack > {
43492f3ab15Sopenharmony_ci    ///    let mut big = BigNum::new()?;
43592f3ab15Sopenharmony_ci    ///
43692f3ab15Sopenharmony_ci    ///    // Generates a 128-bit simple prime number
43792f3ab15Sopenharmony_ci    ///    big.generate_prime(128, false, None, None);
43892f3ab15Sopenharmony_ci    ///    Ok((big))
43992f3ab15Sopenharmony_ci    /// }
44092f3ab15Sopenharmony_ci    /// ```
44192f3ab15Sopenharmony_ci    #[corresponds(BN_generate_prime_ex)]
44292f3ab15Sopenharmony_ci    pub fn generate_prime(
44392f3ab15Sopenharmony_ci        &mut self,
44492f3ab15Sopenharmony_ci        bits: i32,
44592f3ab15Sopenharmony_ci        safe: bool,
44692f3ab15Sopenharmony_ci        add: Option<&BigNumRef>,
44792f3ab15Sopenharmony_ci        rem: Option<&BigNumRef>,
44892f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
44992f3ab15Sopenharmony_ci        unsafe {
45092f3ab15Sopenharmony_ci            cvt(ffi::BN_generate_prime_ex(
45192f3ab15Sopenharmony_ci                self.as_ptr(),
45292f3ab15Sopenharmony_ci                bits as c_int,
45392f3ab15Sopenharmony_ci                safe as c_int,
45492f3ab15Sopenharmony_ci                add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
45592f3ab15Sopenharmony_ci                rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
45692f3ab15Sopenharmony_ci                ptr::null_mut(),
45792f3ab15Sopenharmony_ci            ))
45892f3ab15Sopenharmony_ci            .map(|_| ())
45992f3ab15Sopenharmony_ci        }
46092f3ab15Sopenharmony_ci    }
46192f3ab15Sopenharmony_ci
46292f3ab15Sopenharmony_ci    /// Places the result of `a * b` in `self`.
46392f3ab15Sopenharmony_ci    /// [`core::ops::Mul`] is also implemented for `BigNumRef`.
46492f3ab15Sopenharmony_ci    ///
46592f3ab15Sopenharmony_ci    /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul
46692f3ab15Sopenharmony_ci    #[corresponds(BN_mul)]
46792f3ab15Sopenharmony_ci    pub fn checked_mul(
46892f3ab15Sopenharmony_ci        &mut self,
46992f3ab15Sopenharmony_ci        a: &BigNumRef,
47092f3ab15Sopenharmony_ci        b: &BigNumRef,
47192f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
47292f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
47392f3ab15Sopenharmony_ci        unsafe {
47492f3ab15Sopenharmony_ci            cvt(ffi::BN_mul(
47592f3ab15Sopenharmony_ci                self.as_ptr(),
47692f3ab15Sopenharmony_ci                a.as_ptr(),
47792f3ab15Sopenharmony_ci                b.as_ptr(),
47892f3ab15Sopenharmony_ci                ctx.as_ptr(),
47992f3ab15Sopenharmony_ci            ))
48092f3ab15Sopenharmony_ci            .map(|_| ())
48192f3ab15Sopenharmony_ci        }
48292f3ab15Sopenharmony_ci    }
48392f3ab15Sopenharmony_ci
48492f3ab15Sopenharmony_ci    /// Places the result of `a / b` in `self`. The remainder is discarded.
48592f3ab15Sopenharmony_ci    /// [`core::ops::Div`] is also implemented for `BigNumRef`.
48692f3ab15Sopenharmony_ci    ///
48792f3ab15Sopenharmony_ci    /// [`core::ops::Div`]: struct.BigNumRef.html#method.div
48892f3ab15Sopenharmony_ci    #[corresponds(BN_div)]
48992f3ab15Sopenharmony_ci    pub fn checked_div(
49092f3ab15Sopenharmony_ci        &mut self,
49192f3ab15Sopenharmony_ci        a: &BigNumRef,
49292f3ab15Sopenharmony_ci        b: &BigNumRef,
49392f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
49492f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
49592f3ab15Sopenharmony_ci        unsafe {
49692f3ab15Sopenharmony_ci            cvt(ffi::BN_div(
49792f3ab15Sopenharmony_ci                self.as_ptr(),
49892f3ab15Sopenharmony_ci                ptr::null_mut(),
49992f3ab15Sopenharmony_ci                a.as_ptr(),
50092f3ab15Sopenharmony_ci                b.as_ptr(),
50192f3ab15Sopenharmony_ci                ctx.as_ptr(),
50292f3ab15Sopenharmony_ci            ))
50392f3ab15Sopenharmony_ci            .map(|_| ())
50492f3ab15Sopenharmony_ci        }
50592f3ab15Sopenharmony_ci    }
50692f3ab15Sopenharmony_ci
50792f3ab15Sopenharmony_ci    /// Places the result of `a % b` in `self`.
50892f3ab15Sopenharmony_ci    #[corresponds(BN_div)]
50992f3ab15Sopenharmony_ci    pub fn checked_rem(
51092f3ab15Sopenharmony_ci        &mut self,
51192f3ab15Sopenharmony_ci        a: &BigNumRef,
51292f3ab15Sopenharmony_ci        b: &BigNumRef,
51392f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
51492f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
51592f3ab15Sopenharmony_ci        unsafe {
51692f3ab15Sopenharmony_ci            cvt(ffi::BN_div(
51792f3ab15Sopenharmony_ci                ptr::null_mut(),
51892f3ab15Sopenharmony_ci                self.as_ptr(),
51992f3ab15Sopenharmony_ci                a.as_ptr(),
52092f3ab15Sopenharmony_ci                b.as_ptr(),
52192f3ab15Sopenharmony_ci                ctx.as_ptr(),
52292f3ab15Sopenharmony_ci            ))
52392f3ab15Sopenharmony_ci            .map(|_| ())
52492f3ab15Sopenharmony_ci        }
52592f3ab15Sopenharmony_ci    }
52692f3ab15Sopenharmony_ci
52792f3ab15Sopenharmony_ci    /// Places the result of `a / b` in `self` and `a % b` in `rem`.
52892f3ab15Sopenharmony_ci    #[corresponds(BN_div)]
52992f3ab15Sopenharmony_ci    pub fn div_rem(
53092f3ab15Sopenharmony_ci        &mut self,
53192f3ab15Sopenharmony_ci        rem: &mut BigNumRef,
53292f3ab15Sopenharmony_ci        a: &BigNumRef,
53392f3ab15Sopenharmony_ci        b: &BigNumRef,
53492f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
53592f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
53692f3ab15Sopenharmony_ci        unsafe {
53792f3ab15Sopenharmony_ci            cvt(ffi::BN_div(
53892f3ab15Sopenharmony_ci                self.as_ptr(),
53992f3ab15Sopenharmony_ci                rem.as_ptr(),
54092f3ab15Sopenharmony_ci                a.as_ptr(),
54192f3ab15Sopenharmony_ci                b.as_ptr(),
54292f3ab15Sopenharmony_ci                ctx.as_ptr(),
54392f3ab15Sopenharmony_ci            ))
54492f3ab15Sopenharmony_ci            .map(|_| ())
54592f3ab15Sopenharmony_ci        }
54692f3ab15Sopenharmony_ci    }
54792f3ab15Sopenharmony_ci
54892f3ab15Sopenharmony_ci    /// Places the result of `a²` in `self`.
54992f3ab15Sopenharmony_ci    #[corresponds(BN_sqr)]
55092f3ab15Sopenharmony_ci    pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
55192f3ab15Sopenharmony_ci        unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
55292f3ab15Sopenharmony_ci    }
55392f3ab15Sopenharmony_ci
55492f3ab15Sopenharmony_ci    /// Places the result of `a mod m` in `self`.  As opposed to `div_rem`
55592f3ab15Sopenharmony_ci    /// the result is non-negative.
55692f3ab15Sopenharmony_ci    #[corresponds(BN_nnmod)]
55792f3ab15Sopenharmony_ci    pub fn nnmod(
55892f3ab15Sopenharmony_ci        &mut self,
55992f3ab15Sopenharmony_ci        a: &BigNumRef,
56092f3ab15Sopenharmony_ci        m: &BigNumRef,
56192f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
56292f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
56392f3ab15Sopenharmony_ci        unsafe {
56492f3ab15Sopenharmony_ci            cvt(ffi::BN_nnmod(
56592f3ab15Sopenharmony_ci                self.as_ptr(),
56692f3ab15Sopenharmony_ci                a.as_ptr(),
56792f3ab15Sopenharmony_ci                m.as_ptr(),
56892f3ab15Sopenharmony_ci                ctx.as_ptr(),
56992f3ab15Sopenharmony_ci            ))
57092f3ab15Sopenharmony_ci            .map(|_| ())
57192f3ab15Sopenharmony_ci        }
57292f3ab15Sopenharmony_ci    }
57392f3ab15Sopenharmony_ci
57492f3ab15Sopenharmony_ci    /// Places the result of `(a + b) mod m` in `self`.
57592f3ab15Sopenharmony_ci    #[corresponds(BN_mod_add)]
57692f3ab15Sopenharmony_ci    pub fn mod_add(
57792f3ab15Sopenharmony_ci        &mut self,
57892f3ab15Sopenharmony_ci        a: &BigNumRef,
57992f3ab15Sopenharmony_ci        b: &BigNumRef,
58092f3ab15Sopenharmony_ci        m: &BigNumRef,
58192f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
58292f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
58392f3ab15Sopenharmony_ci        unsafe {
58492f3ab15Sopenharmony_ci            cvt(ffi::BN_mod_add(
58592f3ab15Sopenharmony_ci                self.as_ptr(),
58692f3ab15Sopenharmony_ci                a.as_ptr(),
58792f3ab15Sopenharmony_ci                b.as_ptr(),
58892f3ab15Sopenharmony_ci                m.as_ptr(),
58992f3ab15Sopenharmony_ci                ctx.as_ptr(),
59092f3ab15Sopenharmony_ci            ))
59192f3ab15Sopenharmony_ci            .map(|_| ())
59292f3ab15Sopenharmony_ci        }
59392f3ab15Sopenharmony_ci    }
59492f3ab15Sopenharmony_ci
59592f3ab15Sopenharmony_ci    /// Places the result of `(a - b) mod m` in `self`.
59692f3ab15Sopenharmony_ci    #[corresponds(BN_mod_sub)]
59792f3ab15Sopenharmony_ci    pub fn mod_sub(
59892f3ab15Sopenharmony_ci        &mut self,
59992f3ab15Sopenharmony_ci        a: &BigNumRef,
60092f3ab15Sopenharmony_ci        b: &BigNumRef,
60192f3ab15Sopenharmony_ci        m: &BigNumRef,
60292f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
60392f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
60492f3ab15Sopenharmony_ci        unsafe {
60592f3ab15Sopenharmony_ci            cvt(ffi::BN_mod_sub(
60692f3ab15Sopenharmony_ci                self.as_ptr(),
60792f3ab15Sopenharmony_ci                a.as_ptr(),
60892f3ab15Sopenharmony_ci                b.as_ptr(),
60992f3ab15Sopenharmony_ci                m.as_ptr(),
61092f3ab15Sopenharmony_ci                ctx.as_ptr(),
61192f3ab15Sopenharmony_ci            ))
61292f3ab15Sopenharmony_ci            .map(|_| ())
61392f3ab15Sopenharmony_ci        }
61492f3ab15Sopenharmony_ci    }
61592f3ab15Sopenharmony_ci
61692f3ab15Sopenharmony_ci    /// Places the result of `(a * b) mod m` in `self`.
61792f3ab15Sopenharmony_ci    #[corresponds(BN_mod_mul)]
61892f3ab15Sopenharmony_ci    pub fn mod_mul(
61992f3ab15Sopenharmony_ci        &mut self,
62092f3ab15Sopenharmony_ci        a: &BigNumRef,
62192f3ab15Sopenharmony_ci        b: &BigNumRef,
62292f3ab15Sopenharmony_ci        m: &BigNumRef,
62392f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
62492f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
62592f3ab15Sopenharmony_ci        unsafe {
62692f3ab15Sopenharmony_ci            cvt(ffi::BN_mod_mul(
62792f3ab15Sopenharmony_ci                self.as_ptr(),
62892f3ab15Sopenharmony_ci                a.as_ptr(),
62992f3ab15Sopenharmony_ci                b.as_ptr(),
63092f3ab15Sopenharmony_ci                m.as_ptr(),
63192f3ab15Sopenharmony_ci                ctx.as_ptr(),
63292f3ab15Sopenharmony_ci            ))
63392f3ab15Sopenharmony_ci            .map(|_| ())
63492f3ab15Sopenharmony_ci        }
63592f3ab15Sopenharmony_ci    }
63692f3ab15Sopenharmony_ci
63792f3ab15Sopenharmony_ci    /// Places the result of `a² mod m` in `self`.
63892f3ab15Sopenharmony_ci    #[corresponds(BN_mod_sqr)]
63992f3ab15Sopenharmony_ci    pub fn mod_sqr(
64092f3ab15Sopenharmony_ci        &mut self,
64192f3ab15Sopenharmony_ci        a: &BigNumRef,
64292f3ab15Sopenharmony_ci        m: &BigNumRef,
64392f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
64492f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
64592f3ab15Sopenharmony_ci        unsafe {
64692f3ab15Sopenharmony_ci            cvt(ffi::BN_mod_sqr(
64792f3ab15Sopenharmony_ci                self.as_ptr(),
64892f3ab15Sopenharmony_ci                a.as_ptr(),
64992f3ab15Sopenharmony_ci                m.as_ptr(),
65092f3ab15Sopenharmony_ci                ctx.as_ptr(),
65192f3ab15Sopenharmony_ci            ))
65292f3ab15Sopenharmony_ci            .map(|_| ())
65392f3ab15Sopenharmony_ci        }
65492f3ab15Sopenharmony_ci    }
65592f3ab15Sopenharmony_ci
65692f3ab15Sopenharmony_ci    /// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)`
65792f3ab15Sopenharmony_ci    #[corresponds(BN_mod_sqrt)]
65892f3ab15Sopenharmony_ci    #[cfg(ossl110)]
65992f3ab15Sopenharmony_ci    pub fn mod_sqrt(
66092f3ab15Sopenharmony_ci        &mut self,
66192f3ab15Sopenharmony_ci        a: &BigNumRef,
66292f3ab15Sopenharmony_ci        p: &BigNumRef,
66392f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
66492f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
66592f3ab15Sopenharmony_ci        unsafe {
66692f3ab15Sopenharmony_ci            cvt_p(ffi::BN_mod_sqrt(
66792f3ab15Sopenharmony_ci                self.as_ptr(),
66892f3ab15Sopenharmony_ci                a.as_ptr(),
66992f3ab15Sopenharmony_ci                p.as_ptr(),
67092f3ab15Sopenharmony_ci                ctx.as_ptr(),
67192f3ab15Sopenharmony_ci            ))
67292f3ab15Sopenharmony_ci            .map(|_| ())
67392f3ab15Sopenharmony_ci        }
67492f3ab15Sopenharmony_ci    }
67592f3ab15Sopenharmony_ci
67692f3ab15Sopenharmony_ci    /// Places the result of `a^p` in `self`.
67792f3ab15Sopenharmony_ci    #[corresponds(BN_exp)]
67892f3ab15Sopenharmony_ci    pub fn exp(
67992f3ab15Sopenharmony_ci        &mut self,
68092f3ab15Sopenharmony_ci        a: &BigNumRef,
68192f3ab15Sopenharmony_ci        p: &BigNumRef,
68292f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
68392f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
68492f3ab15Sopenharmony_ci        unsafe {
68592f3ab15Sopenharmony_ci            cvt(ffi::BN_exp(
68692f3ab15Sopenharmony_ci                self.as_ptr(),
68792f3ab15Sopenharmony_ci                a.as_ptr(),
68892f3ab15Sopenharmony_ci                p.as_ptr(),
68992f3ab15Sopenharmony_ci                ctx.as_ptr(),
69092f3ab15Sopenharmony_ci            ))
69192f3ab15Sopenharmony_ci            .map(|_| ())
69292f3ab15Sopenharmony_ci        }
69392f3ab15Sopenharmony_ci    }
69492f3ab15Sopenharmony_ci
69592f3ab15Sopenharmony_ci    /// Places the result of `a^p mod m` in `self`.
69692f3ab15Sopenharmony_ci    #[corresponds(BN_mod_exp)]
69792f3ab15Sopenharmony_ci    pub fn mod_exp(
69892f3ab15Sopenharmony_ci        &mut self,
69992f3ab15Sopenharmony_ci        a: &BigNumRef,
70092f3ab15Sopenharmony_ci        p: &BigNumRef,
70192f3ab15Sopenharmony_ci        m: &BigNumRef,
70292f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
70392f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
70492f3ab15Sopenharmony_ci        unsafe {
70592f3ab15Sopenharmony_ci            cvt(ffi::BN_mod_exp(
70692f3ab15Sopenharmony_ci                self.as_ptr(),
70792f3ab15Sopenharmony_ci                a.as_ptr(),
70892f3ab15Sopenharmony_ci                p.as_ptr(),
70992f3ab15Sopenharmony_ci                m.as_ptr(),
71092f3ab15Sopenharmony_ci                ctx.as_ptr(),
71192f3ab15Sopenharmony_ci            ))
71292f3ab15Sopenharmony_ci            .map(|_| ())
71392f3ab15Sopenharmony_ci        }
71492f3ab15Sopenharmony_ci    }
71592f3ab15Sopenharmony_ci
71692f3ab15Sopenharmony_ci    /// Places the inverse of `a` modulo `n` in `self`.
71792f3ab15Sopenharmony_ci    #[corresponds(BN_mod_inverse)]
71892f3ab15Sopenharmony_ci    pub fn mod_inverse(
71992f3ab15Sopenharmony_ci        &mut self,
72092f3ab15Sopenharmony_ci        a: &BigNumRef,
72192f3ab15Sopenharmony_ci        n: &BigNumRef,
72292f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
72392f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
72492f3ab15Sopenharmony_ci        unsafe {
72592f3ab15Sopenharmony_ci            cvt_p(ffi::BN_mod_inverse(
72692f3ab15Sopenharmony_ci                self.as_ptr(),
72792f3ab15Sopenharmony_ci                a.as_ptr(),
72892f3ab15Sopenharmony_ci                n.as_ptr(),
72992f3ab15Sopenharmony_ci                ctx.as_ptr(),
73092f3ab15Sopenharmony_ci            ))
73192f3ab15Sopenharmony_ci            .map(|_| ())
73292f3ab15Sopenharmony_ci        }
73392f3ab15Sopenharmony_ci    }
73492f3ab15Sopenharmony_ci
73592f3ab15Sopenharmony_ci    /// Places the greatest common denominator of `a` and `b` in `self`.
73692f3ab15Sopenharmony_ci    #[corresponds(BN_gcd)]
73792f3ab15Sopenharmony_ci    pub fn gcd(
73892f3ab15Sopenharmony_ci        &mut self,
73992f3ab15Sopenharmony_ci        a: &BigNumRef,
74092f3ab15Sopenharmony_ci        b: &BigNumRef,
74192f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
74292f3ab15Sopenharmony_ci    ) -> Result<(), ErrorStack> {
74392f3ab15Sopenharmony_ci        unsafe {
74492f3ab15Sopenharmony_ci            cvt(ffi::BN_gcd(
74592f3ab15Sopenharmony_ci                self.as_ptr(),
74692f3ab15Sopenharmony_ci                a.as_ptr(),
74792f3ab15Sopenharmony_ci                b.as_ptr(),
74892f3ab15Sopenharmony_ci                ctx.as_ptr(),
74992f3ab15Sopenharmony_ci            ))
75092f3ab15Sopenharmony_ci            .map(|_| ())
75192f3ab15Sopenharmony_ci        }
75292f3ab15Sopenharmony_ci    }
75392f3ab15Sopenharmony_ci
75492f3ab15Sopenharmony_ci    /// Checks whether `self` is prime.
75592f3ab15Sopenharmony_ci    ///
75692f3ab15Sopenharmony_ci    /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
75792f3ab15Sopenharmony_ci    ///
75892f3ab15Sopenharmony_ci    /// # Return Value
75992f3ab15Sopenharmony_ci    ///
76092f3ab15Sopenharmony_ci    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
76192f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
76292f3ab15Sopenharmony_ci    #[corresponds(BN_is_prime_ex)]
76392f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
76492f3ab15Sopenharmony_ci    pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
76592f3ab15Sopenharmony_ci        unsafe {
76692f3ab15Sopenharmony_ci            cvt_n(ffi::BN_is_prime_ex(
76792f3ab15Sopenharmony_ci                self.as_ptr(),
76892f3ab15Sopenharmony_ci                checks.into(),
76992f3ab15Sopenharmony_ci                ctx.as_ptr(),
77092f3ab15Sopenharmony_ci                ptr::null_mut(),
77192f3ab15Sopenharmony_ci            ))
77292f3ab15Sopenharmony_ci            .map(|r| r != 0)
77392f3ab15Sopenharmony_ci        }
77492f3ab15Sopenharmony_ci    }
77592f3ab15Sopenharmony_ci
77692f3ab15Sopenharmony_ci    /// Checks whether `self` is prime with optional trial division.
77792f3ab15Sopenharmony_ci    ///
77892f3ab15Sopenharmony_ci    /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
77992f3ab15Sopenharmony_ci    /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
78092f3ab15Sopenharmony_ci    /// iterations.
78192f3ab15Sopenharmony_ci    ///
78292f3ab15Sopenharmony_ci    /// # Return Value
78392f3ab15Sopenharmony_ci    ///
78492f3ab15Sopenharmony_ci    /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
78592f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
78692f3ab15Sopenharmony_ci    #[corresponds(BN_is_prime_fasttest_ex)]
78792f3ab15Sopenharmony_ci    #[allow(clippy::useless_conversion)]
78892f3ab15Sopenharmony_ci    pub fn is_prime_fasttest(
78992f3ab15Sopenharmony_ci        &self,
79092f3ab15Sopenharmony_ci        checks: i32,
79192f3ab15Sopenharmony_ci        ctx: &mut BigNumContextRef,
79292f3ab15Sopenharmony_ci        do_trial_division: bool,
79392f3ab15Sopenharmony_ci    ) -> Result<bool, ErrorStack> {
79492f3ab15Sopenharmony_ci        unsafe {
79592f3ab15Sopenharmony_ci            cvt_n(ffi::BN_is_prime_fasttest_ex(
79692f3ab15Sopenharmony_ci                self.as_ptr(),
79792f3ab15Sopenharmony_ci                checks.into(),
79892f3ab15Sopenharmony_ci                ctx.as_ptr(),
79992f3ab15Sopenharmony_ci                do_trial_division as c_int,
80092f3ab15Sopenharmony_ci                ptr::null_mut(),
80192f3ab15Sopenharmony_ci            ))
80292f3ab15Sopenharmony_ci            .map(|r| r != 0)
80392f3ab15Sopenharmony_ci        }
80492f3ab15Sopenharmony_ci    }
80592f3ab15Sopenharmony_ci
80692f3ab15Sopenharmony_ci    /// Returns a big-endian byte vector representation of the absolute value of `self`.
80792f3ab15Sopenharmony_ci    ///
80892f3ab15Sopenharmony_ci    /// `self` can be recreated by using `from_slice`.
80992f3ab15Sopenharmony_ci    ///
81092f3ab15Sopenharmony_ci    /// ```
81192f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
81292f3ab15Sopenharmony_ci    /// let s = -BigNum::from_u32(4543).unwrap();
81392f3ab15Sopenharmony_ci    /// let r = BigNum::from_u32(4543).unwrap();
81492f3ab15Sopenharmony_ci    ///
81592f3ab15Sopenharmony_ci    /// let s_vec = s.to_vec();
81692f3ab15Sopenharmony_ci    /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
81792f3ab15Sopenharmony_ci    /// ```
81892f3ab15Sopenharmony_ci    #[corresponds(BN_bn2bin)]
81992f3ab15Sopenharmony_ci    pub fn to_vec(&self) -> Vec<u8> {
82092f3ab15Sopenharmony_ci        let size = self.num_bytes() as usize;
82192f3ab15Sopenharmony_ci        let mut v = Vec::with_capacity(size);
82292f3ab15Sopenharmony_ci        unsafe {
82392f3ab15Sopenharmony_ci            ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
82492f3ab15Sopenharmony_ci            v.set_len(size);
82592f3ab15Sopenharmony_ci        }
82692f3ab15Sopenharmony_ci        v
82792f3ab15Sopenharmony_ci    }
82892f3ab15Sopenharmony_ci
82992f3ab15Sopenharmony_ci    /// Returns a big-endian byte vector representation of the absolute value of `self` padded
83092f3ab15Sopenharmony_ci    /// to `pad_to` bytes.
83192f3ab15Sopenharmony_ci    ///
83292f3ab15Sopenharmony_ci    /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
83392f3ab15Sopenharmony_ci    ///
83492f3ab15Sopenharmony_ci    /// `self` can be recreated by using `from_slice`.
83592f3ab15Sopenharmony_ci    ///
83692f3ab15Sopenharmony_ci    /// ```
83792f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
83892f3ab15Sopenharmony_ci    /// let bn = BigNum::from_u32(0x4543).unwrap();
83992f3ab15Sopenharmony_ci    ///
84092f3ab15Sopenharmony_ci    /// let bn_vec = bn.to_vec_padded(4).unwrap();
84192f3ab15Sopenharmony_ci    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
84292f3ab15Sopenharmony_ci    ///
84392f3ab15Sopenharmony_ci    /// let r = bn.to_vec_padded(1);
84492f3ab15Sopenharmony_ci    /// assert!(r.is_err());
84592f3ab15Sopenharmony_ci    ///
84692f3ab15Sopenharmony_ci    /// let bn = -BigNum::from_u32(0x4543).unwrap();
84792f3ab15Sopenharmony_ci    /// let bn_vec = bn.to_vec_padded(4).unwrap();
84892f3ab15Sopenharmony_ci    /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
84992f3ab15Sopenharmony_ci    /// ```
85092f3ab15Sopenharmony_ci    #[corresponds(BN_bn2binpad)]
85192f3ab15Sopenharmony_ci    #[cfg(any(ossl110, libressl340, boringssl))]
85292f3ab15Sopenharmony_ci    pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
85392f3ab15Sopenharmony_ci        let mut v = Vec::with_capacity(pad_to as usize);
85492f3ab15Sopenharmony_ci        unsafe {
85592f3ab15Sopenharmony_ci            cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
85692f3ab15Sopenharmony_ci            v.set_len(pad_to as usize);
85792f3ab15Sopenharmony_ci        }
85892f3ab15Sopenharmony_ci        Ok(v)
85992f3ab15Sopenharmony_ci    }
86092f3ab15Sopenharmony_ci
86192f3ab15Sopenharmony_ci    /// Returns a decimal string representation of `self`.
86292f3ab15Sopenharmony_ci    ///
86392f3ab15Sopenharmony_ci    /// ```
86492f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
86592f3ab15Sopenharmony_ci    /// let s = -BigNum::from_u32(12345).unwrap();
86692f3ab15Sopenharmony_ci    ///
86792f3ab15Sopenharmony_ci    /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
86892f3ab15Sopenharmony_ci    /// ```
86992f3ab15Sopenharmony_ci    #[corresponds(BN_bn2dec)]
87092f3ab15Sopenharmony_ci    pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
87192f3ab15Sopenharmony_ci        unsafe {
87292f3ab15Sopenharmony_ci            let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
87392f3ab15Sopenharmony_ci            Ok(OpensslString::from_ptr(buf))
87492f3ab15Sopenharmony_ci        }
87592f3ab15Sopenharmony_ci    }
87692f3ab15Sopenharmony_ci
87792f3ab15Sopenharmony_ci    /// Returns a hexadecimal string representation of `self`.
87892f3ab15Sopenharmony_ci    ///
87992f3ab15Sopenharmony_ci    /// ```
88092f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
88192f3ab15Sopenharmony_ci    /// let s = -BigNum::from_u32(0x99ff).unwrap();
88292f3ab15Sopenharmony_ci    ///
88392f3ab15Sopenharmony_ci    /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
88492f3ab15Sopenharmony_ci    /// ```
88592f3ab15Sopenharmony_ci    #[corresponds(BN_bn2hex)]
88692f3ab15Sopenharmony_ci    pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
88792f3ab15Sopenharmony_ci        unsafe {
88892f3ab15Sopenharmony_ci            let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
88992f3ab15Sopenharmony_ci            Ok(OpensslString::from_ptr(buf))
89092f3ab15Sopenharmony_ci        }
89192f3ab15Sopenharmony_ci    }
89292f3ab15Sopenharmony_ci
89392f3ab15Sopenharmony_ci    /// Returns an `Asn1Integer` containing the value of `self`.
89492f3ab15Sopenharmony_ci    #[corresponds(BN_to_ASN1_INTEGER)]
89592f3ab15Sopenharmony_ci    pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
89692f3ab15Sopenharmony_ci        unsafe {
89792f3ab15Sopenharmony_ci            cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
89892f3ab15Sopenharmony_ci                .map(|p| Asn1Integer::from_ptr(p))
89992f3ab15Sopenharmony_ci        }
90092f3ab15Sopenharmony_ci    }
90192f3ab15Sopenharmony_ci
90292f3ab15Sopenharmony_ci    /// Force constant time computation on this value.
90392f3ab15Sopenharmony_ci    #[corresponds(BN_set_flags)]
90492f3ab15Sopenharmony_ci    #[cfg(ossl110)]
90592f3ab15Sopenharmony_ci    pub fn set_const_time(&mut self) {
90692f3ab15Sopenharmony_ci        unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
90792f3ab15Sopenharmony_ci    }
90892f3ab15Sopenharmony_ci
90992f3ab15Sopenharmony_ci    /// Returns true if `self` is in const time mode.
91092f3ab15Sopenharmony_ci    #[corresponds(BN_get_flags)]
91192f3ab15Sopenharmony_ci    #[cfg(ossl110)]
91292f3ab15Sopenharmony_ci    pub fn is_const_time(&self) -> bool {
91392f3ab15Sopenharmony_ci        unsafe {
91492f3ab15Sopenharmony_ci            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
91592f3ab15Sopenharmony_ci            ret == ffi::BN_FLG_CONSTTIME
91692f3ab15Sopenharmony_ci        }
91792f3ab15Sopenharmony_ci    }
91892f3ab15Sopenharmony_ci
91992f3ab15Sopenharmony_ci    /// Returns true if `self` was created with [`BigNum::new_secure`].
92092f3ab15Sopenharmony_ci    #[corresponds(BN_get_flags)]
92192f3ab15Sopenharmony_ci    #[cfg(ossl110)]
92292f3ab15Sopenharmony_ci    pub fn is_secure(&self) -> bool {
92392f3ab15Sopenharmony_ci        unsafe {
92492f3ab15Sopenharmony_ci            let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
92592f3ab15Sopenharmony_ci            ret == ffi::BN_FLG_SECURE
92692f3ab15Sopenharmony_ci        }
92792f3ab15Sopenharmony_ci    }
92892f3ab15Sopenharmony_ci}
92992f3ab15Sopenharmony_ci
93092f3ab15Sopenharmony_ciimpl BigNum {
93192f3ab15Sopenharmony_ci    /// Creates a new `BigNum` with the value 0.
93292f3ab15Sopenharmony_ci    #[corresponds(BN_new)]
93392f3ab15Sopenharmony_ci    pub fn new() -> Result<BigNum, ErrorStack> {
93492f3ab15Sopenharmony_ci        unsafe {
93592f3ab15Sopenharmony_ci            ffi::init();
93692f3ab15Sopenharmony_ci            let v = cvt_p(ffi::BN_new())?;
93792f3ab15Sopenharmony_ci            Ok(BigNum::from_ptr(v))
93892f3ab15Sopenharmony_ci        }
93992f3ab15Sopenharmony_ci    }
94092f3ab15Sopenharmony_ci
94192f3ab15Sopenharmony_ci    /// Returns a new secure `BigNum`.
94292f3ab15Sopenharmony_ci    #[corresponds(BN_secure_new)]
94392f3ab15Sopenharmony_ci    #[cfg(ossl110)]
94492f3ab15Sopenharmony_ci    pub fn new_secure() -> Result<BigNum, ErrorStack> {
94592f3ab15Sopenharmony_ci        unsafe {
94692f3ab15Sopenharmony_ci            ffi::init();
94792f3ab15Sopenharmony_ci            let v = cvt_p(ffi::BN_secure_new())?;
94892f3ab15Sopenharmony_ci            Ok(BigNum::from_ptr(v))
94992f3ab15Sopenharmony_ci        }
95092f3ab15Sopenharmony_ci    }
95192f3ab15Sopenharmony_ci
95292f3ab15Sopenharmony_ci    /// Creates a new `BigNum` with the given value.
95392f3ab15Sopenharmony_ci    #[corresponds(BN_set_word)]
95492f3ab15Sopenharmony_ci    pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
95592f3ab15Sopenharmony_ci        BigNum::new().and_then(|v| unsafe {
95692f3ab15Sopenharmony_ci            cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
95792f3ab15Sopenharmony_ci        })
95892f3ab15Sopenharmony_ci    }
95992f3ab15Sopenharmony_ci
96092f3ab15Sopenharmony_ci    /// Creates a `BigNum` from a decimal string.
96192f3ab15Sopenharmony_ci    #[corresponds(BN_dec2bn)]
96292f3ab15Sopenharmony_ci    pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
96392f3ab15Sopenharmony_ci        unsafe {
96492f3ab15Sopenharmony_ci            ffi::init();
96592f3ab15Sopenharmony_ci            let c_str = CString::new(s.as_bytes()).unwrap();
96692f3ab15Sopenharmony_ci            let mut bn = ptr::null_mut();
96792f3ab15Sopenharmony_ci            cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?;
96892f3ab15Sopenharmony_ci            Ok(BigNum::from_ptr(bn))
96992f3ab15Sopenharmony_ci        }
97092f3ab15Sopenharmony_ci    }
97192f3ab15Sopenharmony_ci
97292f3ab15Sopenharmony_ci    /// Creates a `BigNum` from a hexadecimal string.
97392f3ab15Sopenharmony_ci    #[corresponds(BN_hex2bn)]
97492f3ab15Sopenharmony_ci    pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
97592f3ab15Sopenharmony_ci        unsafe {
97692f3ab15Sopenharmony_ci            ffi::init();
97792f3ab15Sopenharmony_ci            let c_str = CString::new(s.as_bytes()).unwrap();
97892f3ab15Sopenharmony_ci            let mut bn = ptr::null_mut();
97992f3ab15Sopenharmony_ci            cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?;
98092f3ab15Sopenharmony_ci            Ok(BigNum::from_ptr(bn))
98192f3ab15Sopenharmony_ci        }
98292f3ab15Sopenharmony_ci    }
98392f3ab15Sopenharmony_ci
98492f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
98592f3ab15Sopenharmony_ci    /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
98692f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
98792f3ab15Sopenharmony_ci    ///
98892f3ab15Sopenharmony_ci    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
98992f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc2409_prime_768)]
99092f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
99192f3ab15Sopenharmony_ci    pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
99292f3ab15Sopenharmony_ci        unsafe {
99392f3ab15Sopenharmony_ci            ffi::init();
99492f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
99592f3ab15Sopenharmony_ci        }
99692f3ab15Sopenharmony_ci    }
99792f3ab15Sopenharmony_ci
99892f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
99992f3ab15Sopenharmony_ci    /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
100092f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
100192f3ab15Sopenharmony_ci    ///
100292f3ab15Sopenharmony_ci    /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
100392f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc2409_prime_1024)]
100492f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
100592f3ab15Sopenharmony_ci    pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
100692f3ab15Sopenharmony_ci        unsafe {
100792f3ab15Sopenharmony_ci            ffi::init();
100892f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
100992f3ab15Sopenharmony_ci        }
101092f3ab15Sopenharmony_ci    }
101192f3ab15Sopenharmony_ci
101292f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
101392f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
101492f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
101592f3ab15Sopenharmony_ci    ///
101692f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
101792f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_1536)]
101892f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
101992f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
102092f3ab15Sopenharmony_ci        unsafe {
102192f3ab15Sopenharmony_ci            ffi::init();
102292f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
102392f3ab15Sopenharmony_ci        }
102492f3ab15Sopenharmony_ci    }
102592f3ab15Sopenharmony_ci
102692f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
102792f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
102892f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
102992f3ab15Sopenharmony_ci    ///
103092f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
103192f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_2048)]
103292f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
103392f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
103492f3ab15Sopenharmony_ci        unsafe {
103592f3ab15Sopenharmony_ci            ffi::init();
103692f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
103792f3ab15Sopenharmony_ci        }
103892f3ab15Sopenharmony_ci    }
103992f3ab15Sopenharmony_ci
104092f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
104192f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
104292f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
104392f3ab15Sopenharmony_ci    ///
104492f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
104592f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_3072)]
104692f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
104792f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
104892f3ab15Sopenharmony_ci        unsafe {
104992f3ab15Sopenharmony_ci            ffi::init();
105092f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
105192f3ab15Sopenharmony_ci        }
105292f3ab15Sopenharmony_ci    }
105392f3ab15Sopenharmony_ci
105492f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
105592f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
105692f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
105792f3ab15Sopenharmony_ci    ///
105892f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
105992f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_4096)]
106092f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
106192f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
106292f3ab15Sopenharmony_ci        unsafe {
106392f3ab15Sopenharmony_ci            ffi::init();
106492f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum)
106592f3ab15Sopenharmony_ci        }
106692f3ab15Sopenharmony_ci    }
106792f3ab15Sopenharmony_ci
106892f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
106992f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 6144`.  This number is used during calculated key
107092f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 17.
107192f3ab15Sopenharmony_ci    ///
107292f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
107392f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_6114)]
107492f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
107592f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
107692f3ab15Sopenharmony_ci        unsafe {
107792f3ab15Sopenharmony_ci            ffi::init();
107892f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
107992f3ab15Sopenharmony_ci        }
108092f3ab15Sopenharmony_ci    }
108192f3ab15Sopenharmony_ci
108292f3ab15Sopenharmony_ci    /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
108392f3ab15Sopenharmony_ci    /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
108492f3ab15Sopenharmony_ci    /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
108592f3ab15Sopenharmony_ci    ///
108692f3ab15Sopenharmony_ci    /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
108792f3ab15Sopenharmony_ci    #[corresponds(BN_get_rfc3526_prime_8192)]
108892f3ab15Sopenharmony_ci    #[cfg(not(boringssl))]
108992f3ab15Sopenharmony_ci    pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
109092f3ab15Sopenharmony_ci        unsafe {
109192f3ab15Sopenharmony_ci            ffi::init();
109292f3ab15Sopenharmony_ci            cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
109392f3ab15Sopenharmony_ci        }
109492f3ab15Sopenharmony_ci    }
109592f3ab15Sopenharmony_ci
109692f3ab15Sopenharmony_ci    /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
109792f3ab15Sopenharmony_ci    ///
109892f3ab15Sopenharmony_ci    /// OpenSSL documentation at [`BN_bin2bn`]
109992f3ab15Sopenharmony_ci    ///
110092f3ab15Sopenharmony_ci    /// [`BN_bin2bn`]: https://www.openssl.org/docs/manmaster/crypto/BN_bin2bn.html
110192f3ab15Sopenharmony_ci    ///
110292f3ab15Sopenharmony_ci    /// ```
110392f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
110492f3ab15Sopenharmony_ci    /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
110592f3ab15Sopenharmony_ci    ///
110692f3ab15Sopenharmony_ci    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
110792f3ab15Sopenharmony_ci    /// ```
110892f3ab15Sopenharmony_ci    #[corresponds(BN_bin2bn)]
110992f3ab15Sopenharmony_ci    pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
111092f3ab15Sopenharmony_ci        unsafe {
111192f3ab15Sopenharmony_ci            ffi::init();
111292f3ab15Sopenharmony_ci            assert!(n.len() <= LenType::max_value() as usize);
111392f3ab15Sopenharmony_ci
111492f3ab15Sopenharmony_ci            cvt_p(ffi::BN_bin2bn(
111592f3ab15Sopenharmony_ci                n.as_ptr(),
111692f3ab15Sopenharmony_ci                n.len() as LenType,
111792f3ab15Sopenharmony_ci                ptr::null_mut(),
111892f3ab15Sopenharmony_ci            ))
111992f3ab15Sopenharmony_ci            .map(|p| BigNum::from_ptr(p))
112092f3ab15Sopenharmony_ci        }
112192f3ab15Sopenharmony_ci    }
112292f3ab15Sopenharmony_ci
112392f3ab15Sopenharmony_ci    /// Copies data from a slice overwriting what was in the BigNum.
112492f3ab15Sopenharmony_ci    ///
112592f3ab15Sopenharmony_ci    /// This function can be used to copy data from a slice to a
112692f3ab15Sopenharmony_ci    /// [secure BigNum][`BigNum::new_secure`].
112792f3ab15Sopenharmony_ci    ///
112892f3ab15Sopenharmony_ci    /// # Examples
112992f3ab15Sopenharmony_ci    ///
113092f3ab15Sopenharmony_ci    /// ```
113192f3ab15Sopenharmony_ci    /// # use openssl::bn::BigNum;
113292f3ab15Sopenharmony_ci    /// let mut bignum = BigNum::new().unwrap();
113392f3ab15Sopenharmony_ci    /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
113492f3ab15Sopenharmony_ci    ///
113592f3ab15Sopenharmony_ci    /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
113692f3ab15Sopenharmony_ci    /// ```
113792f3ab15Sopenharmony_ci    #[corresponds(BN_bin2bn)]
113892f3ab15Sopenharmony_ci    pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
113992f3ab15Sopenharmony_ci        unsafe {
114092f3ab15Sopenharmony_ci            assert!(n.len() <= LenType::max_value() as usize);
114192f3ab15Sopenharmony_ci
114292f3ab15Sopenharmony_ci            cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
114392f3ab15Sopenharmony_ci            Ok(())
114492f3ab15Sopenharmony_ci        }
114592f3ab15Sopenharmony_ci    }
114692f3ab15Sopenharmony_ci}
114792f3ab15Sopenharmony_ci
114892f3ab15Sopenharmony_ciimpl fmt::Debug for BigNumRef {
114992f3ab15Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115092f3ab15Sopenharmony_ci        match self.to_dec_str() {
115192f3ab15Sopenharmony_ci            Ok(s) => f.write_str(&s),
115292f3ab15Sopenharmony_ci            Err(e) => Err(e.into()),
115392f3ab15Sopenharmony_ci        }
115492f3ab15Sopenharmony_ci    }
115592f3ab15Sopenharmony_ci}
115692f3ab15Sopenharmony_ci
115792f3ab15Sopenharmony_ciimpl fmt::Debug for BigNum {
115892f3ab15Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115992f3ab15Sopenharmony_ci        match self.to_dec_str() {
116092f3ab15Sopenharmony_ci            Ok(s) => f.write_str(&s),
116192f3ab15Sopenharmony_ci            Err(e) => Err(e.into()),
116292f3ab15Sopenharmony_ci        }
116392f3ab15Sopenharmony_ci    }
116492f3ab15Sopenharmony_ci}
116592f3ab15Sopenharmony_ci
116692f3ab15Sopenharmony_ciimpl fmt::Display for BigNumRef {
116792f3ab15Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116892f3ab15Sopenharmony_ci        match self.to_dec_str() {
116992f3ab15Sopenharmony_ci            Ok(s) => f.write_str(&s),
117092f3ab15Sopenharmony_ci            Err(e) => Err(e.into()),
117192f3ab15Sopenharmony_ci        }
117292f3ab15Sopenharmony_ci    }
117392f3ab15Sopenharmony_ci}
117492f3ab15Sopenharmony_ci
117592f3ab15Sopenharmony_ciimpl fmt::Display for BigNum {
117692f3ab15Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117792f3ab15Sopenharmony_ci        match self.to_dec_str() {
117892f3ab15Sopenharmony_ci            Ok(s) => f.write_str(&s),
117992f3ab15Sopenharmony_ci            Err(e) => Err(e.into()),
118092f3ab15Sopenharmony_ci        }
118192f3ab15Sopenharmony_ci    }
118292f3ab15Sopenharmony_ci}
118392f3ab15Sopenharmony_ci
118492f3ab15Sopenharmony_ciimpl PartialEq<BigNumRef> for BigNumRef {
118592f3ab15Sopenharmony_ci    fn eq(&self, oth: &BigNumRef) -> bool {
118692f3ab15Sopenharmony_ci        self.cmp(oth) == Ordering::Equal
118792f3ab15Sopenharmony_ci    }
118892f3ab15Sopenharmony_ci}
118992f3ab15Sopenharmony_ci
119092f3ab15Sopenharmony_ciimpl PartialEq<BigNum> for BigNumRef {
119192f3ab15Sopenharmony_ci    fn eq(&self, oth: &BigNum) -> bool {
119292f3ab15Sopenharmony_ci        self.eq(oth.deref())
119392f3ab15Sopenharmony_ci    }
119492f3ab15Sopenharmony_ci}
119592f3ab15Sopenharmony_ci
119692f3ab15Sopenharmony_ciimpl Eq for BigNumRef {}
119792f3ab15Sopenharmony_ci
119892f3ab15Sopenharmony_ciimpl PartialEq for BigNum {
119992f3ab15Sopenharmony_ci    fn eq(&self, oth: &BigNum) -> bool {
120092f3ab15Sopenharmony_ci        self.deref().eq(oth)
120192f3ab15Sopenharmony_ci    }
120292f3ab15Sopenharmony_ci}
120392f3ab15Sopenharmony_ci
120492f3ab15Sopenharmony_ciimpl PartialEq<BigNumRef> for BigNum {
120592f3ab15Sopenharmony_ci    fn eq(&self, oth: &BigNumRef) -> bool {
120692f3ab15Sopenharmony_ci        self.deref().eq(oth)
120792f3ab15Sopenharmony_ci    }
120892f3ab15Sopenharmony_ci}
120992f3ab15Sopenharmony_ci
121092f3ab15Sopenharmony_ciimpl Eq for BigNum {}
121192f3ab15Sopenharmony_ci
121292f3ab15Sopenharmony_ciimpl PartialOrd<BigNumRef> for BigNumRef {
121392f3ab15Sopenharmony_ci    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
121492f3ab15Sopenharmony_ci        Some(self.cmp(oth))
121592f3ab15Sopenharmony_ci    }
121692f3ab15Sopenharmony_ci}
121792f3ab15Sopenharmony_ci
121892f3ab15Sopenharmony_ciimpl PartialOrd<BigNum> for BigNumRef {
121992f3ab15Sopenharmony_ci    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
122092f3ab15Sopenharmony_ci        Some(self.cmp(oth.deref()))
122192f3ab15Sopenharmony_ci    }
122292f3ab15Sopenharmony_ci}
122392f3ab15Sopenharmony_ci
122492f3ab15Sopenharmony_ciimpl Ord for BigNumRef {
122592f3ab15Sopenharmony_ci    fn cmp(&self, oth: &BigNumRef) -> Ordering {
122692f3ab15Sopenharmony_ci        unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
122792f3ab15Sopenharmony_ci    }
122892f3ab15Sopenharmony_ci}
122992f3ab15Sopenharmony_ci
123092f3ab15Sopenharmony_ciimpl PartialOrd for BigNum {
123192f3ab15Sopenharmony_ci    fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
123292f3ab15Sopenharmony_ci        self.deref().partial_cmp(oth.deref())
123392f3ab15Sopenharmony_ci    }
123492f3ab15Sopenharmony_ci}
123592f3ab15Sopenharmony_ci
123692f3ab15Sopenharmony_ciimpl PartialOrd<BigNumRef> for BigNum {
123792f3ab15Sopenharmony_ci    fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
123892f3ab15Sopenharmony_ci        self.deref().partial_cmp(oth)
123992f3ab15Sopenharmony_ci    }
124092f3ab15Sopenharmony_ci}
124192f3ab15Sopenharmony_ci
124292f3ab15Sopenharmony_ciimpl Ord for BigNum {
124392f3ab15Sopenharmony_ci    fn cmp(&self, oth: &BigNum) -> Ordering {
124492f3ab15Sopenharmony_ci        self.deref().cmp(oth.deref())
124592f3ab15Sopenharmony_ci    }
124692f3ab15Sopenharmony_ci}
124792f3ab15Sopenharmony_ci
124892f3ab15Sopenharmony_cimacro_rules! delegate {
124992f3ab15Sopenharmony_ci    ($t:ident, $m:ident) => {
125092f3ab15Sopenharmony_ci        impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
125192f3ab15Sopenharmony_ci            type Output = BigNum;
125292f3ab15Sopenharmony_ci
125392f3ab15Sopenharmony_ci            fn $m(self, oth: &BigNum) -> BigNum {
125492f3ab15Sopenharmony_ci                $t::$m(self, oth.deref())
125592f3ab15Sopenharmony_ci            }
125692f3ab15Sopenharmony_ci        }
125792f3ab15Sopenharmony_ci
125892f3ab15Sopenharmony_ci        impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
125992f3ab15Sopenharmony_ci            type Output = BigNum;
126092f3ab15Sopenharmony_ci
126192f3ab15Sopenharmony_ci            fn $m(self, oth: &BigNumRef) -> BigNum {
126292f3ab15Sopenharmony_ci                $t::$m(self.deref(), oth)
126392f3ab15Sopenharmony_ci            }
126492f3ab15Sopenharmony_ci        }
126592f3ab15Sopenharmony_ci
126692f3ab15Sopenharmony_ci        impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
126792f3ab15Sopenharmony_ci            type Output = BigNum;
126892f3ab15Sopenharmony_ci
126992f3ab15Sopenharmony_ci            fn $m(self, oth: &BigNum) -> BigNum {
127092f3ab15Sopenharmony_ci                $t::$m(self.deref(), oth.deref())
127192f3ab15Sopenharmony_ci            }
127292f3ab15Sopenharmony_ci        }
127392f3ab15Sopenharmony_ci    };
127492f3ab15Sopenharmony_ci}
127592f3ab15Sopenharmony_ci
127692f3ab15Sopenharmony_ciimpl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
127792f3ab15Sopenharmony_ci    type Output = BigNum;
127892f3ab15Sopenharmony_ci
127992f3ab15Sopenharmony_ci    fn add(self, oth: &BigNumRef) -> BigNum {
128092f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
128192f3ab15Sopenharmony_ci        r.checked_add(self, oth).unwrap();
128292f3ab15Sopenharmony_ci        r
128392f3ab15Sopenharmony_ci    }
128492f3ab15Sopenharmony_ci}
128592f3ab15Sopenharmony_ci
128692f3ab15Sopenharmony_cidelegate!(Add, add);
128792f3ab15Sopenharmony_ci
128892f3ab15Sopenharmony_ciimpl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
128992f3ab15Sopenharmony_ci    type Output = BigNum;
129092f3ab15Sopenharmony_ci
129192f3ab15Sopenharmony_ci    fn sub(self, oth: &BigNumRef) -> BigNum {
129292f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
129392f3ab15Sopenharmony_ci        r.checked_sub(self, oth).unwrap();
129492f3ab15Sopenharmony_ci        r
129592f3ab15Sopenharmony_ci    }
129692f3ab15Sopenharmony_ci}
129792f3ab15Sopenharmony_ci
129892f3ab15Sopenharmony_cidelegate!(Sub, sub);
129992f3ab15Sopenharmony_ci
130092f3ab15Sopenharmony_ciimpl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
130192f3ab15Sopenharmony_ci    type Output = BigNum;
130292f3ab15Sopenharmony_ci
130392f3ab15Sopenharmony_ci    fn mul(self, oth: &BigNumRef) -> BigNum {
130492f3ab15Sopenharmony_ci        let mut ctx = BigNumContext::new().unwrap();
130592f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
130692f3ab15Sopenharmony_ci        r.checked_mul(self, oth, &mut ctx).unwrap();
130792f3ab15Sopenharmony_ci        r
130892f3ab15Sopenharmony_ci    }
130992f3ab15Sopenharmony_ci}
131092f3ab15Sopenharmony_ci
131192f3ab15Sopenharmony_cidelegate!(Mul, mul);
131292f3ab15Sopenharmony_ci
131392f3ab15Sopenharmony_ciimpl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
131492f3ab15Sopenharmony_ci    type Output = BigNum;
131592f3ab15Sopenharmony_ci
131692f3ab15Sopenharmony_ci    fn div(self, oth: &'b BigNumRef) -> BigNum {
131792f3ab15Sopenharmony_ci        let mut ctx = BigNumContext::new().unwrap();
131892f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
131992f3ab15Sopenharmony_ci        r.checked_div(self, oth, &mut ctx).unwrap();
132092f3ab15Sopenharmony_ci        r
132192f3ab15Sopenharmony_ci    }
132292f3ab15Sopenharmony_ci}
132392f3ab15Sopenharmony_ci
132492f3ab15Sopenharmony_cidelegate!(Div, div);
132592f3ab15Sopenharmony_ci
132692f3ab15Sopenharmony_ciimpl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
132792f3ab15Sopenharmony_ci    type Output = BigNum;
132892f3ab15Sopenharmony_ci
132992f3ab15Sopenharmony_ci    fn rem(self, oth: &'b BigNumRef) -> BigNum {
133092f3ab15Sopenharmony_ci        let mut ctx = BigNumContext::new().unwrap();
133192f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
133292f3ab15Sopenharmony_ci        r.checked_rem(self, oth, &mut ctx).unwrap();
133392f3ab15Sopenharmony_ci        r
133492f3ab15Sopenharmony_ci    }
133592f3ab15Sopenharmony_ci}
133692f3ab15Sopenharmony_ci
133792f3ab15Sopenharmony_cidelegate!(Rem, rem);
133892f3ab15Sopenharmony_ci
133992f3ab15Sopenharmony_ciimpl<'a> Shl<i32> for &'a BigNumRef {
134092f3ab15Sopenharmony_ci    type Output = BigNum;
134192f3ab15Sopenharmony_ci
134292f3ab15Sopenharmony_ci    fn shl(self, n: i32) -> BigNum {
134392f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
134492f3ab15Sopenharmony_ci        r.lshift(self, n).unwrap();
134592f3ab15Sopenharmony_ci        r
134692f3ab15Sopenharmony_ci    }
134792f3ab15Sopenharmony_ci}
134892f3ab15Sopenharmony_ci
134992f3ab15Sopenharmony_ciimpl<'a> Shl<i32> for &'a BigNum {
135092f3ab15Sopenharmony_ci    type Output = BigNum;
135192f3ab15Sopenharmony_ci
135292f3ab15Sopenharmony_ci    fn shl(self, n: i32) -> BigNum {
135392f3ab15Sopenharmony_ci        self.deref().shl(n)
135492f3ab15Sopenharmony_ci    }
135592f3ab15Sopenharmony_ci}
135692f3ab15Sopenharmony_ci
135792f3ab15Sopenharmony_ciimpl<'a> Shr<i32> for &'a BigNumRef {
135892f3ab15Sopenharmony_ci    type Output = BigNum;
135992f3ab15Sopenharmony_ci
136092f3ab15Sopenharmony_ci    fn shr(self, n: i32) -> BigNum {
136192f3ab15Sopenharmony_ci        let mut r = BigNum::new().unwrap();
136292f3ab15Sopenharmony_ci        r.rshift(self, n).unwrap();
136392f3ab15Sopenharmony_ci        r
136492f3ab15Sopenharmony_ci    }
136592f3ab15Sopenharmony_ci}
136692f3ab15Sopenharmony_ci
136792f3ab15Sopenharmony_ciimpl<'a> Shr<i32> for &'a BigNum {
136892f3ab15Sopenharmony_ci    type Output = BigNum;
136992f3ab15Sopenharmony_ci
137092f3ab15Sopenharmony_ci    fn shr(self, n: i32) -> BigNum {
137192f3ab15Sopenharmony_ci        self.deref().shr(n)
137292f3ab15Sopenharmony_ci    }
137392f3ab15Sopenharmony_ci}
137492f3ab15Sopenharmony_ci
137592f3ab15Sopenharmony_ciimpl<'a> Neg for &'a BigNumRef {
137692f3ab15Sopenharmony_ci    type Output = BigNum;
137792f3ab15Sopenharmony_ci
137892f3ab15Sopenharmony_ci    fn neg(self) -> BigNum {
137992f3ab15Sopenharmony_ci        self.to_owned().unwrap().neg()
138092f3ab15Sopenharmony_ci    }
138192f3ab15Sopenharmony_ci}
138292f3ab15Sopenharmony_ci
138392f3ab15Sopenharmony_ciimpl<'a> Neg for &'a BigNum {
138492f3ab15Sopenharmony_ci    type Output = BigNum;
138592f3ab15Sopenharmony_ci
138692f3ab15Sopenharmony_ci    fn neg(self) -> BigNum {
138792f3ab15Sopenharmony_ci        self.deref().neg()
138892f3ab15Sopenharmony_ci    }
138992f3ab15Sopenharmony_ci}
139092f3ab15Sopenharmony_ci
139192f3ab15Sopenharmony_ciimpl Neg for BigNum {
139292f3ab15Sopenharmony_ci    type Output = BigNum;
139392f3ab15Sopenharmony_ci
139492f3ab15Sopenharmony_ci    fn neg(mut self) -> BigNum {
139592f3ab15Sopenharmony_ci        let negative = self.is_negative();
139692f3ab15Sopenharmony_ci        self.set_negative(!negative);
139792f3ab15Sopenharmony_ci        self
139892f3ab15Sopenharmony_ci    }
139992f3ab15Sopenharmony_ci}
140092f3ab15Sopenharmony_ci
140192f3ab15Sopenharmony_ci#[cfg(test)]
140292f3ab15Sopenharmony_cimod tests {
140392f3ab15Sopenharmony_ci    use crate::bn::{BigNum, BigNumContext};
140492f3ab15Sopenharmony_ci
140592f3ab15Sopenharmony_ci    #[test]
140692f3ab15Sopenharmony_ci    fn test_to_from_slice() {
140792f3ab15Sopenharmony_ci        let v0 = BigNum::from_u32(10_203_004).unwrap();
140892f3ab15Sopenharmony_ci        let vec = v0.to_vec();
140992f3ab15Sopenharmony_ci        let v1 = BigNum::from_slice(&vec).unwrap();
141092f3ab15Sopenharmony_ci
141192f3ab15Sopenharmony_ci        assert_eq!(v0, v1);
141292f3ab15Sopenharmony_ci    }
141392f3ab15Sopenharmony_ci
141492f3ab15Sopenharmony_ci    #[test]
141592f3ab15Sopenharmony_ci    fn test_negation() {
141692f3ab15Sopenharmony_ci        let a = BigNum::from_u32(909_829_283).unwrap();
141792f3ab15Sopenharmony_ci
141892f3ab15Sopenharmony_ci        assert!(!a.is_negative());
141992f3ab15Sopenharmony_ci        assert!((-a).is_negative());
142092f3ab15Sopenharmony_ci    }
142192f3ab15Sopenharmony_ci
142292f3ab15Sopenharmony_ci    #[test]
142392f3ab15Sopenharmony_ci    fn test_shift() {
142492f3ab15Sopenharmony_ci        let a = BigNum::from_u32(909_829_283).unwrap();
142592f3ab15Sopenharmony_ci
142692f3ab15Sopenharmony_ci        assert_eq!(a, &(&a << 1) >> 1);
142792f3ab15Sopenharmony_ci    }
142892f3ab15Sopenharmony_ci
142992f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
143092f3ab15Sopenharmony_ci    #[test]
143192f3ab15Sopenharmony_ci    fn test_rand_range() {
143292f3ab15Sopenharmony_ci        let range = BigNum::from_u32(909_829_283).unwrap();
143392f3ab15Sopenharmony_ci        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
143492f3ab15Sopenharmony_ci        range.rand_range(&mut result).unwrap();
143592f3ab15Sopenharmony_ci        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
143692f3ab15Sopenharmony_ci    }
143792f3ab15Sopenharmony_ci
143892f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
143992f3ab15Sopenharmony_ci    #[test]
144092f3ab15Sopenharmony_ci    fn test_pseudo_rand_range() {
144192f3ab15Sopenharmony_ci        let range = BigNum::from_u32(909_829_283).unwrap();
144292f3ab15Sopenharmony_ci        let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
144392f3ab15Sopenharmony_ci        range.pseudo_rand_range(&mut result).unwrap();
144492f3ab15Sopenharmony_ci        assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
144592f3ab15Sopenharmony_ci    }
144692f3ab15Sopenharmony_ci
144792f3ab15Sopenharmony_ci    #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
144892f3ab15Sopenharmony_ci    #[test]
144992f3ab15Sopenharmony_ci    fn test_prime_numbers() {
145092f3ab15Sopenharmony_ci        let a = BigNum::from_u32(19_029_017).unwrap();
145192f3ab15Sopenharmony_ci        let mut p = BigNum::new().unwrap();
145292f3ab15Sopenharmony_ci        p.generate_prime(128, true, None, Some(&a)).unwrap();
145392f3ab15Sopenharmony_ci
145492f3ab15Sopenharmony_ci        let mut ctx = BigNumContext::new().unwrap();
145592f3ab15Sopenharmony_ci        assert!(p.is_prime(100, &mut ctx).unwrap());
145692f3ab15Sopenharmony_ci        assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
145792f3ab15Sopenharmony_ci    }
145892f3ab15Sopenharmony_ci
145992f3ab15Sopenharmony_ci    #[cfg(ossl110)]
146092f3ab15Sopenharmony_ci    #[test]
146192f3ab15Sopenharmony_ci    fn test_secure_bn_ctx() {
146292f3ab15Sopenharmony_ci        let mut cxt = BigNumContext::new_secure().unwrap();
146392f3ab15Sopenharmony_ci        let a = BigNum::from_u32(8).unwrap();
146492f3ab15Sopenharmony_ci        let b = BigNum::from_u32(3).unwrap();
146592f3ab15Sopenharmony_ci
146692f3ab15Sopenharmony_ci        let mut remainder = BigNum::new().unwrap();
146792f3ab15Sopenharmony_ci        remainder.nnmod(&a, &b, &mut cxt).unwrap();
146892f3ab15Sopenharmony_ci
146992f3ab15Sopenharmony_ci        assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
147092f3ab15Sopenharmony_ci    }
147192f3ab15Sopenharmony_ci
147292f3ab15Sopenharmony_ci    #[cfg(ossl110)]
147392f3ab15Sopenharmony_ci    #[test]
147492f3ab15Sopenharmony_ci    fn test_secure_bn() {
147592f3ab15Sopenharmony_ci        let a = BigNum::new().unwrap();
147692f3ab15Sopenharmony_ci        assert!(!a.is_secure());
147792f3ab15Sopenharmony_ci
147892f3ab15Sopenharmony_ci        let b = BigNum::new_secure().unwrap();
147992f3ab15Sopenharmony_ci        assert!(b.is_secure())
148092f3ab15Sopenharmony_ci    }
148192f3ab15Sopenharmony_ci
148292f3ab15Sopenharmony_ci    #[cfg(ossl110)]
148392f3ab15Sopenharmony_ci    #[test]
148492f3ab15Sopenharmony_ci    fn test_const_time_bn() {
148592f3ab15Sopenharmony_ci        let a = BigNum::new().unwrap();
148692f3ab15Sopenharmony_ci        assert!(!a.is_const_time());
148792f3ab15Sopenharmony_ci
148892f3ab15Sopenharmony_ci        let mut b = BigNum::new().unwrap();
148992f3ab15Sopenharmony_ci        b.set_const_time();
149092f3ab15Sopenharmony_ci        assert!(b.is_const_time())
149192f3ab15Sopenharmony_ci    }
149292f3ab15Sopenharmony_ci
149392f3ab15Sopenharmony_ci    #[cfg(ossl110)]
149492f3ab15Sopenharmony_ci    #[test]
149592f3ab15Sopenharmony_ci    fn test_mod_sqrt() {
149692f3ab15Sopenharmony_ci        let mut ctx = BigNumContext::new().unwrap();
149792f3ab15Sopenharmony_ci
149892f3ab15Sopenharmony_ci        let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap();
149992f3ab15Sopenharmony_ci        let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap();
150092f3ab15Sopenharmony_ci        let mut out = BigNum::new().unwrap();
150192f3ab15Sopenharmony_ci
150292f3ab15Sopenharmony_ci        out.mod_sqrt(&s, &p, &mut ctx).unwrap();
150392f3ab15Sopenharmony_ci        assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap());
150492f3ab15Sopenharmony_ci    }
150592f3ab15Sopenharmony_ci
150692f3ab15Sopenharmony_ci    #[test]
150792f3ab15Sopenharmony_ci    #[cfg(any(ossl110, boringssl, libressl350))]
150892f3ab15Sopenharmony_ci    fn test_odd_even() {
150992f3ab15Sopenharmony_ci        let a = BigNum::from_u32(17).unwrap();
151092f3ab15Sopenharmony_ci        let b = BigNum::from_u32(18).unwrap();
151192f3ab15Sopenharmony_ci
151292f3ab15Sopenharmony_ci        assert!(a.is_odd());
151392f3ab15Sopenharmony_ci        assert!(!b.is_odd());
151492f3ab15Sopenharmony_ci
151592f3ab15Sopenharmony_ci        assert!(!a.is_even());
151692f3ab15Sopenharmony_ci        assert!(b.is_even());
151792f3ab15Sopenharmony_ci    }
151892f3ab15Sopenharmony_ci}
1519