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