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