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