2 use foreign_types
::{ForeignType, ForeignTypeRef}
;
4 use std
::cmp
::Ordering
;
7 use std
::ops
::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref}
;
9 use {cvt, cvt_p, cvt_n}
;
10 use asn1
::Asn1Integer
;
11 use error
::ErrorStack
;
12 use string
::OpensslString
;
15 use ffi
::{get_rfc2409_prime_768
as BN_get_rfc2409_prime_768
,
16 get_rfc2409_prime_1024
as BN_get_rfc2409_prime_1024
,
17 get_rfc3526_prime_1536
as BN_get_rfc3526_prime_1536
,
18 get_rfc3526_prime_2048
as BN_get_rfc3526_prime_2048
,
19 get_rfc3526_prime_3072
as BN_get_rfc3526_prime_3072
,
20 get_rfc3526_prime_4096
as BN_get_rfc3526_prime_4096
,
21 get_rfc3526_prime_6144
as BN_get_rfc3526_prime_6144
,
22 get_rfc3526_prime_8192
as BN_get_rfc3526_prime_8192
};
25 use ffi
::{BN_get_rfc2409_prime_768
, BN_get_rfc2409_prime_1024
, BN_get_rfc3526_prime_1536
,
26 BN_get_rfc3526_prime_2048
, BN_get_rfc3526_prime_3072
, BN_get_rfc3526_prime_4096
,
27 BN_get_rfc3526_prime_6144
, BN_get_rfc3526_prime_8192
};
29 /// Options for the most significant bits of a randomly generated `BigNum`.
30 pub struct MsbOption(c_int
);
32 /// The most significant bit of the number may be 0.
33 pub const MSB_MAYBE_ZERO
: MsbOption
= MsbOption(-1);
35 /// The most significant bit of the number must be 1.
36 pub const MSB_ONE
: MsbOption
= MsbOption(0);
38 /// The most significant two bits of the number must be 1.
40 /// The number of bits in the product of two such numbers will always be exactly twice the number
41 /// of bits in the original numbers.
42 pub const TWO_MSB_ONE
: MsbOption
= MsbOption(1);
45 type CType
= ffi
::BN_CTX
;
46 fn drop
= ffi
::BN_CTX_free
;
48 pub struct BigNumContext
;
49 pub struct BigNumContextRef
;
53 /// Returns a new `BigNumContext`.
54 pub fn new() -> Result
<BigNumContext
, ErrorStack
> {
57 cvt_p(ffi
::BN_CTX_new()).map(BigNumContext
)
63 /// Erases the memory used by this `BigNum`, resetting its value to 0.
65 /// This can be used to destroy sensitive data such as keys when they are no longer needed.
66 pub fn clear(&mut self) {
67 unsafe { ffi::BN_clear(self.as_ptr()) }
70 /// Adds a `u32` to `self`.
71 pub fn add_word(&mut self, w
: u32) -> Result
<(), ErrorStack
> {
72 unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
75 /// Subtracts a `u32` from `self`.
76 pub fn sub_word(&mut self, w
: u32) -> Result
<(), ErrorStack
> {
77 unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
80 /// Multiplies a `u32` by `self`.
81 pub fn mul_word(&mut self, w
: u32) -> Result
<(), ErrorStack
> {
82 unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) }
85 /// Divides `self` by a `u32`, returning the remainder.
86 pub fn div_word(&mut self, w
: u32) -> Result
<u64, ErrorStack
> {
88 let r
= ffi
::BN_div_word(self.as_ptr(), w
.into());
89 if r
== ffi
::BN_ULONG
::max_value() {
90 Err(ErrorStack
::get())
97 /// Returns the result of `self` modulo `w`.
98 pub fn mod_word(&self, w
: u32) -> Result
<u64, ErrorStack
> {
100 let r
= ffi
::BN_mod_word(self.as_ptr(), w
.into());
101 if r
== ffi
::BN_ULONG
::max_value() {
102 Err(ErrorStack
::get())
109 /// Places a cryptographically-secure pseudo-random number nonnegative
110 /// number less than `self` in `rnd`.
111 pub fn rand_range(&self, rnd
: &mut BigNumRef
) -> Result
<(), ErrorStack
> {
112 unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
115 /// The cryptographically weak counterpart to `rand_in_range`.
116 pub fn pseudo_rand_range(&self, rnd
: &mut BigNumRef
) -> Result
<(), ErrorStack
> {
117 unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) }
120 /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
122 /// When setting a bit outside of `self`, it is expanded.
123 pub fn set_bit(&mut self, n
: i32) -> Result
<(), ErrorStack
> {
124 unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) }
127 /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
129 /// When clearing a bit outside of `self`, an error is returned.
130 pub fn clear_bit(&mut self, n
: i32) -> Result
<(), ErrorStack
> {
131 unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) }
134 /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise.
135 pub fn is_bit_set(&self, n
: i32) -> bool
{
136 unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 }
139 /// Truncates `self` to the lowest `n` bits.
141 /// An error occurs if `self` is already shorter than `n` bits.
142 pub fn mask_bits(&mut self, n
: i32) -> Result
<(), ErrorStack
> {
143 unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) }
146 /// Places `a << 1` in `self`.
147 pub fn lshift1(&mut self, a
: &BigNumRef
) -> Result
<(), ErrorStack
> {
148 unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
151 /// Places `a >> 1` in `self`.
152 pub fn rshift1(&mut self, a
: &BigNumRef
) -> Result
<(), ErrorStack
> {
153 unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) }
156 /// Places `a + b` in `self`.
157 pub fn checked_add(&mut self, a
: &BigNumRef
, b
: &BigNumRef
) -> Result
<(), ErrorStack
> {
158 unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
161 /// Places `a - b` in `self`.
162 pub fn checked_sub(&mut self, a
: &BigNumRef
, b
: &BigNumRef
) -> Result
<(), ErrorStack
> {
163 unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) }
166 /// Places `a << n` in `self`.
167 pub fn lshift(&mut self, a
: &BigNumRef
, n
: i32) -> Result
<(), ErrorStack
> {
168 unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
171 /// Places `a >> n` in `self`.
172 pub fn rshift(&mut self, a
: &BigNumRef
, n
: i32) -> Result
<(), ErrorStack
> {
173 unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) }
176 pub fn to_owned(&self) -> Result
<BigNum
, ErrorStack
> {
177 unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) }
180 /// Sets the sign of `self`.
181 pub fn set_negative(&mut self, negative
: bool
) {
182 unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) }
185 /// Compare the absolute values of `self` and `oth`.
188 /// # use openssl::bn::BigNum;
189 /// # use std::cmp::Ordering;
190 /// let s = -BigNum::from_u32(8).unwrap();
191 /// let o = BigNum::from_u32(8).unwrap();
193 /// assert_eq!(s.ucmp(&o), Ordering::Equal);
195 pub fn ucmp(&self, oth
: &BigNumRef
) -> Ordering
{
196 unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
199 pub fn is_negative(&self) -> bool
{
204 fn _is_negative(&self) -> bool
{
205 unsafe { (*self.as_ptr()).neg == 1 }
209 fn _is_negative(&self) -> bool
{
210 unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
213 /// Returns the number of significant bits in `self`.
214 pub fn num_bits(&self) -> i32 {
215 unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 }
218 /// Returns the size of `self` in bytes.
219 pub fn num_bytes(&self) -> i32 {
220 (self.num_bits() + 7) / 8
223 /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
227 /// * `bits`: Length of the number in bits.
228 /// * `msb`: The desired properties of the number.
229 /// * `odd`: If `true`, the generated number will be odd.
230 pub fn rand(&mut self, bits
: i32, msb
: MsbOption
, odd
: bool
) -> Result
<(), ErrorStack
> {
241 /// The cryptographically weak counterpart to `rand`.
242 pub fn pseudo_rand(&mut self, bits
: i32, msb
: MsbOption
, odd
: bool
) -> Result
<(), ErrorStack
> {
244 cvt(ffi
::BN_pseudo_rand(
253 /// Generates a prime number, placing it in `self`.
257 /// * `bits`: The length of the prime in bits (lower bound).
258 /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
259 /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
260 /// generated prime and `rem` is `1` if not specified (`None`).
261 pub fn generate_prime(
265 add
: Option
<&BigNumRef
>,
266 rem
: Option
<&BigNumRef
>,
267 ) -> Result
<(), ErrorStack
> {
269 cvt(ffi
::BN_generate_prime_ex(
273 add
.map(|n
| n
.as_ptr()).unwrap_or(ptr
::null_mut()),
274 rem
.map(|n
| n
.as_ptr()).unwrap_or(ptr
::null_mut()),
280 /// Places the result of `a * b` in `self`.
285 ctx
: &mut BigNumContextRef
,
286 ) -> Result
<(), ErrorStack
> {
297 /// Places the result of `a / b` in `self`.
302 ctx
: &mut BigNumContextRef
,
303 ) -> Result
<(), ErrorStack
> {
315 /// Places the result of `a % b` in `self`.
320 ctx
: &mut BigNumContextRef
,
321 ) -> Result
<(), ErrorStack
> {
333 /// Places the result of `a / b` in `self` and `a % b` in `rem`.
339 ctx
: &mut BigNumContextRef
,
340 ) -> Result
<(), ErrorStack
> {
352 /// Places the result of `a²` in `self`.
353 pub fn sqr(&mut self, a
: &BigNumRef
, ctx
: &mut BigNumContextRef
) -> Result
<(), ErrorStack
> {
354 unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) }
357 /// Places the result of `a mod m` in `self`.
362 ctx
: &mut BigNumContextRef
,
363 ) -> Result
<(), ErrorStack
> {
374 /// Places the result of `(a + b) mod m` in `self`.
380 ctx
: &mut BigNumContextRef
,
381 ) -> Result
<(), ErrorStack
> {
393 /// Places the result of `(a - b) mod m` in `self`.
399 ctx
: &mut BigNumContextRef
,
400 ) -> Result
<(), ErrorStack
> {
412 /// Places the result of `(a * b) mod m` in `self`.
418 ctx
: &mut BigNumContextRef
,
419 ) -> Result
<(), ErrorStack
> {
431 /// Places the result of `a² mod m` in `self`.
436 ctx
: &mut BigNumContextRef
,
437 ) -> Result
<(), ErrorStack
> {
448 /// Places the result of `a^p` in `self`.
453 ctx
: &mut BigNumContextRef
,
454 ) -> Result
<(), ErrorStack
> {
465 /// Places the result of `a^p mod m` in `self`.
471 ctx
: &mut BigNumContextRef
,
472 ) -> Result
<(), ErrorStack
> {
484 /// Places the inverse of `a` modulo `n` in `self`.
489 ctx
: &mut BigNumContextRef
,
490 ) -> Result
<(), ErrorStack
> {
492 cvt_p(ffi
::BN_mod_inverse(
501 /// Places the greatest common denominator of `a` and `b` in `self`.
506 ctx
: &mut BigNumContextRef
,
507 ) -> Result
<(), ErrorStack
> {
518 /// Checks whether `self` is prime.
520 /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
522 /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
523 pub fn is_prime(&self, checks
: i32, ctx
: &mut BigNumContextRef
) -> Result
<bool
, ErrorStack
> {
525 cvt_n(ffi
::BN_is_prime_ex(
534 /// Checks whether `self` is prime with optional trial division.
536 /// If `do_trial_division` is `true`, first performs trial division by a number of small primes.
537 /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks`
542 /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
543 pub fn is_prime_fasttest(
546 ctx
: &mut BigNumContextRef
,
547 do_trial_division
: bool
,
548 ) -> Result
<bool
, ErrorStack
> {
550 cvt_n(ffi
::BN_is_prime_fasttest_ex(
554 do_trial_division
as c_int
,
560 /// Returns a big-endian byte vector representation of the absolute value of `self`.
562 /// `self` can be recreated by using `from_slice`.
565 /// # use openssl::bn::BigNum;
566 /// let s = -BigNum::from_u32(4543).unwrap();
567 /// let r = BigNum::from_u32(4543).unwrap();
569 /// let s_vec = s.to_vec();
570 /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
572 pub fn to_vec(&self) -> Vec
<u8> {
573 let size
= self.num_bytes() as usize;
574 let mut v
= Vec
::with_capacity(size
);
576 ffi
::BN_bn2bin(self.as_ptr(), v
.as_mut_ptr());
582 /// Returns a decimal string representation of `self`.
585 /// # use openssl::bn::BigNum;
586 /// let s = -BigNum::from_u32(12345).unwrap();
588 /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
590 pub fn to_dec_str(&self) -> Result
<OpensslString
, ErrorStack
> {
592 let buf
= try
!(cvt_p(ffi
::BN_bn2dec(self.as_ptr())));
593 Ok(OpensslString
::from_ptr(buf
))
597 /// Returns a hexadecimal string representation of `self`.
600 /// # use openssl::bn::BigNum;
601 /// let s = -BigNum::from_u32(0x99ff).unwrap();
603 /// assert_eq!(&**s.to_hex_str().unwrap(), "-99FF");
605 pub fn to_hex_str(&self) -> Result
<OpensslString
, ErrorStack
> {
607 let buf
= try
!(cvt_p(ffi
::BN_bn2hex(self.as_ptr())));
608 Ok(OpensslString
::from_ptr(buf
))
612 /// Returns an `Asn1Integer` containing the value of `self`.
613 pub fn to_asn1_integer(&self) -> Result
<Asn1Integer
, ErrorStack
> {
615 cvt_p(ffi
::BN_to_ASN1_INTEGER(self.as_ptr(), ptr
::null_mut()))
616 .map(|p
| Asn1Integer
::from_ptr(p
))
622 type CType
= ffi
::BIGNUM
;
623 fn drop
= ffi
::BN_free
;
626 pub struct BigNumRef
;
630 /// Creates a new `BigNum` with the value 0.
631 pub fn new() -> Result
<BigNum
, ErrorStack
> {
634 let v
= try
!(cvt_p(ffi
::BN_new()));
635 Ok(BigNum
::from_ptr(v
))
639 /// Creates a new `BigNum` with the given value.
640 pub fn from_u32(n
: u32) -> Result
<BigNum
, ErrorStack
> {
641 BigNum
::new().and_then(|v
| unsafe {
642 cvt(ffi
::BN_set_word(v
.as_ptr(), n
as ffi
::BN_ULONG
)).map(|_
| v
)
646 /// Creates a `BigNum` from a decimal string.
647 pub fn from_dec_str(s
: &str) -> Result
<BigNum
, ErrorStack
> {
650 let c_str
= CString
::new(s
.as_bytes()).unwrap();
651 let mut bn
= ptr
::null_mut();
652 try
!(cvt(ffi
::BN_dec2bn(&mut bn
, c_str
.as_ptr() as *const _
)));
653 Ok(BigNum
::from_ptr(bn
))
657 /// Creates a `BigNum` from a hexadecimal string.
658 pub fn from_hex_str(s
: &str) -> Result
<BigNum
, ErrorStack
> {
661 let c_str
= CString
::new(s
.as_bytes()).unwrap();
662 let mut bn
= ptr
::null_mut();
663 try
!(cvt(ffi
::BN_hex2bn(&mut bn
, c_str
.as_ptr() as *const _
)));
664 Ok(BigNum
::from_ptr(bn
))
668 pub fn get_rfc2409_prime_768() -> Result
<BigNum
, ErrorStack
> {
671 cvt_p(BN_get_rfc2409_prime_768(ptr
::null_mut())).map(BigNum
)
675 pub fn get_rfc2409_prime_1024() -> Result
<BigNum
, ErrorStack
> {
678 cvt_p(BN_get_rfc2409_prime_1024(ptr
::null_mut())).map(BigNum
)
682 pub fn get_rfc3526_prime_1536() -> Result
<BigNum
, ErrorStack
> {
685 cvt_p(BN_get_rfc3526_prime_1536(ptr
::null_mut())).map(BigNum
)
689 pub fn get_rfc3526_prime_2048() -> Result
<BigNum
, ErrorStack
> {
692 cvt_p(BN_get_rfc3526_prime_2048(ptr
::null_mut())).map(BigNum
)
696 pub fn get_rfc3526_prime_3072() -> Result
<BigNum
, ErrorStack
> {
699 cvt_p(BN_get_rfc3526_prime_3072(ptr
::null_mut())).map(BigNum
)
703 pub fn get_rfc3526_prime_4096() -> Result
<BigNum
, ErrorStack
> {
706 cvt_p(BN_get_rfc3526_prime_4096(ptr
::null_mut())).map(BigNum
)
710 pub fn get_rfc3526_prime_6144() -> Result
<BigNum
, ErrorStack
> {
713 cvt_p(BN_get_rfc3526_prime_6144(ptr
::null_mut())).map(BigNum
)
717 pub fn get_rfc3526_prime_8192() -> Result
<BigNum
, ErrorStack
> {
720 cvt_p(BN_get_rfc3526_prime_8192(ptr
::null_mut())).map(BigNum
)
724 /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
727 /// # use openssl::bn::BigNum;
728 /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
730 /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
732 pub fn from_slice(n
: &[u8]) -> Result
<BigNum
, ErrorStack
> {
735 assert
!(n
.len() <= c_int
::max_value() as usize);
736 cvt_p(ffi
::BN_bin2bn(
740 )).map(|p
| BigNum
::from_ptr(p
))
745 impl AsRef
<BigNumRef
> for BigNum
{
746 fn as_ref(&self) -> &BigNumRef
{
751 impl fmt
::Debug
for BigNumRef
{
752 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
753 match self.to_dec_str() {
754 Ok(s
) => f
.write_str(&s
),
755 Err(e
) => Err(e
.into()),
760 impl fmt
::Debug
for BigNum
{
761 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
762 match self.to_dec_str() {
763 Ok(s
) => f
.write_str(&s
),
764 Err(e
) => Err(e
.into()),
769 impl fmt
::Display
for BigNumRef
{
770 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
771 match self.to_dec_str() {
772 Ok(s
) => f
.write_str(&s
),
773 Err(e
) => Err(e
.into()),
778 impl fmt
::Display
for BigNum
{
779 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
780 match self.to_dec_str() {
781 Ok(s
) => f
.write_str(&s
),
782 Err(e
) => Err(e
.into()),
787 impl PartialEq
<BigNumRef
> for BigNumRef
{
788 fn eq(&self, oth
: &BigNumRef
) -> bool
{
789 self.cmp(oth
) == Ordering
::Equal
793 impl PartialEq
<BigNum
> for BigNumRef
{
794 fn eq(&self, oth
: &BigNum
) -> bool
{
799 impl Eq
for BigNumRef {}
801 impl PartialEq
for BigNum
{
802 fn eq(&self, oth
: &BigNum
) -> bool
{
807 impl PartialEq
<BigNumRef
> for BigNum
{
808 fn eq(&self, oth
: &BigNumRef
) -> bool
{
813 impl Eq
for BigNum {}
815 impl PartialOrd
<BigNumRef
> for BigNumRef
{
816 fn partial_cmp(&self, oth
: &BigNumRef
) -> Option
<Ordering
> {
821 impl PartialOrd
<BigNum
> for BigNumRef
{
822 fn partial_cmp(&self, oth
: &BigNum
) -> Option
<Ordering
> {
823 Some(self.cmp(oth
.deref()))
827 impl Ord
for BigNumRef
{
828 fn cmp(&self, oth
: &BigNumRef
) -> Ordering
{
829 unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
833 impl PartialOrd
for BigNum
{
834 fn partial_cmp(&self, oth
: &BigNum
) -> Option
<Ordering
> {
835 self.deref().partial_cmp(oth
.deref())
839 impl PartialOrd
<BigNumRef
> for BigNum
{
840 fn partial_cmp(&self, oth
: &BigNumRef
) -> Option
<Ordering
> {
841 self.deref().partial_cmp(oth
)
845 impl Ord
for BigNum
{
846 fn cmp(&self, oth
: &BigNum
) -> Ordering
{
847 self.deref().cmp(oth
.deref())
851 macro_rules
! delegate
{
852 ($t
:ident
, $m
:ident
) => {
853 impl<'a
, 'b
> $t
<&'b BigNum
> for &'a BigNumRef
{
854 type Output
= BigNum
;
856 fn $
m(self, oth
: &BigNum
) -> BigNum
{
857 $t
::$
m(self, oth
.deref())
861 impl<'a
, 'b
> $t
<&'b BigNumRef
> for &'a BigNum
{
862 type Output
= BigNum
;
864 fn $
m(self, oth
: &BigNumRef
) -> BigNum
{
865 $t
::$
m(self.deref(), oth
)
869 impl<'a
, 'b
> $t
<&'b BigNum
> for &'a BigNum
{
870 type Output
= BigNum
;
872 fn $
m(self, oth
: &BigNum
) -> BigNum
{
873 $t
::$
m(self.deref(), oth
.deref())
879 impl<'a
, 'b
> Add
<&'b BigNumRef
> for &'a BigNumRef
{
880 type Output
= BigNum
;
882 fn add(self, oth
: &BigNumRef
) -> BigNum
{
883 let mut r
= BigNum
::new().unwrap();
884 r
.checked_add(self, oth
).unwrap();
891 impl<'a
, 'b
> Sub
<&'b BigNumRef
> for &'a BigNumRef
{
892 type Output
= BigNum
;
894 fn sub(self, oth
: &BigNumRef
) -> BigNum
{
895 let mut r
= BigNum
::new().unwrap();
896 r
.checked_sub(self, oth
).unwrap();
903 impl<'a
, 'b
> Mul
<&'b BigNumRef
> for &'a BigNumRef
{
904 type Output
= BigNum
;
906 fn mul(self, oth
: &BigNumRef
) -> BigNum
{
907 let mut ctx
= BigNumContext
::new().unwrap();
908 let mut r
= BigNum
::new().unwrap();
909 r
.checked_mul(self, oth
, &mut ctx
).unwrap();
916 impl<'a
, 'b
> Div
<&'b BigNumRef
> for &'a BigNumRef
{
917 type Output
= BigNum
;
919 fn div(self, oth
: &'b BigNumRef
) -> BigNum
{
920 let mut ctx
= BigNumContext
::new().unwrap();
921 let mut r
= BigNum
::new().unwrap();
922 r
.checked_div(self, oth
, &mut ctx
).unwrap();
929 impl<'a
, 'b
> Rem
<&'b BigNumRef
> for &'a BigNumRef
{
930 type Output
= BigNum
;
932 fn rem(self, oth
: &'b BigNumRef
) -> BigNum
{
933 let mut ctx
= BigNumContext
::new().unwrap();
934 let mut r
= BigNum
::new().unwrap();
935 r
.checked_rem(self, oth
, &mut ctx
).unwrap();
942 impl<'a
> Shl
<i32> for &'a BigNumRef
{
943 type Output
= BigNum
;
945 fn shl(self, n
: i32) -> BigNum
{
946 let mut r
= BigNum
::new().unwrap();
947 r
.lshift(self, n
).unwrap();
952 impl<'a
> Shl
<i32> for &'a BigNum
{
953 type Output
= BigNum
;
955 fn shl(self, n
: i32) -> BigNum
{
960 impl<'a
> Shr
<i32> for &'a BigNumRef
{
961 type Output
= BigNum
;
963 fn shr(self, n
: i32) -> BigNum
{
964 let mut r
= BigNum
::new().unwrap();
965 r
.rshift(self, n
).unwrap();
970 impl<'a
> Shr
<i32> for &'a BigNum
{
971 type Output
= BigNum
;
973 fn shr(self, n
: i32) -> BigNum
{
978 impl<'a
> Neg
for &'a BigNumRef
{
979 type Output
= BigNum
;
981 fn neg(self) -> BigNum
{
982 self.to_owned().unwrap().neg()
986 impl<'a
> Neg
for &'a BigNum
{
987 type Output
= BigNum
;
989 fn neg(self) -> BigNum
{
994 impl Neg
for BigNum
{
995 type Output
= BigNum
;
997 fn neg(mut self) -> BigNum
{
998 let negative
= self.is_negative();
999 self.set_negative(!negative
);
1006 use bn
::{BigNumContext, BigNum}
;
1009 fn test_to_from_slice() {
1010 let v0
= BigNum
::from_u32(10203004).unwrap();
1011 let vec
= v0
.to_vec();
1012 let v1
= BigNum
::from_slice(&vec
).unwrap();
1018 fn test_negation() {
1019 let a
= BigNum
::from_u32(909829283).unwrap();
1021 assert
!(!a
.is_negative());
1022 assert
!((-a
).is_negative());
1027 let a
= BigNum
::from_u32(909829283).unwrap();
1028 use std
::ops
::{Shl, Shr}
;
1030 assert
!(a
== a
.shl(1).shr(1));
1034 fn test_rand_range() {
1035 let range
= BigNum
::from_u32(909829283).unwrap();
1036 let mut result
= BigNum
::from_dec_str(&range
.to_dec_str().unwrap()).unwrap();
1037 range
.rand_range(&mut result
).unwrap();
1038 assert
!(result
>= BigNum
::from_u32(0).unwrap() && result
< range
);
1042 fn test_pseudo_rand_range() {
1043 let range
= BigNum
::from_u32(909829283).unwrap();
1044 let mut result
= BigNum
::from_dec_str(&range
.to_dec_str().unwrap()).unwrap();
1045 range
.pseudo_rand_range(&mut result
).unwrap();
1046 assert
!(result
>= BigNum
::from_u32(0).unwrap() && result
< range
);
1050 fn test_prime_numbers() {
1051 let a
= BigNum
::from_u32(19029017).unwrap();
1052 let mut p
= BigNum
::new().unwrap();
1053 p
.generate_prime(128, true, None
, Some(&a
)).unwrap();
1055 let mut ctx
= BigNumContext
::new().unwrap();
1056 assert
!(p
.is_prime(100, &mut ctx
).unwrap());
1057 assert
!(p
.is_prime_fasttest(100, &mut ctx
, true).unwrap());