• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)]
658     #[cfg(ossl110)]
mod_sqrt( &mut self, a: &BigNumRef, p: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>659     pub fn mod_sqrt(
660         &mut self,
661         a: &BigNumRef,
662         p: &BigNumRef,
663         ctx: &mut BigNumContextRef,
664     ) -> Result<(), ErrorStack> {
665         unsafe {
666             cvt_p(ffi::BN_mod_sqrt(
667                 self.as_ptr(),
668                 a.as_ptr(),
669                 p.as_ptr(),
670                 ctx.as_ptr(),
671             ))
672             .map(|_| ())
673         }
674     }
675 
676     /// Places the result of `a^p` in `self`.
677     #[corresponds(BN_exp)]
exp( &mut self, a: &BigNumRef, p: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>678     pub fn exp(
679         &mut self,
680         a: &BigNumRef,
681         p: &BigNumRef,
682         ctx: &mut BigNumContextRef,
683     ) -> Result<(), ErrorStack> {
684         unsafe {
685             cvt(ffi::BN_exp(
686                 self.as_ptr(),
687                 a.as_ptr(),
688                 p.as_ptr(),
689                 ctx.as_ptr(),
690             ))
691             .map(|_| ())
692         }
693     }
694 
695     /// Places the result of `a^p mod m` in `self`.
696     #[corresponds(BN_mod_exp)]
mod_exp( &mut self, a: &BigNumRef, p: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>697     pub fn mod_exp(
698         &mut self,
699         a: &BigNumRef,
700         p: &BigNumRef,
701         m: &BigNumRef,
702         ctx: &mut BigNumContextRef,
703     ) -> Result<(), ErrorStack> {
704         unsafe {
705             cvt(ffi::BN_mod_exp(
706                 self.as_ptr(),
707                 a.as_ptr(),
708                 p.as_ptr(),
709                 m.as_ptr(),
710                 ctx.as_ptr(),
711             ))
712             .map(|_| ())
713         }
714     }
715 
716     /// Places the inverse of `a` modulo `n` in `self`.
717     #[corresponds(BN_mod_inverse)]
mod_inverse( &mut self, a: &BigNumRef, n: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>718     pub fn mod_inverse(
719         &mut self,
720         a: &BigNumRef,
721         n: &BigNumRef,
722         ctx: &mut BigNumContextRef,
723     ) -> Result<(), ErrorStack> {
724         unsafe {
725             cvt_p(ffi::BN_mod_inverse(
726                 self.as_ptr(),
727                 a.as_ptr(),
728                 n.as_ptr(),
729                 ctx.as_ptr(),
730             ))
731             .map(|_| ())
732         }
733     }
734 
735     /// Places the greatest common denominator of `a` and `b` in `self`.
736     #[corresponds(BN_gcd)]
gcd( &mut self, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>737     pub fn gcd(
738         &mut self,
739         a: &BigNumRef,
740         b: &BigNumRef,
741         ctx: &mut BigNumContextRef,
742     ) -> Result<(), ErrorStack> {
743         unsafe {
744             cvt(ffi::BN_gcd(
745                 self.as_ptr(),
746                 a.as_ptr(),
747                 b.as_ptr(),
748                 ctx.as_ptr(),
749             ))
750             .map(|_| ())
751         }
752     }
753 
754     /// Checks whether `self` is prime.
755     ///
756     /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
757     ///
758     /// # Return Value
759     ///
760     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
761     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
762     #[corresponds(BN_is_prime_ex)]
763     #[allow(clippy::useless_conversion)]
is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack>764     pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
765         unsafe {
766             cvt_n(ffi::BN_is_prime_ex(
767                 self.as_ptr(),
768                 checks.into(),
769                 ctx.as_ptr(),
770                 ptr::null_mut(),
771             ))
772             .map(|r| r != 0)
773         }
774     }
775 
776     /// Checks whether `self` is prime with optional trial division.
777     ///
778     /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
779     /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
780     /// iterations.
781     ///
782     /// # Return Value
783     ///
784     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
785     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
786     #[corresponds(BN_is_prime_fasttest_ex)]
787     #[allow(clippy::useless_conversion)]
is_prime_fasttest( &self, checks: i32, ctx: &mut BigNumContextRef, do_trial_division: bool, ) -> Result<bool, ErrorStack>788     pub fn is_prime_fasttest(
789         &self,
790         checks: i32,
791         ctx: &mut BigNumContextRef,
792         do_trial_division: bool,
793     ) -> Result<bool, ErrorStack> {
794         unsafe {
795             cvt_n(ffi::BN_is_prime_fasttest_ex(
796                 self.as_ptr(),
797                 checks.into(),
798                 ctx.as_ptr(),
799                 do_trial_division as c_int,
800                 ptr::null_mut(),
801             ))
802             .map(|r| r != 0)
803         }
804     }
805 
806     /// Returns a big-endian byte vector representation of the absolute value of `self`.
807     ///
808     /// `self` can be recreated by using `from_slice`.
809     ///
810     /// ```
811     /// # use openssl::bn::BigNum;
812     /// let s = -BigNum::from_u32(4543).unwrap();
813     /// let r = BigNum::from_u32(4543).unwrap();
814     ///
815     /// let s_vec = s.to_vec();
816     /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
817     /// ```
818     #[corresponds(BN_bn2bin)]
to_vec(&self) -> Vec<u8>819     pub fn to_vec(&self) -> Vec<u8> {
820         let size = self.num_bytes() as usize;
821         let mut v = Vec::with_capacity(size);
822         unsafe {
823             ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
824             v.set_len(size);
825         }
826         v
827     }
828 
829     /// Returns a big-endian byte vector representation of the absolute value of `self` padded
830     /// to `pad_to` bytes.
831     ///
832     /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
833     ///
834     /// `self` can be recreated by using `from_slice`.
835     ///
836     /// ```
837     /// # use openssl::bn::BigNum;
838     /// let bn = BigNum::from_u32(0x4543).unwrap();
839     ///
840     /// let bn_vec = bn.to_vec_padded(4).unwrap();
841     /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
842     ///
843     /// let r = bn.to_vec_padded(1);
844     /// assert!(r.is_err());
845     ///
846     /// let bn = -BigNum::from_u32(0x4543).unwrap();
847     /// let bn_vec = bn.to_vec_padded(4).unwrap();
848     /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
849     /// ```
850     #[corresponds(BN_bn2binpad)]
851     #[cfg(any(ossl110, libressl340, boringssl))]
to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack>852     pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
853         let mut v = Vec::with_capacity(pad_to as usize);
854         unsafe {
855             cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
856             v.set_len(pad_to as usize);
857         }
858         Ok(v)
859     }
860 
861     /// Returns a decimal string representation of `self`.
862     ///
863     /// ```
864     /// # use openssl::bn::BigNum;
865     /// let s = -BigNum::from_u32(12345).unwrap();
866     ///
867     /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
868     /// ```
869     #[corresponds(BN_bn2dec)]
to_dec_str(&self) -> Result<OpensslString, ErrorStack>870     pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
871         unsafe {
872             let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
873             Ok(OpensslString::from_ptr(buf))
874         }
875     }
876 
877     /// Returns a hexadecimal string representation of `self`.
878     ///
879     /// ```
880     /// # use openssl::bn::BigNum;
881     /// let s = -BigNum::from_u32(0x99ff).unwrap();
882     ///
883     /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
884     /// ```
885     #[corresponds(BN_bn2hex)]
to_hex_str(&self) -> Result<OpensslString, ErrorStack>886     pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
887         unsafe {
888             let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
889             Ok(OpensslString::from_ptr(buf))
890         }
891     }
892 
893     /// Returns an `Asn1Integer` containing the value of `self`.
894     #[corresponds(BN_to_ASN1_INTEGER)]
to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack>895     pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
896         unsafe {
897             cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
898                 .map(|p| Asn1Integer::from_ptr(p))
899         }
900     }
901 
902     /// Force constant time computation on this value.
903     #[corresponds(BN_set_flags)]
904     #[cfg(ossl110)]
set_const_time(&mut self)905     pub fn set_const_time(&mut self) {
906         unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
907     }
908 
909     /// Returns true if `self` is in const time mode.
910     #[corresponds(BN_get_flags)]
911     #[cfg(ossl110)]
is_const_time(&self) -> bool912     pub fn is_const_time(&self) -> bool {
913         unsafe {
914             let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
915             ret == ffi::BN_FLG_CONSTTIME
916         }
917     }
918 
919     /// Returns true if `self` was created with [`BigNum::new_secure`].
920     #[corresponds(BN_get_flags)]
921     #[cfg(ossl110)]
is_secure(&self) -> bool922     pub fn is_secure(&self) -> bool {
923         unsafe {
924             let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
925             ret == ffi::BN_FLG_SECURE
926         }
927     }
928 }
929 
930 impl BigNum {
931     /// Creates a new `BigNum` with the value 0.
932     #[corresponds(BN_new)]
new() -> Result<BigNum, ErrorStack>933     pub fn new() -> Result<BigNum, ErrorStack> {
934         unsafe {
935             ffi::init();
936             let v = cvt_p(ffi::BN_new())?;
937             Ok(BigNum::from_ptr(v))
938         }
939     }
940 
941     /// Returns a new secure `BigNum`.
942     #[corresponds(BN_secure_new)]
943     #[cfg(ossl110)]
new_secure() -> Result<BigNum, ErrorStack>944     pub fn new_secure() -> Result<BigNum, ErrorStack> {
945         unsafe {
946             ffi::init();
947             let v = cvt_p(ffi::BN_secure_new())?;
948             Ok(BigNum::from_ptr(v))
949         }
950     }
951 
952     /// Creates a new `BigNum` with the given value.
953     #[corresponds(BN_set_word)]
from_u32(n: u32) -> Result<BigNum, ErrorStack>954     pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
955         BigNum::new().and_then(|v| unsafe {
956             cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
957         })
958     }
959 
960     /// Creates a `BigNum` from a decimal string.
961     #[corresponds(BN_dec2bn)]
from_dec_str(s: &str) -> Result<BigNum, ErrorStack>962     pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
963         unsafe {
964             ffi::init();
965             let c_str = CString::new(s.as_bytes()).unwrap();
966             let mut bn = ptr::null_mut();
967             cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?;
968             Ok(BigNum::from_ptr(bn))
969         }
970     }
971 
972     /// Creates a `BigNum` from a hexadecimal string.
973     #[corresponds(BN_hex2bn)]
from_hex_str(s: &str) -> Result<BigNum, ErrorStack>974     pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
975         unsafe {
976             ffi::init();
977             let c_str = CString::new(s.as_bytes()).unwrap();
978             let mut bn = ptr::null_mut();
979             cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?;
980             Ok(BigNum::from_ptr(bn))
981         }
982     }
983 
984     /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
985     /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
986     /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
987     ///
988     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
989     #[corresponds(BN_get_rfc2409_prime_768)]
990     #[cfg(not(boringssl))]
get_rfc2409_prime_768() -> Result<BigNum, ErrorStack>991     pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
992         unsafe {
993             ffi::init();
994             cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
995         }
996     }
997 
998     /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
999     /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
1000     /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
1001     ///
1002     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
1003     #[corresponds(BN_get_rfc2409_prime_1024)]
1004     #[cfg(not(boringssl))]
get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack>1005     pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
1006         unsafe {
1007             ffi::init();
1008             cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
1009         }
1010     }
1011 
1012     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1013     /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
1014     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
1015     ///
1016     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1017     #[corresponds(BN_get_rfc3526_prime_1536)]
1018     #[cfg(not(boringssl))]
get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack>1019     pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
1020         unsafe {
1021             ffi::init();
1022             cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
1023         }
1024     }
1025 
1026     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1027     /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
1028     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
1029     ///
1030     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
1031     #[corresponds(BN_get_rfc3526_prime_2048)]
1032     #[cfg(not(boringssl))]
get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack>1033     pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
1034         unsafe {
1035             ffi::init();
1036             cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
1037         }
1038     }
1039 
1040     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1041     /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
1042     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
1043     ///
1044     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1045     #[corresponds(BN_get_rfc3526_prime_3072)]
1046     #[cfg(not(boringssl))]
get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack>1047     pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
1048         unsafe {
1049             ffi::init();
1050             cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
1051         }
1052     }
1053 
1054     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1055     /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
1056     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
1057     ///
1058     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1059     #[corresponds(BN_get_rfc3526_prime_4096)]
1060     #[cfg(not(boringssl))]
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     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1073     #[corresponds(BN_get_rfc3526_prime_6114)]
1074     #[cfg(not(boringssl))]
get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack>1075     pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
1076         unsafe {
1077             ffi::init();
1078             cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
1079         }
1080     }
1081 
1082     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1083     /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
1084     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
1085     ///
1086     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1087     #[corresponds(BN_get_rfc3526_prime_8192)]
1088     #[cfg(not(boringssl))]
get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack>1089     pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
1090         unsafe {
1091             ffi::init();
1092             cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
1093         }
1094     }
1095 
1096     /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
1097     ///
1098     /// OpenSSL documentation at [`BN_bin2bn`]
1099     ///
1100     /// [`BN_bin2bn`]: https://www.openssl.org/docs/manmaster/crypto/BN_bin2bn.html
1101     ///
1102     /// ```
1103     /// # use openssl::bn::BigNum;
1104     /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
1105     ///
1106     /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1107     /// ```
1108     #[corresponds(BN_bin2bn)]
from_slice(n: &[u8]) -> Result<BigNum, ErrorStack>1109     pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
1110         unsafe {
1111             ffi::init();
1112             assert!(n.len() <= LenType::max_value() as usize);
1113 
1114             cvt_p(ffi::BN_bin2bn(
1115                 n.as_ptr(),
1116                 n.len() as LenType,
1117                 ptr::null_mut(),
1118             ))
1119             .map(|p| BigNum::from_ptr(p))
1120         }
1121     }
1122 
1123     /// Copies data from a slice overwriting what was in the BigNum.
1124     ///
1125     /// This function can be used to copy data from a slice to a
1126     /// [secure BigNum][`BigNum::new_secure`].
1127     ///
1128     /// # Examples
1129     ///
1130     /// ```
1131     /// # use openssl::bn::BigNum;
1132     /// let mut bignum = BigNum::new().unwrap();
1133     /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
1134     ///
1135     /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1136     /// ```
1137     #[corresponds(BN_bin2bn)]
copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack>1138     pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
1139         unsafe {
1140             assert!(n.len() <= LenType::max_value() as usize);
1141 
1142             cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
1143             Ok(())
1144         }
1145     }
1146 }
1147 
1148 impl fmt::Debug for BigNumRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1149     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150         match self.to_dec_str() {
1151             Ok(s) => f.write_str(&s),
1152             Err(e) => Err(e.into()),
1153         }
1154     }
1155 }
1156 
1157 impl fmt::Debug for BigNum {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1158     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1159         match self.to_dec_str() {
1160             Ok(s) => f.write_str(&s),
1161             Err(e) => Err(e.into()),
1162         }
1163     }
1164 }
1165 
1166 impl fmt::Display for BigNumRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1167     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1168         match self.to_dec_str() {
1169             Ok(s) => f.write_str(&s),
1170             Err(e) => Err(e.into()),
1171         }
1172     }
1173 }
1174 
1175 impl fmt::Display for BigNum {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1176     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1177         match self.to_dec_str() {
1178             Ok(s) => f.write_str(&s),
1179             Err(e) => Err(e.into()),
1180         }
1181     }
1182 }
1183 
1184 impl PartialEq<BigNumRef> for BigNumRef {
eq(&self, oth: &BigNumRef) -> bool1185     fn eq(&self, oth: &BigNumRef) -> bool {
1186         self.cmp(oth) == Ordering::Equal
1187     }
1188 }
1189 
1190 impl PartialEq<BigNum> for BigNumRef {
eq(&self, oth: &BigNum) -> bool1191     fn eq(&self, oth: &BigNum) -> bool {
1192         self.eq(oth.deref())
1193     }
1194 }
1195 
1196 impl Eq for BigNumRef {}
1197 
1198 impl PartialEq for BigNum {
eq(&self, oth: &BigNum) -> bool1199     fn eq(&self, oth: &BigNum) -> bool {
1200         self.deref().eq(oth)
1201     }
1202 }
1203 
1204 impl PartialEq<BigNumRef> for BigNum {
eq(&self, oth: &BigNumRef) -> bool1205     fn eq(&self, oth: &BigNumRef) -> bool {
1206         self.deref().eq(oth)
1207     }
1208 }
1209 
1210 impl Eq for BigNum {}
1211 
1212 impl PartialOrd<BigNumRef> for BigNumRef {
partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering>1213     fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1214         Some(self.cmp(oth))
1215     }
1216 }
1217 
1218 impl PartialOrd<BigNum> for BigNumRef {
partial_cmp(&self, oth: &BigNum) -> Option<Ordering>1219     fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1220         Some(self.cmp(oth.deref()))
1221     }
1222 }
1223 
1224 impl Ord for BigNumRef {
cmp(&self, oth: &BigNumRef) -> Ordering1225     fn cmp(&self, oth: &BigNumRef) -> Ordering {
1226         unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
1227     }
1228 }
1229 
1230 impl PartialOrd for BigNum {
partial_cmp(&self, oth: &BigNum) -> Option<Ordering>1231     fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1232         self.deref().partial_cmp(oth.deref())
1233     }
1234 }
1235 
1236 impl PartialOrd<BigNumRef> for BigNum {
partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering>1237     fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1238         self.deref().partial_cmp(oth)
1239     }
1240 }
1241 
1242 impl Ord for BigNum {
cmp(&self, oth: &BigNum) -> Ordering1243     fn cmp(&self, oth: &BigNum) -> Ordering {
1244         self.deref().cmp(oth.deref())
1245     }
1246 }
1247 
1248 macro_rules! delegate {
1249     ($t:ident, $m:ident) => {
1250         impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
1251             type Output = BigNum;
1252 
1253             fn $m(self, oth: &BigNum) -> BigNum {
1254                 $t::$m(self, oth.deref())
1255             }
1256         }
1257 
1258         impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
1259             type Output = BigNum;
1260 
1261             fn $m(self, oth: &BigNumRef) -> BigNum {
1262                 $t::$m(self.deref(), oth)
1263             }
1264         }
1265 
1266         impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
1267             type Output = BigNum;
1268 
1269             fn $m(self, oth: &BigNum) -> BigNum {
1270                 $t::$m(self.deref(), oth.deref())
1271             }
1272         }
1273     };
1274 }
1275 
1276 impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
1277     type Output = BigNum;
1278 
add(self, oth: &BigNumRef) -> BigNum1279     fn add(self, oth: &BigNumRef) -> BigNum {
1280         let mut r = BigNum::new().unwrap();
1281         r.checked_add(self, oth).unwrap();
1282         r
1283     }
1284 }
1285 
1286 delegate!(Add, add);
1287 
1288 impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
1289     type Output = BigNum;
1290 
sub(self, oth: &BigNumRef) -> BigNum1291     fn sub(self, oth: &BigNumRef) -> BigNum {
1292         let mut r = BigNum::new().unwrap();
1293         r.checked_sub(self, oth).unwrap();
1294         r
1295     }
1296 }
1297 
1298 delegate!(Sub, sub);
1299 
1300 impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
1301     type Output = BigNum;
1302 
mul(self, oth: &BigNumRef) -> BigNum1303     fn mul(self, oth: &BigNumRef) -> BigNum {
1304         let mut ctx = BigNumContext::new().unwrap();
1305         let mut r = BigNum::new().unwrap();
1306         r.checked_mul(self, oth, &mut ctx).unwrap();
1307         r
1308     }
1309 }
1310 
1311 delegate!(Mul, mul);
1312 
1313 impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
1314     type Output = BigNum;
1315 
div(self, oth: &'b BigNumRef) -> BigNum1316     fn div(self, oth: &'b BigNumRef) -> BigNum {
1317         let mut ctx = BigNumContext::new().unwrap();
1318         let mut r = BigNum::new().unwrap();
1319         r.checked_div(self, oth, &mut ctx).unwrap();
1320         r
1321     }
1322 }
1323 
1324 delegate!(Div, div);
1325 
1326 impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
1327     type Output = BigNum;
1328 
rem(self, oth: &'b BigNumRef) -> BigNum1329     fn rem(self, oth: &'b BigNumRef) -> BigNum {
1330         let mut ctx = BigNumContext::new().unwrap();
1331         let mut r = BigNum::new().unwrap();
1332         r.checked_rem(self, oth, &mut ctx).unwrap();
1333         r
1334     }
1335 }
1336 
1337 delegate!(Rem, rem);
1338 
1339 impl<'a> Shl<i32> for &'a BigNumRef {
1340     type Output = BigNum;
1341 
shl(self, n: i32) -> BigNum1342     fn shl(self, n: i32) -> BigNum {
1343         let mut r = BigNum::new().unwrap();
1344         r.lshift(self, n).unwrap();
1345         r
1346     }
1347 }
1348 
1349 impl<'a> Shl<i32> for &'a BigNum {
1350     type Output = BigNum;
1351 
shl(self, n: i32) -> BigNum1352     fn shl(self, n: i32) -> BigNum {
1353         self.deref().shl(n)
1354     }
1355 }
1356 
1357 impl<'a> Shr<i32> for &'a BigNumRef {
1358     type Output = BigNum;
1359 
shr(self, n: i32) -> BigNum1360     fn shr(self, n: i32) -> BigNum {
1361         let mut r = BigNum::new().unwrap();
1362         r.rshift(self, n).unwrap();
1363         r
1364     }
1365 }
1366 
1367 impl<'a> Shr<i32> for &'a BigNum {
1368     type Output = BigNum;
1369 
shr(self, n: i32) -> BigNum1370     fn shr(self, n: i32) -> BigNum {
1371         self.deref().shr(n)
1372     }
1373 }
1374 
1375 impl<'a> Neg for &'a BigNumRef {
1376     type Output = BigNum;
1377 
neg(self) -> BigNum1378     fn neg(self) -> BigNum {
1379         self.to_owned().unwrap().neg()
1380     }
1381 }
1382 
1383 impl<'a> Neg for &'a BigNum {
1384     type Output = BigNum;
1385 
neg(self) -> BigNum1386     fn neg(self) -> BigNum {
1387         self.deref().neg()
1388     }
1389 }
1390 
1391 impl Neg for BigNum {
1392     type Output = BigNum;
1393 
neg(mut self) -> BigNum1394     fn neg(mut self) -> BigNum {
1395         let negative = self.is_negative();
1396         self.set_negative(!negative);
1397         self
1398     }
1399 }
1400 
1401 #[cfg(test)]
1402 mod tests {
1403     use crate::bn::{BigNum, BigNumContext};
1404 
1405     #[test]
test_to_from_slice()1406     fn test_to_from_slice() {
1407         let v0 = BigNum::from_u32(10_203_004).unwrap();
1408         let vec = v0.to_vec();
1409         let v1 = BigNum::from_slice(&vec).unwrap();
1410 
1411         assert_eq!(v0, v1);
1412     }
1413 
1414     #[test]
test_negation()1415     fn test_negation() {
1416         let a = BigNum::from_u32(909_829_283).unwrap();
1417 
1418         assert!(!a.is_negative());
1419         assert!((-a).is_negative());
1420     }
1421 
1422     #[test]
test_shift()1423     fn test_shift() {
1424         let a = BigNum::from_u32(909_829_283).unwrap();
1425 
1426         assert_eq!(a, &(&a << 1) >> 1);
1427     }
1428 
1429     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1430     #[test]
test_rand_range()1431     fn test_rand_range() {
1432         let range = BigNum::from_u32(909_829_283).unwrap();
1433         let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1434         range.rand_range(&mut result).unwrap();
1435         assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1436     }
1437 
1438     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1439     #[test]
test_pseudo_rand_range()1440     fn test_pseudo_rand_range() {
1441         let range = BigNum::from_u32(909_829_283).unwrap();
1442         let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1443         range.pseudo_rand_range(&mut result).unwrap();
1444         assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1445     }
1446 
1447     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1448     #[test]
test_prime_numbers()1449     fn test_prime_numbers() {
1450         let a = BigNum::from_u32(19_029_017).unwrap();
1451         let mut p = BigNum::new().unwrap();
1452         p.generate_prime(128, true, None, Some(&a)).unwrap();
1453 
1454         let mut ctx = BigNumContext::new().unwrap();
1455         assert!(p.is_prime(100, &mut ctx).unwrap());
1456         assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
1457     }
1458 
1459     #[cfg(ossl110)]
1460     #[test]
test_secure_bn_ctx()1461     fn test_secure_bn_ctx() {
1462         let mut cxt = BigNumContext::new_secure().unwrap();
1463         let a = BigNum::from_u32(8).unwrap();
1464         let b = BigNum::from_u32(3).unwrap();
1465 
1466         let mut remainder = BigNum::new().unwrap();
1467         remainder.nnmod(&a, &b, &mut cxt).unwrap();
1468 
1469         assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
1470     }
1471 
1472     #[cfg(ossl110)]
1473     #[test]
test_secure_bn()1474     fn test_secure_bn() {
1475         let a = BigNum::new().unwrap();
1476         assert!(!a.is_secure());
1477 
1478         let b = BigNum::new_secure().unwrap();
1479         assert!(b.is_secure())
1480     }
1481 
1482     #[cfg(ossl110)]
1483     #[test]
test_const_time_bn()1484     fn test_const_time_bn() {
1485         let a = BigNum::new().unwrap();
1486         assert!(!a.is_const_time());
1487 
1488         let mut b = BigNum::new().unwrap();
1489         b.set_const_time();
1490         assert!(b.is_const_time())
1491     }
1492 
1493     #[cfg(ossl110)]
1494     #[test]
test_mod_sqrt()1495     fn test_mod_sqrt() {
1496         let mut ctx = BigNumContext::new().unwrap();
1497 
1498         let s = BigNum::from_hex_str("47A8DD7626B9908C80ACD7E0D3344D69").unwrap();
1499         let p = BigNum::from_hex_str("81EF47265B58BCE5").unwrap();
1500         let mut out = BigNum::new().unwrap();
1501 
1502         out.mod_sqrt(&s, &p, &mut ctx).unwrap();
1503         assert_eq!(out, BigNum::from_hex_str("7C6D179E19B97BDD").unwrap());
1504     }
1505 
1506     #[test]
1507     #[cfg(any(ossl110, boringssl, libressl350))]
test_odd_even()1508     fn test_odd_even() {
1509         let a = BigNum::from_u32(17).unwrap();
1510         let b = BigNum::from_u32(18).unwrap();
1511 
1512         assert!(a.is_odd());
1513         assert!(!b.is_odd());
1514 
1515         assert!(!a.is_even());
1516         assert!(b.is_even());
1517     }
1518 }
1519