]> git.proxmox.com Git - cargo.git/blob - vendor/openssl-0.9.19/src/bn.rs
New upstream version 0.23.0
[cargo.git] / vendor / openssl-0.9.19 / src / bn.rs
1 use ffi;
2 use foreign_types::{ForeignType, ForeignTypeRef};
3 use libc::c_int;
4 use std::cmp::Ordering;
5 use std::ffi::CString;
6 use std::{fmt, ptr};
7 use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
8
9 use {cvt, cvt_p, cvt_n};
10 use asn1::Asn1Integer;
11 use error::ErrorStack;
12 use string::OpensslString;
13
14 #[cfg(ossl10x)]
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};
23
24 #[cfg(ossl110)]
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};
28
29 /// Options for the most significant bits of a randomly generated `BigNum`.
30 pub struct MsbOption(c_int);
31
32 /// The most significant bit of the number may be 0.
33 pub const MSB_MAYBE_ZERO: MsbOption = MsbOption(-1);
34
35 /// The most significant bit of the number must be 1.
36 pub const MSB_ONE: MsbOption = MsbOption(0);
37
38 /// The most significant two bits of the number must be 1.
39 ///
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);
43
44 foreign_type! {
45 type CType = ffi::BN_CTX;
46 fn drop = ffi::BN_CTX_free;
47
48 pub struct BigNumContext;
49 pub struct BigNumContextRef;
50 }
51
52 impl BigNumContext {
53 /// Returns a new `BigNumContext`.
54 pub fn new() -> Result<BigNumContext, ErrorStack> {
55 unsafe {
56 ffi::init();
57 cvt_p(ffi::BN_CTX_new()).map(BigNumContext)
58 }
59 }
60 }
61
62 impl BigNumRef {
63 /// Erases the memory used by this `BigNum`, resetting its value to 0.
64 ///
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()) }
68 }
69
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(|_| ()) }
73 }
74
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(|_| ()) }
78 }
79
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(|_| ()) }
83 }
84
85 /// Divides `self` by a `u32`, returning the remainder.
86 pub fn div_word(&mut self, w: u32) -> Result<u64, ErrorStack> {
87 unsafe {
88 let r = ffi::BN_div_word(self.as_ptr(), w.into());
89 if r == ffi::BN_ULONG::max_value() {
90 Err(ErrorStack::get())
91 } else {
92 Ok(r.into())
93 }
94 }
95 }
96
97 /// Returns the result of `self` modulo `w`.
98 pub fn mod_word(&self, w: u32) -> Result<u64, ErrorStack> {
99 unsafe {
100 let r = ffi::BN_mod_word(self.as_ptr(), w.into());
101 if r == ffi::BN_ULONG::max_value() {
102 Err(ErrorStack::get())
103 } else {
104 Ok(r.into())
105 }
106 }
107 }
108
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(|_| ()) }
113 }
114
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(|_| ()) }
118 }
119
120 /// Sets bit `n`. Equivalent to `self |= (1 << n)`.
121 ///
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(|_| ()) }
125 }
126
127 /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
128 ///
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(|_| ()) }
132 }
133
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 }
137 }
138
139 /// Truncates `self` to the lowest `n` bits.
140 ///
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(|_| ()) }
144 }
145
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(|_| ()) }
149 }
150
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(|_| ()) }
154 }
155
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(|_| ()) }
159 }
160
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(|_| ()) }
164 }
165
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(|_| ()) }
169 }
170
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(|_| ()) }
174 }
175
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)) }
178 }
179
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) }
183 }
184
185 /// Compare the absolute values of `self` and `oth`.
186 ///
187 /// ```
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();
192 ///
193 /// assert_eq!(s.ucmp(&o), Ordering::Equal);
194 /// ```
195 pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
196 unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
197 }
198
199 pub fn is_negative(&self) -> bool {
200 self._is_negative()
201 }
202
203 #[cfg(ossl10x)]
204 fn _is_negative(&self) -> bool {
205 unsafe { (*self.as_ptr()).neg == 1 }
206 }
207
208 #[cfg(ossl110)]
209 fn _is_negative(&self) -> bool {
210 unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 }
211 }
212
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 }
216 }
217
218 /// Returns the size of `self` in bytes.
219 pub fn num_bytes(&self) -> i32 {
220 (self.num_bits() + 7) / 8
221 }
222
223 /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
224 ///
225 /// # Parameters
226 ///
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> {
231 unsafe {
232 cvt(ffi::BN_rand(
233 self.as_ptr(),
234 bits.into(),
235 msb.0,
236 odd as c_int,
237 )).map(|_| ())
238 }
239 }
240
241 /// The cryptographically weak counterpart to `rand`.
242 pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> {
243 unsafe {
244 cvt(ffi::BN_pseudo_rand(
245 self.as_ptr(),
246 bits.into(),
247 msb.0,
248 odd as c_int,
249 )).map(|_| ())
250 }
251 }
252
253 /// Generates a prime number, placing it in `self`.
254 ///
255 /// # Parameters
256 ///
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(
262 &mut self,
263 bits: i32,
264 safe: bool,
265 add: Option<&BigNumRef>,
266 rem: Option<&BigNumRef>,
267 ) -> Result<(), ErrorStack> {
268 unsafe {
269 cvt(ffi::BN_generate_prime_ex(
270 self.as_ptr(),
271 bits as c_int,
272 safe as c_int,
273 add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
274 rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
275 ptr::null_mut(),
276 )).map(|_| ())
277 }
278 }
279
280 /// Places the result of `a * b` in `self`.
281 pub fn checked_mul(
282 &mut self,
283 a: &BigNumRef,
284 b: &BigNumRef,
285 ctx: &mut BigNumContextRef,
286 ) -> Result<(), ErrorStack> {
287 unsafe {
288 cvt(ffi::BN_mul(
289 self.as_ptr(),
290 a.as_ptr(),
291 b.as_ptr(),
292 ctx.as_ptr(),
293 )).map(|_| ())
294 }
295 }
296
297 /// Places the result of `a / b` in `self`.
298 pub fn checked_div(
299 &mut self,
300 a: &BigNumRef,
301 b: &BigNumRef,
302 ctx: &mut BigNumContextRef,
303 ) -> Result<(), ErrorStack> {
304 unsafe {
305 cvt(ffi::BN_div(
306 self.as_ptr(),
307 ptr::null_mut(),
308 a.as_ptr(),
309 b.as_ptr(),
310 ctx.as_ptr(),
311 )).map(|_| ())
312 }
313 }
314
315 /// Places the result of `a % b` in `self`.
316 pub fn checked_rem(
317 &mut self,
318 a: &BigNumRef,
319 b: &BigNumRef,
320 ctx: &mut BigNumContextRef,
321 ) -> Result<(), ErrorStack> {
322 unsafe {
323 cvt(ffi::BN_div(
324 ptr::null_mut(),
325 self.as_ptr(),
326 a.as_ptr(),
327 b.as_ptr(),
328 ctx.as_ptr(),
329 )).map(|_| ())
330 }
331 }
332
333 /// Places the result of `a / b` in `self` and `a % b` in `rem`.
334 pub fn div_rem(
335 &mut self,
336 rem: &mut BigNumRef,
337 a: &BigNumRef,
338 b: &BigNumRef,
339 ctx: &mut BigNumContextRef,
340 ) -> Result<(), ErrorStack> {
341 unsafe {
342 cvt(ffi::BN_div(
343 self.as_ptr(),
344 rem.as_ptr(),
345 a.as_ptr(),
346 b.as_ptr(),
347 ctx.as_ptr(),
348 )).map(|_| ())
349 }
350 }
351
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(|_| ()) }
355 }
356
357 /// Places the result of `a mod m` in `self`.
358 pub fn nnmod(
359 &mut self,
360 a: &BigNumRef,
361 m: &BigNumRef,
362 ctx: &mut BigNumContextRef,
363 ) -> Result<(), ErrorStack> {
364 unsafe {
365 cvt(ffi::BN_nnmod(
366 self.as_ptr(),
367 a.as_ptr(),
368 m.as_ptr(),
369 ctx.as_ptr(),
370 )).map(|_| ())
371 }
372 }
373
374 /// Places the result of `(a + b) mod m` in `self`.
375 pub fn mod_add(
376 &mut self,
377 a: &BigNumRef,
378 b: &BigNumRef,
379 m: &BigNumRef,
380 ctx: &mut BigNumContextRef,
381 ) -> Result<(), ErrorStack> {
382 unsafe {
383 cvt(ffi::BN_mod_add(
384 self.as_ptr(),
385 a.as_ptr(),
386 b.as_ptr(),
387 m.as_ptr(),
388 ctx.as_ptr(),
389 )).map(|_| ())
390 }
391 }
392
393 /// Places the result of `(a - b) mod m` in `self`.
394 pub fn mod_sub(
395 &mut self,
396 a: &BigNumRef,
397 b: &BigNumRef,
398 m: &BigNumRef,
399 ctx: &mut BigNumContextRef,
400 ) -> Result<(), ErrorStack> {
401 unsafe {
402 cvt(ffi::BN_mod_sub(
403 self.as_ptr(),
404 a.as_ptr(),
405 b.as_ptr(),
406 m.as_ptr(),
407 ctx.as_ptr(),
408 )).map(|_| ())
409 }
410 }
411
412 /// Places the result of `(a * b) mod m` in `self`.
413 pub fn mod_mul(
414 &mut self,
415 a: &BigNumRef,
416 b: &BigNumRef,
417 m: &BigNumRef,
418 ctx: &mut BigNumContextRef,
419 ) -> Result<(), ErrorStack> {
420 unsafe {
421 cvt(ffi::BN_mod_mul(
422 self.as_ptr(),
423 a.as_ptr(),
424 b.as_ptr(),
425 m.as_ptr(),
426 ctx.as_ptr(),
427 )).map(|_| ())
428 }
429 }
430
431 /// Places the result of `a² mod m` in `self`.
432 pub fn mod_sqr(
433 &mut self,
434 a: &BigNumRef,
435 m: &BigNumRef,
436 ctx: &mut BigNumContextRef,
437 ) -> Result<(), ErrorStack> {
438 unsafe {
439 cvt(ffi::BN_mod_sqr(
440 self.as_ptr(),
441 a.as_ptr(),
442 m.as_ptr(),
443 ctx.as_ptr(),
444 )).map(|_| ())
445 }
446 }
447
448 /// Places the result of `a^p` in `self`.
449 pub fn exp(
450 &mut self,
451 a: &BigNumRef,
452 p: &BigNumRef,
453 ctx: &mut BigNumContextRef,
454 ) -> Result<(), ErrorStack> {
455 unsafe {
456 cvt(ffi::BN_exp(
457 self.as_ptr(),
458 a.as_ptr(),
459 p.as_ptr(),
460 ctx.as_ptr(),
461 )).map(|_| ())
462 }
463 }
464
465 /// Places the result of `a^p mod m` in `self`.
466 pub fn mod_exp(
467 &mut self,
468 a: &BigNumRef,
469 p: &BigNumRef,
470 m: &BigNumRef,
471 ctx: &mut BigNumContextRef,
472 ) -> Result<(), ErrorStack> {
473 unsafe {
474 cvt(ffi::BN_mod_exp(
475 self.as_ptr(),
476 a.as_ptr(),
477 p.as_ptr(),
478 m.as_ptr(),
479 ctx.as_ptr(),
480 )).map(|_| ())
481 }
482 }
483
484 /// Places the inverse of `a` modulo `n` in `self`.
485 pub fn mod_inverse(
486 &mut self,
487 a: &BigNumRef,
488 n: &BigNumRef,
489 ctx: &mut BigNumContextRef,
490 ) -> Result<(), ErrorStack> {
491 unsafe {
492 cvt_p(ffi::BN_mod_inverse(
493 self.as_ptr(),
494 a.as_ptr(),
495 n.as_ptr(),
496 ctx.as_ptr(),
497 )).map(|_| ())
498 }
499 }
500
501 /// Places the greatest common denominator of `a` and `b` in `self`.
502 pub fn gcd(
503 &mut self,
504 a: &BigNumRef,
505 b: &BigNumRef,
506 ctx: &mut BigNumContextRef,
507 ) -> Result<(), ErrorStack> {
508 unsafe {
509 cvt(ffi::BN_gcd(
510 self.as_ptr(),
511 a.as_ptr(),
512 b.as_ptr(),
513 ctx.as_ptr(),
514 )).map(|_| ())
515 }
516 }
517
518 /// Checks whether `self` is prime.
519 ///
520 /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations.
521 ///
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> {
524 unsafe {
525 cvt_n(ffi::BN_is_prime_ex(
526 self.as_ptr(),
527 checks.into(),
528 ctx.as_ptr(),
529 ptr::null_mut(),
530 )).map(|r| r != 0)
531 }
532 }
533
534 /// Checks whether `self` is prime with optional trial division.
535 ///
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`
538 /// iterations.
539 ///
540 /// # Return Value
541 ///
542 /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
543 pub fn is_prime_fasttest(
544 &self,
545 checks: i32,
546 ctx: &mut BigNumContextRef,
547 do_trial_division: bool,
548 ) -> Result<bool, ErrorStack> {
549 unsafe {
550 cvt_n(ffi::BN_is_prime_fasttest_ex(
551 self.as_ptr(),
552 checks.into(),
553 ctx.as_ptr(),
554 do_trial_division as c_int,
555 ptr::null_mut(),
556 )).map(|r| r != 0)
557 }
558 }
559
560 /// Returns a big-endian byte vector representation of the absolute value of `self`.
561 ///
562 /// `self` can be recreated by using `from_slice`.
563 ///
564 /// ```
565 /// # use openssl::bn::BigNum;
566 /// let s = -BigNum::from_u32(4543).unwrap();
567 /// let r = BigNum::from_u32(4543).unwrap();
568 ///
569 /// let s_vec = s.to_vec();
570 /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r);
571 /// ```
572 pub fn to_vec(&self) -> Vec<u8> {
573 let size = self.num_bytes() as usize;
574 let mut v = Vec::with_capacity(size);
575 unsafe {
576 ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr());
577 v.set_len(size);
578 }
579 v
580 }
581
582 /// Returns a decimal string representation of `self`.
583 ///
584 /// ```
585 /// # use openssl::bn::BigNum;
586 /// let s = -BigNum::from_u32(12345).unwrap();
587 ///
588 /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345");
589 /// ```
590 pub fn to_dec_str(&self) -> Result<OpensslString, ErrorStack> {
591 unsafe {
592 let buf = try!(cvt_p(ffi::BN_bn2dec(self.as_ptr())));
593 Ok(OpensslString::from_ptr(buf))
594 }
595 }
596
597 /// Returns a hexadecimal string representation of `self`.
598 ///
599 /// ```
600 /// # use openssl::bn::BigNum;
601 /// let s = -BigNum::from_u32(0x99ff).unwrap();
602 ///
603 /// assert_eq!(&**s.to_hex_str().unwrap(), "-99FF");
604 /// ```
605 pub fn to_hex_str(&self) -> Result<OpensslString, ErrorStack> {
606 unsafe {
607 let buf = try!(cvt_p(ffi::BN_bn2hex(self.as_ptr())));
608 Ok(OpensslString::from_ptr(buf))
609 }
610 }
611
612 /// Returns an `Asn1Integer` containing the value of `self`.
613 pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
614 unsafe {
615 cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
616 .map(|p| Asn1Integer::from_ptr(p))
617 }
618 }
619 }
620
621 foreign_type! {
622 type CType = ffi::BIGNUM;
623 fn drop = ffi::BN_free;
624
625 pub struct BigNum;
626 pub struct BigNumRef;
627 }
628
629 impl BigNum {
630 /// Creates a new `BigNum` with the value 0.
631 pub fn new() -> Result<BigNum, ErrorStack> {
632 unsafe {
633 ffi::init();
634 let v = try!(cvt_p(ffi::BN_new()));
635 Ok(BigNum::from_ptr(v))
636 }
637 }
638
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)
643 })
644 }
645
646 /// Creates a `BigNum` from a decimal string.
647 pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
648 unsafe {
649 ffi::init();
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))
654 }
655 }
656
657 /// Creates a `BigNum` from a hexadecimal string.
658 pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
659 unsafe {
660 ffi::init();
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))
665 }
666 }
667
668 pub fn get_rfc2409_prime_768() -> Result<BigNum, ErrorStack> {
669 unsafe {
670 ffi::init();
671 cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum)
672 }
673 }
674
675 pub fn get_rfc2409_prime_1024() -> Result<BigNum, ErrorStack> {
676 unsafe {
677 ffi::init();
678 cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum)
679 }
680 }
681
682 pub fn get_rfc3526_prime_1536() -> Result<BigNum, ErrorStack> {
683 unsafe {
684 ffi::init();
685 cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum)
686 }
687 }
688
689 pub fn get_rfc3526_prime_2048() -> Result<BigNum, ErrorStack> {
690 unsafe {
691 ffi::init();
692 cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum)
693 }
694 }
695
696 pub fn get_rfc3526_prime_3072() -> Result<BigNum, ErrorStack> {
697 unsafe {
698 ffi::init();
699 cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum)
700 }
701 }
702
703 pub fn get_rfc3526_prime_4096() -> Result<BigNum, ErrorStack> {
704 unsafe {
705 ffi::init();
706 cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum)
707 }
708 }
709
710 pub fn get_rfc3526_prime_6144() -> Result<BigNum, ErrorStack> {
711 unsafe {
712 ffi::init();
713 cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum)
714 }
715 }
716
717 pub fn get_rfc3526_prime_8192() -> Result<BigNum, ErrorStack> {
718 unsafe {
719 ffi::init();
720 cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum)
721 }
722 }
723
724 /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length.
725 ///
726 /// ```
727 /// # use openssl::bn::BigNum;
728 /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap();
729 ///
730 /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap());
731 /// ```
732 pub fn from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
733 unsafe {
734 ffi::init();
735 assert!(n.len() <= c_int::max_value() as usize);
736 cvt_p(ffi::BN_bin2bn(
737 n.as_ptr(),
738 n.len() as c_int,
739 ptr::null_mut(),
740 )).map(|p| BigNum::from_ptr(p))
741 }
742 }
743 }
744
745 impl AsRef<BigNumRef> for BigNum {
746 fn as_ref(&self) -> &BigNumRef {
747 self.deref()
748 }
749 }
750
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()),
756 }
757 }
758 }
759
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()),
765 }
766 }
767 }
768
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()),
774 }
775 }
776 }
777
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()),
783 }
784 }
785 }
786
787 impl PartialEq<BigNumRef> for BigNumRef {
788 fn eq(&self, oth: &BigNumRef) -> bool {
789 self.cmp(oth) == Ordering::Equal
790 }
791 }
792
793 impl PartialEq<BigNum> for BigNumRef {
794 fn eq(&self, oth: &BigNum) -> bool {
795 self.eq(oth.deref())
796 }
797 }
798
799 impl Eq for BigNumRef {}
800
801 impl PartialEq for BigNum {
802 fn eq(&self, oth: &BigNum) -> bool {
803 self.deref().eq(oth)
804 }
805 }
806
807 impl PartialEq<BigNumRef> for BigNum {
808 fn eq(&self, oth: &BigNumRef) -> bool {
809 self.deref().eq(oth)
810 }
811 }
812
813 impl Eq for BigNum {}
814
815 impl PartialOrd<BigNumRef> for BigNumRef {
816 fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
817 Some(self.cmp(oth))
818 }
819 }
820
821 impl PartialOrd<BigNum> for BigNumRef {
822 fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
823 Some(self.cmp(oth.deref()))
824 }
825 }
826
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) }
830 }
831 }
832
833 impl PartialOrd for BigNum {
834 fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
835 self.deref().partial_cmp(oth.deref())
836 }
837 }
838
839 impl PartialOrd<BigNumRef> for BigNum {
840 fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
841 self.deref().partial_cmp(oth)
842 }
843 }
844
845 impl Ord for BigNum {
846 fn cmp(&self, oth: &BigNum) -> Ordering {
847 self.deref().cmp(oth.deref())
848 }
849 }
850
851 macro_rules! delegate {
852 ($t:ident, $m:ident) => {
853 impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
854 type Output = BigNum;
855
856 fn $m(self, oth: &BigNum) -> BigNum {
857 $t::$m(self, oth.deref())
858 }
859 }
860
861 impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
862 type Output = BigNum;
863
864 fn $m(self, oth: &BigNumRef) -> BigNum {
865 $t::$m(self.deref(), oth)
866 }
867 }
868
869 impl<'a, 'b> $t<&'b BigNum> for &'a BigNum {
870 type Output = BigNum;
871
872 fn $m(self, oth: &BigNum) -> BigNum {
873 $t::$m(self.deref(), oth.deref())
874 }
875 }
876 }
877 }
878
879 impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
880 type Output = BigNum;
881
882 fn add(self, oth: &BigNumRef) -> BigNum {
883 let mut r = BigNum::new().unwrap();
884 r.checked_add(self, oth).unwrap();
885 r
886 }
887 }
888
889 delegate!(Add, add);
890
891 impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
892 type Output = BigNum;
893
894 fn sub(self, oth: &BigNumRef) -> BigNum {
895 let mut r = BigNum::new().unwrap();
896 r.checked_sub(self, oth).unwrap();
897 r
898 }
899 }
900
901 delegate!(Sub, sub);
902
903 impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
904 type Output = BigNum;
905
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();
910 r
911 }
912 }
913
914 delegate!(Mul, mul);
915
916 impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
917 type Output = BigNum;
918
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();
923 r
924 }
925 }
926
927 delegate!(Div, div);
928
929 impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
930 type Output = BigNum;
931
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();
936 r
937 }
938 }
939
940 delegate!(Rem, rem);
941
942 impl<'a> Shl<i32> for &'a BigNumRef {
943 type Output = BigNum;
944
945 fn shl(self, n: i32) -> BigNum {
946 let mut r = BigNum::new().unwrap();
947 r.lshift(self, n).unwrap();
948 r
949 }
950 }
951
952 impl<'a> Shl<i32> for &'a BigNum {
953 type Output = BigNum;
954
955 fn shl(self, n: i32) -> BigNum {
956 self.deref().shl(n)
957 }
958 }
959
960 impl<'a> Shr<i32> for &'a BigNumRef {
961 type Output = BigNum;
962
963 fn shr(self, n: i32) -> BigNum {
964 let mut r = BigNum::new().unwrap();
965 r.rshift(self, n).unwrap();
966 r
967 }
968 }
969
970 impl<'a> Shr<i32> for &'a BigNum {
971 type Output = BigNum;
972
973 fn shr(self, n: i32) -> BigNum {
974 self.deref().shr(n)
975 }
976 }
977
978 impl<'a> Neg for &'a BigNumRef {
979 type Output = BigNum;
980
981 fn neg(self) -> BigNum {
982 self.to_owned().unwrap().neg()
983 }
984 }
985
986 impl<'a> Neg for &'a BigNum {
987 type Output = BigNum;
988
989 fn neg(self) -> BigNum {
990 self.deref().neg()
991 }
992 }
993
994 impl Neg for BigNum {
995 type Output = BigNum;
996
997 fn neg(mut self) -> BigNum {
998 let negative = self.is_negative();
999 self.set_negative(!negative);
1000 self
1001 }
1002 }
1003
1004 #[cfg(test)]
1005 mod tests {
1006 use bn::{BigNumContext, BigNum};
1007
1008 #[test]
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();
1013
1014 assert!(v0 == v1);
1015 }
1016
1017 #[test]
1018 fn test_negation() {
1019 let a = BigNum::from_u32(909829283).unwrap();
1020
1021 assert!(!a.is_negative());
1022 assert!((-a).is_negative());
1023 }
1024
1025 #[test]
1026 fn test_shift() {
1027 let a = BigNum::from_u32(909829283).unwrap();
1028 use std::ops::{Shl, Shr};
1029
1030 assert!(a == a.shl(1).shr(1));
1031 }
1032
1033 #[test]
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);
1039 }
1040
1041 #[test]
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);
1047 }
1048
1049 #[test]
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();
1054
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());
1058 }
1059 }