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