• 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/man1.1.0/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/man1.1.0/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 the number of significant bits in `self`.
339     #[corresponds(BN_num_bits)]
340     #[allow(clippy::unnecessary_cast)]
num_bits(&self) -> i32341     pub fn num_bits(&self) -> i32 {
342         unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
343     }
344 
345     /// Returns the size of `self` in bytes. Implemented natively.
num_bytes(&self) -> i32346     pub fn num_bytes(&self) -> i32 {
347         (self.num_bits() + 7) / 8
348     }
349 
350     /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
351     ///
352     /// # Parameters
353     ///
354     /// * `bits`: Length of the number in bits.
355     /// * `msb`: The desired properties of the most significant bit. See [`constants`].
356     /// * `odd`: If `true`, the generated number will be odd.
357     ///
358     /// # Examples
359     ///
360     /// ```
361     /// use openssl::bn::{BigNum, MsbOption};
362     /// use openssl::error::ErrorStack;
363     ///
364     /// fn generate_random() -> Result< BigNum, ErrorStack > {
365     ///    let mut big = BigNum::new()?;
366     ///
367     ///    // Generates a 128-bit odd random number
368     ///    big.rand(128, MsbOption::MAYBE_ZERO, true);
369     ///    Ok((big))
370     /// }
371     /// ```
372     ///
373     /// [`constants`]: index.html#constants
374     #[corresponds(BN_rand)]
375     #[allow(clippy::useless_conversion)]
rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack>376     pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
377         unsafe {
378             cvt(ffi::BN_rand(
379                 self.as_ptr(),
380                 bits.into(),
381                 msb.0,
382                 odd as c_int,
383             ))
384             .map(|_| ())
385         }
386     }
387 
388     /// The cryptographically weak counterpart to `rand`.  Not suitable for key generation.
389     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
390     #[corresponds(BN_pseudo_rand)]
391     #[allow(clippy::useless_conversion)]
pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack>392     pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
393         unsafe {
394             cvt(ffi::BN_pseudo_rand(
395                 self.as_ptr(),
396                 bits.into(),
397                 msb.0,
398                 odd as c_int,
399             ))
400             .map(|_| ())
401         }
402     }
403 
404     /// Generates a prime number, placing it in `self`.
405     ///
406     /// # Parameters
407     ///
408     /// * `bits`: The length of the prime in bits (lower bound).
409     /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
410     /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
411     ///   generated prime and `rem` is `1` if not specified (`None`).
412     ///
413     /// # Examples
414     ///
415     /// ```
416     /// use openssl::bn::BigNum;
417     /// use openssl::error::ErrorStack;
418     ///
419     /// fn generate_weak_prime() -> Result< BigNum, ErrorStack > {
420     ///    let mut big = BigNum::new()?;
421     ///
422     ///    // Generates a 128-bit simple prime number
423     ///    big.generate_prime(128, false, None, None);
424     ///    Ok((big))
425     /// }
426     /// ```
427     #[corresponds(BN_generate_prime_ex)]
generate_prime( &mut self, bits: i32, safe: bool, add: Option<&BigNumRef>, rem: Option<&BigNumRef>, ) -> Result<(), ErrorStack>428     pub fn generate_prime(
429         &mut self,
430         bits: i32,
431         safe: bool,
432         add: Option<&BigNumRef>,
433         rem: Option<&BigNumRef>,
434     ) -> Result<(), ErrorStack> {
435         unsafe {
436             cvt(ffi::BN_generate_prime_ex(
437                 self.as_ptr(),
438                 bits as c_int,
439                 safe as c_int,
440                 add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
441                 rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
442                 ptr::null_mut(),
443             ))
444             .map(|_| ())
445         }
446     }
447 
448     /// Places the result of `a * b` in `self`.
449     /// [`core::ops::Mul`] is also implemented for `BigNumRef`.
450     ///
451     /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul
452     #[corresponds(BN_mul)]
checked_mul( &mut self, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>453     pub fn checked_mul(
454         &mut self,
455         a: &BigNumRef,
456         b: &BigNumRef,
457         ctx: &mut BigNumContextRef,
458     ) -> Result<(), ErrorStack> {
459         unsafe {
460             cvt(ffi::BN_mul(
461                 self.as_ptr(),
462                 a.as_ptr(),
463                 b.as_ptr(),
464                 ctx.as_ptr(),
465             ))
466             .map(|_| ())
467         }
468     }
469 
470     /// Places the result of `a / b` in `self`. The remainder is discarded.
471     /// [`core::ops::Div`] is also implemented for `BigNumRef`.
472     ///
473     /// [`core::ops::Div`]: struct.BigNumRef.html#method.div
474     #[corresponds(BN_div)]
checked_div( &mut self, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>475     pub fn checked_div(
476         &mut self,
477         a: &BigNumRef,
478         b: &BigNumRef,
479         ctx: &mut BigNumContextRef,
480     ) -> Result<(), ErrorStack> {
481         unsafe {
482             cvt(ffi::BN_div(
483                 self.as_ptr(),
484                 ptr::null_mut(),
485                 a.as_ptr(),
486                 b.as_ptr(),
487                 ctx.as_ptr(),
488             ))
489             .map(|_| ())
490         }
491     }
492 
493     /// Places the result of `a % b` in `self`.
494     #[corresponds(BN_div)]
checked_rem( &mut self, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>495     pub fn checked_rem(
496         &mut self,
497         a: &BigNumRef,
498         b: &BigNumRef,
499         ctx: &mut BigNumContextRef,
500     ) -> Result<(), ErrorStack> {
501         unsafe {
502             cvt(ffi::BN_div(
503                 ptr::null_mut(),
504                 self.as_ptr(),
505                 a.as_ptr(),
506                 b.as_ptr(),
507                 ctx.as_ptr(),
508             ))
509             .map(|_| ())
510         }
511     }
512 
513     /// Places the result of `a / b` in `self` and `a % b` in `rem`.
514     #[corresponds(BN_div)]
div_rem( &mut self, rem: &mut BigNumRef, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>515     pub fn div_rem(
516         &mut self,
517         rem: &mut BigNumRef,
518         a: &BigNumRef,
519         b: &BigNumRef,
520         ctx: &mut BigNumContextRef,
521     ) -> Result<(), ErrorStack> {
522         unsafe {
523             cvt(ffi::BN_div(
524                 self.as_ptr(),
525                 rem.as_ptr(),
526                 a.as_ptr(),
527                 b.as_ptr(),
528                 ctx.as_ptr(),
529             ))
530             .map(|_| ())
531         }
532     }
533 
534     /// Places the result of `a²` in `self`.
535     #[corresponds(BN_sqr)]
sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack>536     pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> {
537         unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
538     }
539 
540     /// Places the result of `a mod m` in `self`.  As opposed to `div_rem`
541     /// the result is non-negative.
542     #[corresponds(BN_nnmod)]
nnmod( &mut self, a: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>543     pub fn nnmod(
544         &mut self,
545         a: &BigNumRef,
546         m: &BigNumRef,
547         ctx: &mut BigNumContextRef,
548     ) -> Result<(), ErrorStack> {
549         unsafe {
550             cvt(ffi::BN_nnmod(
551                 self.as_ptr(),
552                 a.as_ptr(),
553                 m.as_ptr(),
554                 ctx.as_ptr(),
555             ))
556             .map(|_| ())
557         }
558     }
559 
560     /// Places the result of `(a + b) mod m` in `self`.
561     #[corresponds(BN_mod_add)]
mod_add( &mut self, a: &BigNumRef, b: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>562     pub fn mod_add(
563         &mut self,
564         a: &BigNumRef,
565         b: &BigNumRef,
566         m: &BigNumRef,
567         ctx: &mut BigNumContextRef,
568     ) -> Result<(), ErrorStack> {
569         unsafe {
570             cvt(ffi::BN_mod_add(
571                 self.as_ptr(),
572                 a.as_ptr(),
573                 b.as_ptr(),
574                 m.as_ptr(),
575                 ctx.as_ptr(),
576             ))
577             .map(|_| ())
578         }
579     }
580 
581     /// Places the result of `(a - b) mod m` in `self`.
582     #[corresponds(BN_mod_sub)]
mod_sub( &mut self, a: &BigNumRef, b: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>583     pub fn mod_sub(
584         &mut self,
585         a: &BigNumRef,
586         b: &BigNumRef,
587         m: &BigNumRef,
588         ctx: &mut BigNumContextRef,
589     ) -> Result<(), ErrorStack> {
590         unsafe {
591             cvt(ffi::BN_mod_sub(
592                 self.as_ptr(),
593                 a.as_ptr(),
594                 b.as_ptr(),
595                 m.as_ptr(),
596                 ctx.as_ptr(),
597             ))
598             .map(|_| ())
599         }
600     }
601 
602     /// Places the result of `(a * b) mod m` in `self`.
603     #[corresponds(BN_mod_mul)]
mod_mul( &mut self, a: &BigNumRef, b: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>604     pub fn mod_mul(
605         &mut self,
606         a: &BigNumRef,
607         b: &BigNumRef,
608         m: &BigNumRef,
609         ctx: &mut BigNumContextRef,
610     ) -> Result<(), ErrorStack> {
611         unsafe {
612             cvt(ffi::BN_mod_mul(
613                 self.as_ptr(),
614                 a.as_ptr(),
615                 b.as_ptr(),
616                 m.as_ptr(),
617                 ctx.as_ptr(),
618             ))
619             .map(|_| ())
620         }
621     }
622 
623     /// Places the result of `a² mod m` in `self`.
624     #[corresponds(BN_mod_sqr)]
mod_sqr( &mut self, a: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>625     pub fn mod_sqr(
626         &mut self,
627         a: &BigNumRef,
628         m: &BigNumRef,
629         ctx: &mut BigNumContextRef,
630     ) -> Result<(), ErrorStack> {
631         unsafe {
632             cvt(ffi::BN_mod_sqr(
633                 self.as_ptr(),
634                 a.as_ptr(),
635                 m.as_ptr(),
636                 ctx.as_ptr(),
637             ))
638             .map(|_| ())
639         }
640     }
641 
642     /// Places the result of `a^p` in `self`.
643     #[corresponds(BN_exp)]
exp( &mut self, a: &BigNumRef, p: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>644     pub fn exp(
645         &mut self,
646         a: &BigNumRef,
647         p: &BigNumRef,
648         ctx: &mut BigNumContextRef,
649     ) -> Result<(), ErrorStack> {
650         unsafe {
651             cvt(ffi::BN_exp(
652                 self.as_ptr(),
653                 a.as_ptr(),
654                 p.as_ptr(),
655                 ctx.as_ptr(),
656             ))
657             .map(|_| ())
658         }
659     }
660 
661     /// Places the result of `a^p mod m` in `self`.
662     #[corresponds(BN_mod_exp)]
mod_exp( &mut self, a: &BigNumRef, p: &BigNumRef, m: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>663     pub fn mod_exp(
664         &mut self,
665         a: &BigNumRef,
666         p: &BigNumRef,
667         m: &BigNumRef,
668         ctx: &mut BigNumContextRef,
669     ) -> Result<(), ErrorStack> {
670         unsafe {
671             cvt(ffi::BN_mod_exp(
672                 self.as_ptr(),
673                 a.as_ptr(),
674                 p.as_ptr(),
675                 m.as_ptr(),
676                 ctx.as_ptr(),
677             ))
678             .map(|_| ())
679         }
680     }
681 
682     /// Places the inverse of `a` modulo `n` in `self`.
683     #[corresponds(BN_mod_inverse)]
mod_inverse( &mut self, a: &BigNumRef, n: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>684     pub fn mod_inverse(
685         &mut self,
686         a: &BigNumRef,
687         n: &BigNumRef,
688         ctx: &mut BigNumContextRef,
689     ) -> Result<(), ErrorStack> {
690         unsafe {
691             cvt_p(ffi::BN_mod_inverse(
692                 self.as_ptr(),
693                 a.as_ptr(),
694                 n.as_ptr(),
695                 ctx.as_ptr(),
696             ))
697             .map(|_| ())
698         }
699     }
700 
701     /// Places the greatest common denominator of `a` and `b` in `self`.
702     #[corresponds(BN_gcd)]
gcd( &mut self, a: &BigNumRef, b: &BigNumRef, ctx: &mut BigNumContextRef, ) -> Result<(), ErrorStack>703     pub fn gcd(
704         &mut self,
705         a: &BigNumRef,
706         b: &BigNumRef,
707         ctx: &mut BigNumContextRef,
708     ) -> Result<(), ErrorStack> {
709         unsafe {
710             cvt(ffi::BN_gcd(
711                 self.as_ptr(),
712                 a.as_ptr(),
713                 b.as_ptr(),
714                 ctx.as_ptr(),
715             ))
716             .map(|_| ())
717         }
718     }
719 
720     /// Checks whether `self` is prime.
721     ///
722     /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
723     ///
724     /// # Return Value
725     ///
726     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
727     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
728     #[corresponds(BN_is_prime_ex)]
729     #[allow(clippy::useless_conversion)]
is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack>730     pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result<bool, ErrorStack> {
731         unsafe {
732             cvt_n(ffi::BN_is_prime_ex(
733                 self.as_ptr(),
734                 checks.into(),
735                 ctx.as_ptr(),
736                 ptr::null_mut(),
737             ))
738             .map(|r| r != 0)
739         }
740     }
741 
742     /// Checks whether `self` is prime with optional trial division.
743     ///
744     /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
745     /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
746     /// iterations.
747     ///
748     /// # Return Value
749     ///
750     /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
751     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
752     #[corresponds(BN_is_prime_fasttest_ex)]
753     #[allow(clippy::useless_conversion)]
is_prime_fasttest( &self, checks: i32, ctx: &mut BigNumContextRef, do_trial_division: bool, ) -> Result<bool, ErrorStack>754     pub fn is_prime_fasttest(
755         &self,
756         checks: i32,
757         ctx: &mut BigNumContextRef,
758         do_trial_division: bool,
759     ) -> Result<bool, ErrorStack> {
760         unsafe {
761             cvt_n(ffi::BN_is_prime_fasttest_ex(
762                 self.as_ptr(),
763                 checks.into(),
764                 ctx.as_ptr(),
765                 do_trial_division as c_int,
766                 ptr::null_mut(),
767             ))
768             .map(|r| r != 0)
769         }
770     }
771 
772     /// Returns a big-endian byte vector representation of the absolute value of `self`.
773     ///
774     /// `self` can be recreated by using `from_slice`.
775     ///
776     /// ```
777     /// # use openssl::bn::BigNum;
778     /// let s = -BigNum::from_u32(4543).unwrap();
779     /// let r = BigNum::from_u32(4543).unwrap();
780     ///
781     /// let s_vec = s.to_vec();
782     /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
783     /// ```
784     #[corresponds(BN_bn2bin)]
to_vec(&self) -> Vec<u8>785     pub fn to_vec(&self) -> Vec<u8> {
786         let size = self.num_bytes() as usize;
787         let mut v = Vec::with_capacity(size);
788         unsafe {
789             ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
790             v.set_len(size);
791         }
792         v
793     }
794 
795     /// Returns a big-endian byte vector representation of the absolute value of `self` padded
796     /// to `pad_to` bytes.
797     ///
798     /// If `pad_to` is less than `self.num_bytes()` then an error is returned.
799     ///
800     /// `self` can be recreated by using `from_slice`.
801     ///
802     /// ```
803     /// # use openssl::bn::BigNum;
804     /// let bn = BigNum::from_u32(0x4543).unwrap();
805     ///
806     /// let bn_vec = bn.to_vec_padded(4).unwrap();
807     /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
808     ///
809     /// let r = bn.to_vec_padded(1);
810     /// assert!(r.is_err());
811     ///
812     /// let bn = -BigNum::from_u32(0x4543).unwrap();
813     /// let bn_vec = bn.to_vec_padded(4).unwrap();
814     /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]);
815     /// ```
816     #[corresponds(BN_bn2binpad)]
817     #[cfg(any(boringssl, ossl110))]
to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack>818     pub fn to_vec_padded(&self, pad_to: i32) -> Result<Vec<u8>, ErrorStack> {
819         let mut v = Vec::with_capacity(pad_to as usize);
820         unsafe {
821             cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?;
822             v.set_len(pad_to as usize);
823         }
824         Ok(v)
825     }
826 
827     /// Returns a decimal string representation of `self`.
828     ///
829     /// ```
830     /// # use openssl::bn::BigNum;
831     /// let s = -BigNum::from_u32(12345).unwrap();
832     ///
833     /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
834     /// ```
835     #[corresponds(BN_bn2dec)]
to_dec_str(&self) -> Result<OpensslString, ErrorStack>836     pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
837         unsafe {
838             let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?;
839             Ok(OpensslString::from_ptr(buf))
840         }
841     }
842 
843     /// Returns a hexadecimal string representation of `self`.
844     ///
845     /// ```
846     /// # use openssl::bn::BigNum;
847     /// let s = -BigNum::from_u32(0x99ff).unwrap();
848     ///
849     /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF");
850     /// ```
851     #[corresponds(BN_bn2hex)]
to_hex_str(&self) -> Result<OpensslString, ErrorStack>852     pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
853         unsafe {
854             let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?;
855             Ok(OpensslString::from_ptr(buf))
856         }
857     }
858 
859     /// Returns an `Asn1Integer` containing the value of `self`.
860     #[corresponds(BN_to_ASN1_INTEGER)]
to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack>861     pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
862         unsafe {
863             cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
864                 .map(|p| Asn1Integer::from_ptr(p))
865         }
866     }
867 
868     /// Force constant time computation on this value.
869     #[corresponds(BN_set_flags)]
870     #[cfg(ossl110)]
set_const_time(&mut self)871     pub fn set_const_time(&mut self) {
872         unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) }
873     }
874 
875     /// Returns true if `self` is in const time mode.
876     #[corresponds(BN_get_flags)]
877     #[cfg(ossl110)]
is_const_time(&self) -> bool878     pub fn is_const_time(&self) -> bool {
879         unsafe {
880             let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME);
881             ret == ffi::BN_FLG_CONSTTIME
882         }
883     }
884 
885     /// Returns true if `self` was created with [`BigNum::new_secure`].
886     #[corresponds(BN_get_flags)]
887     #[cfg(ossl110)]
is_secure(&self) -> bool888     pub fn is_secure(&self) -> bool {
889         unsafe {
890             let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE);
891             ret == ffi::BN_FLG_SECURE
892         }
893     }
894 }
895 
896 impl BigNum {
897     /// Creates a new `BigNum` with the value 0.
898     #[corresponds(BN_new)]
new() -> Result<BigNum, ErrorStack>899     pub fn new() -> Result<BigNum, ErrorStack> {
900         unsafe {
901             ffi::init();
902             let v = cvt_p(ffi::BN_new())?;
903             Ok(BigNum::from_ptr(v))
904         }
905     }
906 
907     /// Returns a new secure `BigNum`.
908     #[corresponds(BN_secure_new)]
909     #[cfg(ossl110)]
new_secure() -> Result<BigNum, ErrorStack>910     pub fn new_secure() -> Result<BigNum, ErrorStack> {
911         unsafe {
912             ffi::init();
913             let v = cvt_p(ffi::BN_secure_new())?;
914             Ok(BigNum::from_ptr(v))
915         }
916     }
917 
918     /// Creates a new `BigNum` with the given value.
919     #[corresponds(BN_set_word)]
from_u32(n: u32) -> Result<BigNum, ErrorStack>920     pub fn from_u32(n: u32) -> Result<BigNum, ErrorStack> {
921         BigNum::new().and_then(|v| unsafe {
922             cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v)
923         })
924     }
925 
926     /// Creates a `BigNum` from a decimal string.
927     #[corresponds(BN_dec2bn)]
from_dec_str(s: &str) -> Result<BigNum, ErrorStack>928     pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
929         unsafe {
930             ffi::init();
931             let c_str = CString::new(s.as_bytes()).unwrap();
932             let mut bn = ptr::null_mut();
933             cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?;
934             Ok(BigNum::from_ptr(bn))
935         }
936     }
937 
938     /// Creates a `BigNum` from a hexadecimal string.
939     #[corresponds(BN_hex2bn)]
from_hex_str(s: &str) -> Result<BigNum, ErrorStack>940     pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
941         unsafe {
942             ffi::init();
943             let c_str = CString::new(s.as_bytes()).unwrap();
944             let mut bn = ptr::null_mut();
945             cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?;
946             Ok(BigNum::from_ptr(bn))
947         }
948     }
949 
950     /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
951     /// the order of magnitude of `2 ^ 768`.  This number is used during calculated key
952     /// exchanges such as Diffie-Hellman.  This number is labeled Oakley group id 1.
953     ///
954     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
955     #[corresponds(BN_get_rfc2409_prime_768)]
956     #[cfg(not(boringssl))]
get_rfc2409_prime_768() -> Result<BigNum, ErrorStack>957     pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
958         unsafe {
959             ffi::init();
960             cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
961         }
962     }
963 
964     /// Returns a constant used in IKE as defined in [`RFC 2409`].  This prime number is in
965     /// the order of magnitude of `2 ^ 1024`.  This number is used during calculated key
966     /// exchanges such as Diffie-Hellman.  This number is labeled Oakly group 2.
967     ///
968     /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21
969     #[corresponds(BN_get_rfc2409_prime_1024)]
970     #[cfg(not(boringssl))]
get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack>971     pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
972         unsafe {
973             ffi::init();
974             cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
975         }
976     }
977 
978     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
979     /// of magnitude of `2 ^ 1536`.  This number is used during calculated key
980     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 5.
981     ///
982     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
983     #[corresponds(BN_get_rfc3526_prime_1536)]
984     #[cfg(not(boringssl))]
get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack>985     pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
986         unsafe {
987             ffi::init();
988             cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
989         }
990     }
991 
992     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
993     /// of magnitude of `2 ^ 2048`.  This number is used during calculated key
994     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 14.
995     ///
996     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3
997     #[corresponds(BN_get_rfc3526_prime_2048)]
998     #[cfg(not(boringssl))]
get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack>999     pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
1000         unsafe {
1001             ffi::init();
1002             cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
1003         }
1004     }
1005 
1006     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1007     /// of magnitude of `2 ^ 3072`.  This number is used during calculated key
1008     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 15.
1009     ///
1010     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1011     #[corresponds(BN_get_rfc3526_prime_3072)]
1012     #[cfg(not(boringssl))]
get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack>1013     pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
1014         unsafe {
1015             ffi::init();
1016             cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
1017         }
1018     }
1019 
1020     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1021     /// of magnitude of `2 ^ 4096`.  This number is used during calculated key
1022     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 16.
1023     ///
1024     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4
1025     #[corresponds(BN_get_rfc3526_prime_4096)]
1026     #[cfg(not(boringssl))]
get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack>1027     pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
1028         unsafe {
1029             ffi::init();
1030             cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum)
1031         }
1032     }
1033 
1034     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1035     /// of magnitude of `2 ^ 6144`.  This number is used during calculated key
1036     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 17.
1037     ///
1038     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1039     #[corresponds(BN_get_rfc3526_prime_6114)]
1040     #[cfg(not(boringssl))]
get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack>1041     pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
1042         unsafe {
1043             ffi::init();
1044             cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
1045         }
1046     }
1047 
1048     /// Returns a constant used in IKE as defined in [`RFC 3526`].  The prime is in the order
1049     /// of magnitude of `2 ^ 8192`.  This number is used during calculated key
1050     /// exchanges such as Diffie-Hellman.  This number is labeled MODP group 18.
1051     ///
1052     /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6
1053     #[corresponds(BN_get_rfc3526_prime_8192)]
1054     #[cfg(not(boringssl))]
get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack>1055     pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
1056         unsafe {
1057             ffi::init();
1058             cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
1059         }
1060     }
1061 
1062     /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
1063     ///
1064     /// OpenSSL documentation at [`BN_bin2bn`]
1065     ///
1066     /// [`BN_bin2bn`]: https://www.openssl.org/docs/man1.1.0/crypto/BN_bin2bn.html
1067     ///
1068     /// ```
1069     /// # use openssl::bn::BigNum;
1070     /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
1071     ///
1072     /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1073     /// ```
1074     #[corresponds(BN_bin2bn)]
from_slice(n: &[u8]) -> Result<BigNum, ErrorStack>1075     pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
1076         unsafe {
1077             ffi::init();
1078             assert!(n.len() <= LenType::max_value() as usize);
1079 
1080             cvt_p(ffi::BN_bin2bn(
1081                 n.as_ptr(),
1082                 n.len() as LenType,
1083                 ptr::null_mut(),
1084             ))
1085             .map(|p| BigNum::from_ptr(p))
1086         }
1087     }
1088 
1089     /// Copies data from a slice overwriting what was in the BigNum.
1090     ///
1091     /// This function can be used to copy data from a slice to a
1092     /// [secure BigNum][`BigNum::new_secure`].
1093     ///
1094     /// # Examples
1095     ///
1096     /// ```
1097     /// # use openssl::bn::BigNum;
1098     /// let mut bignum = BigNum::new().unwrap();
1099     /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap();
1100     ///
1101     /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
1102     /// ```
1103     #[corresponds(BN_bin2bn)]
copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack>1104     pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> {
1105         unsafe {
1106             assert!(n.len() <= LenType::max_value() as usize);
1107 
1108             cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?;
1109             Ok(())
1110         }
1111     }
1112 }
1113 
1114 impl fmt::Debug for BigNumRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1115     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1116         match self.to_dec_str() {
1117             Ok(s) => f.write_str(&s),
1118             Err(e) => Err(e.into()),
1119         }
1120     }
1121 }
1122 
1123 impl fmt::Debug for BigNum {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1124     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1125         match self.to_dec_str() {
1126             Ok(s) => f.write_str(&s),
1127             Err(e) => Err(e.into()),
1128         }
1129     }
1130 }
1131 
1132 impl fmt::Display for BigNumRef {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1133     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1134         match self.to_dec_str() {
1135             Ok(s) => f.write_str(&s),
1136             Err(e) => Err(e.into()),
1137         }
1138     }
1139 }
1140 
1141 impl fmt::Display for BigNum {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1142     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1143         match self.to_dec_str() {
1144             Ok(s) => f.write_str(&s),
1145             Err(e) => Err(e.into()),
1146         }
1147     }
1148 }
1149 
1150 impl PartialEq<BigNumRef> for BigNumRef {
eq(&self, oth: &BigNumRef) -> bool1151     fn eq(&self, oth: &BigNumRef) -> bool {
1152         self.cmp(oth) == Ordering::Equal
1153     }
1154 }
1155 
1156 impl PartialEq<BigNum> for BigNumRef {
eq(&self, oth: &BigNum) -> bool1157     fn eq(&self, oth: &BigNum) -> bool {
1158         self.eq(oth.deref())
1159     }
1160 }
1161 
1162 impl Eq for BigNumRef {}
1163 
1164 impl PartialEq for BigNum {
eq(&self, oth: &BigNum) -> bool1165     fn eq(&self, oth: &BigNum) -> bool {
1166         self.deref().eq(oth)
1167     }
1168 }
1169 
1170 impl PartialEq<BigNumRef> for BigNum {
eq(&self, oth: &BigNumRef) -> bool1171     fn eq(&self, oth: &BigNumRef) -> bool {
1172         self.deref().eq(oth)
1173     }
1174 }
1175 
1176 impl Eq for BigNum {}
1177 
1178 impl PartialOrd<BigNumRef> for BigNumRef {
partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering>1179     fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1180         Some(self.cmp(oth))
1181     }
1182 }
1183 
1184 impl PartialOrd<BigNum> for BigNumRef {
partial_cmp(&self, oth: &BigNum) -> Option<Ordering>1185     fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1186         Some(self.cmp(oth.deref()))
1187     }
1188 }
1189 
1190 impl Ord for BigNumRef {
cmp(&self, oth: &BigNumRef) -> Ordering1191     fn cmp(&self, oth: &BigNumRef) -> Ordering {
1192         unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
1193     }
1194 }
1195 
1196 impl PartialOrd for BigNum {
partial_cmp(&self, oth: &BigNum) -> Option<Ordering>1197     fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
1198         self.deref().partial_cmp(oth.deref())
1199     }
1200 }
1201 
1202 impl PartialOrd<BigNumRef> for BigNum {
partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering>1203     fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
1204         self.deref().partial_cmp(oth)
1205     }
1206 }
1207 
1208 impl Ord for BigNum {
cmp(&self, oth: &BigNum) -> Ordering1209     fn cmp(&self, oth: &BigNum) -> Ordering {
1210         self.deref().cmp(oth.deref())
1211     }
1212 }
1213 
1214 macro_rules! delegate {
1215     ($t:ident, $m:ident) => {
1216         impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
1217             type Output = BigNum;
1218 
1219             fn $m(self, oth: &BigNum) -> BigNum {
1220                 $t::$m(self, oth.deref())
1221             }
1222         }
1223 
1224         impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
1225             type Output = BigNum;
1226 
1227             fn $m(self, oth: &BigNumRef) -> BigNum {
1228                 $t::$m(self.deref(), oth)
1229             }
1230         }
1231 
1232         impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
1233             type Output = BigNum;
1234 
1235             fn $m(self, oth: &BigNum) -> BigNum {
1236                 $t::$m(self.deref(), oth.deref())
1237             }
1238         }
1239     };
1240 }
1241 
1242 impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
1243     type Output = BigNum;
1244 
add(self, oth: &BigNumRef) -> BigNum1245     fn add(self, oth: &BigNumRef) -> BigNum {
1246         let mut r = BigNum::new().unwrap();
1247         r.checked_add(self, oth).unwrap();
1248         r
1249     }
1250 }
1251 
1252 delegate!(Add, add);
1253 
1254 impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
1255     type Output = BigNum;
1256 
sub(self, oth: &BigNumRef) -> BigNum1257     fn sub(self, oth: &BigNumRef) -> BigNum {
1258         let mut r = BigNum::new().unwrap();
1259         r.checked_sub(self, oth).unwrap();
1260         r
1261     }
1262 }
1263 
1264 delegate!(Sub, sub);
1265 
1266 impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
1267     type Output = BigNum;
1268 
mul(self, oth: &BigNumRef) -> BigNum1269     fn mul(self, oth: &BigNumRef) -> BigNum {
1270         let mut ctx = BigNumContext::new().unwrap();
1271         let mut r = BigNum::new().unwrap();
1272         r.checked_mul(self, oth, &mut ctx).unwrap();
1273         r
1274     }
1275 }
1276 
1277 delegate!(Mul, mul);
1278 
1279 impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
1280     type Output = BigNum;
1281 
div(self, oth: &'b BigNumRef) -> BigNum1282     fn div(self, oth: &'b BigNumRef) -> BigNum {
1283         let mut ctx = BigNumContext::new().unwrap();
1284         let mut r = BigNum::new().unwrap();
1285         r.checked_div(self, oth, &mut ctx).unwrap();
1286         r
1287     }
1288 }
1289 
1290 delegate!(Div, div);
1291 
1292 impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
1293     type Output = BigNum;
1294 
rem(self, oth: &'b BigNumRef) -> BigNum1295     fn rem(self, oth: &'b BigNumRef) -> BigNum {
1296         let mut ctx = BigNumContext::new().unwrap();
1297         let mut r = BigNum::new().unwrap();
1298         r.checked_rem(self, oth, &mut ctx).unwrap();
1299         r
1300     }
1301 }
1302 
1303 delegate!(Rem, rem);
1304 
1305 impl<'a> Shl<i32> for &'a BigNumRef {
1306     type Output = BigNum;
1307 
shl(self, n: i32) -> BigNum1308     fn shl(self, n: i32) -> BigNum {
1309         let mut r = BigNum::new().unwrap();
1310         r.lshift(self, n).unwrap();
1311         r
1312     }
1313 }
1314 
1315 impl<'a> Shl<i32> for &'a BigNum {
1316     type Output = BigNum;
1317 
shl(self, n: i32) -> BigNum1318     fn shl(self, n: i32) -> BigNum {
1319         self.deref().shl(n)
1320     }
1321 }
1322 
1323 impl<'a> Shr<i32> for &'a BigNumRef {
1324     type Output = BigNum;
1325 
shr(self, n: i32) -> BigNum1326     fn shr(self, n: i32) -> BigNum {
1327         let mut r = BigNum::new().unwrap();
1328         r.rshift(self, n).unwrap();
1329         r
1330     }
1331 }
1332 
1333 impl<'a> Shr<i32> for &'a BigNum {
1334     type Output = BigNum;
1335 
shr(self, n: i32) -> BigNum1336     fn shr(self, n: i32) -> BigNum {
1337         self.deref().shr(n)
1338     }
1339 }
1340 
1341 impl<'a> Neg for &'a BigNumRef {
1342     type Output = BigNum;
1343 
neg(self) -> BigNum1344     fn neg(self) -> BigNum {
1345         self.to_owned().unwrap().neg()
1346     }
1347 }
1348 
1349 impl<'a> Neg for &'a BigNum {
1350     type Output = BigNum;
1351 
neg(self) -> BigNum1352     fn neg(self) -> BigNum {
1353         self.deref().neg()
1354     }
1355 }
1356 
1357 impl Neg for BigNum {
1358     type Output = BigNum;
1359 
neg(mut self) -> BigNum1360     fn neg(mut self) -> BigNum {
1361         let negative = self.is_negative();
1362         self.set_negative(!negative);
1363         self
1364     }
1365 }
1366 
1367 #[cfg(test)]
1368 mod tests {
1369     use crate::bn::{BigNum, BigNumContext};
1370 
1371     #[test]
test_to_from_slice()1372     fn test_to_from_slice() {
1373         let v0 = BigNum::from_u32(10_203_004).unwrap();
1374         let vec = v0.to_vec();
1375         let v1 = BigNum::from_slice(&vec).unwrap();
1376 
1377         assert_eq!(v0, v1);
1378     }
1379 
1380     #[test]
test_negation()1381     fn test_negation() {
1382         let a = BigNum::from_u32(909_829_283).unwrap();
1383 
1384         assert!(!a.is_negative());
1385         assert!((-a).is_negative());
1386     }
1387 
1388     #[test]
test_shift()1389     fn test_shift() {
1390         let a = BigNum::from_u32(909_829_283).unwrap();
1391 
1392         assert_eq!(a, &(&a << 1) >> 1);
1393     }
1394 
1395     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1396     #[test]
test_rand_range()1397     fn test_rand_range() {
1398         let range = BigNum::from_u32(909_829_283).unwrap();
1399         let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap();
1400         range.rand_range(&mut result).unwrap();
1401         assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1402     }
1403 
1404     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1405     #[test]
test_pseudo_rand_range()1406     fn test_pseudo_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.pseudo_rand_range(&mut result).unwrap();
1410         assert!(result >= BigNum::from_u32(0).unwrap() && result < range);
1411     }
1412 
1413     #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))]
1414     #[test]
test_prime_numbers()1415     fn test_prime_numbers() {
1416         let a = BigNum::from_u32(19_029_017).unwrap();
1417         let mut p = BigNum::new().unwrap();
1418         p.generate_prime(128, true, None, Some(&a)).unwrap();
1419 
1420         let mut ctx = BigNumContext::new().unwrap();
1421         assert!(p.is_prime(100, &mut ctx).unwrap());
1422         assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap());
1423     }
1424 
1425     #[cfg(ossl110)]
1426     #[test]
test_secure_bn_ctx()1427     fn test_secure_bn_ctx() {
1428         let mut cxt = BigNumContext::new_secure().unwrap();
1429         let a = BigNum::from_u32(8).unwrap();
1430         let b = BigNum::from_u32(3).unwrap();
1431 
1432         let mut remainder = BigNum::new().unwrap();
1433         remainder.nnmod(&a, &b, &mut cxt).unwrap();
1434 
1435         assert!(remainder.eq(&BigNum::from_u32(2).unwrap()));
1436     }
1437 
1438     #[cfg(ossl110)]
1439     #[test]
test_secure_bn()1440     fn test_secure_bn() {
1441         let a = BigNum::new().unwrap();
1442         assert!(!a.is_secure());
1443 
1444         let b = BigNum::new_secure().unwrap();
1445         assert!(b.is_secure())
1446     }
1447 
1448     #[cfg(ossl110)]
1449     #[test]
test_const_time_bn()1450     fn test_const_time_bn() {
1451         let a = BigNum::new().unwrap();
1452         assert!(!a.is_const_time());
1453 
1454         let mut b = BigNum::new().unwrap();
1455         b.set_const_time();
1456         assert!(b.is_const_time())
1457     }
1458 }
1459