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