Clean up some bignum APIs
This commit is contained in:
parent
e87b75fa03
commit
772a506294
|
|
@ -10,18 +10,20 @@ use crypto::CryptoString;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use types::{Ref, OpenSslType};
|
use types::{Ref, OpenSslType};
|
||||||
|
|
||||||
/// Specifies the desired properties of a randomly generated `BigNum`.
|
/// Options for the most significant bits of a randomly generated `BigNum`.
|
||||||
#[derive(Copy, Clone)]
|
pub struct MsbOption(c_int);
|
||||||
#[repr(C)]
|
|
||||||
pub enum RNGProperty {
|
/// The most significant bit of the number may be 0.
|
||||||
/// The most significant bit of the number is allowed to be 0.
|
pub const MSB_MAYBE_ZERO: MsbOption = MsbOption(-1);
|
||||||
MsbMaybeZero = -1,
|
|
||||||
/// The MSB should be set to 1.
|
/// The most significant bit of the number must be 1.
|
||||||
MsbOne = 0,
|
pub const MSB_ONE: MsbOption = MsbOption(0);
|
||||||
/// The two most significant bits of the number will be set to 1, so that the product of two
|
|
||||||
/// such random numbers will always have `2 * bits` length.
|
/// The most significant two bits of the number must be 1.
|
||||||
TwoMsbOne = 1,
|
///
|
||||||
}
|
/// The number of bits in the product of two such numbers will always be exactly twice the number
|
||||||
|
/// of bits in the original numbers.
|
||||||
|
pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
|
||||||
|
|
||||||
type_!(BigNumContext, ffi::BN_CTX, ffi::BN_CTX_free);
|
type_!(BigNumContext, ffi::BN_CTX, ffi::BN_CTX_free);
|
||||||
|
|
||||||
|
|
@ -193,35 +195,6 @@ impl BigNumContext {
|
||||||
.map(|r| r != 0)
|
.map(|r| r != 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `r`.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * `bits`: Length of the number in bits.
|
|
||||||
/// * `prop`: The desired properties of the number.
|
|
||||||
/// * `odd`: If `true`, the generated number will be odd.
|
|
||||||
pub fn rand(r: &mut Ref<BigNum>,
|
|
||||||
bits: i32,
|
|
||||||
prop: RNGProperty,
|
|
||||||
odd: bool)
|
|
||||||
-> Result<(), ErrorStack> {
|
|
||||||
unsafe {
|
|
||||||
cvt(ffi::BN_rand(r.as_ptr(), bits.into(), prop as c_int, odd as c_int)).map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The cryptographically weak counterpart to `rand`.
|
|
||||||
pub fn pseudo_rand(r: &mut Ref<BigNum>,
|
|
||||||
bits: i32,
|
|
||||||
prop: RNGProperty,
|
|
||||||
odd: bool)
|
|
||||||
-> Result<(), ErrorStack> {
|
|
||||||
unsafe {
|
|
||||||
cvt(ffi::BN_pseudo_rand(r.as_ptr(), bits.into(), prop as c_int, odd as c_int))
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ref<BigNum> {
|
impl Ref<BigNum> {
|
||||||
|
|
@ -385,6 +358,59 @@ impl Ref<BigNum> {
|
||||||
(self.num_bits() + 7) / 8
|
(self.num_bits() + 7) / 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
///
|
||||||
|
/// * `bits`: Length of the number in bits.
|
||||||
|
/// * `msb`: The desired properties of the number.
|
||||||
|
/// * `odd`: If `true`, the generated number will be odd.
|
||||||
|
pub fn rand(&mut self,
|
||||||
|
bits: i32,
|
||||||
|
msb: MsbOption,
|
||||||
|
odd: bool)
|
||||||
|
-> Result<(), ErrorStack> {
|
||||||
|
unsafe {
|
||||||
|
cvt(ffi::BN_rand(self.as_ptr(), bits.into(), msb.0, odd as c_int)).map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The cryptographically weak counterpart to `rand`.
|
||||||
|
pub fn pseudo_rand(&mut self,
|
||||||
|
bits: i32,
|
||||||
|
msb: MsbOption,
|
||||||
|
odd: bool)
|
||||||
|
-> Result<(), ErrorStack> {
|
||||||
|
unsafe {
|
||||||
|
cvt(ffi::BN_pseudo_rand(self.as_ptr(), bits.into(), msb.0, odd as c_int)).map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a prime number, placing it in `self`.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
///
|
||||||
|
/// * `bits`: The length of the prime in bits (lower bound).
|
||||||
|
/// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
|
||||||
|
/// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
|
||||||
|
/// generated prime and `rem` is `1` if not specified (`None`).
|
||||||
|
pub fn generate_prime(&mut self,
|
||||||
|
bits: i32,
|
||||||
|
safe: bool,
|
||||||
|
add: Option<&Ref<BigNum>>,
|
||||||
|
rem: Option<&Ref<BigNum>>)
|
||||||
|
-> Result<(), ErrorStack> {
|
||||||
|
unsafe {
|
||||||
|
cvt(ffi::BN_generate_prime_ex(self.as_ptr(),
|
||||||
|
bits as c_int,
|
||||||
|
safe as c_int,
|
||||||
|
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
||||||
|
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
||||||
|
ptr::null_mut()))
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a big-endian byte vector representation of the absolute value of `self`.
|
/// Returns a big-endian byte vector representation of the absolute value of `self`.
|
||||||
///
|
///
|
||||||
/// `self` can be recreated by using `new_from_slice`.
|
/// `self` can be recreated by using `new_from_slice`.
|
||||||
|
|
@ -492,31 +518,6 @@ impl BigNum {
|
||||||
.map(|p| BigNum::from_ptr(p))
|
.map(|p| BigNum::from_ptr(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a prime number, placing it in `r`.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// * `bits`: The length of the prime in bits (lower bound).
|
|
||||||
/// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime.
|
|
||||||
/// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the
|
|
||||||
/// generated prime and `rem` is `1` if not specified (`None`).
|
|
||||||
pub fn generate_prime(r: &mut Ref<BigNum>,
|
|
||||||
bits: i32,
|
|
||||||
safe: bool,
|
|
||||||
add: Option<&Ref<BigNum>>,
|
|
||||||
rem: Option<&Ref<BigNum>>)
|
|
||||||
-> Result<(), ErrorStack> {
|
|
||||||
unsafe {
|
|
||||||
cvt(ffi::BN_generate_prime_ex(r.as_ptr(),
|
|
||||||
bits as c_int,
|
|
||||||
safe as c_int,
|
|
||||||
add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
|
||||||
rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()),
|
|
||||||
ptr::null_mut()))
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<Ref<BigNum>> for BigNum {
|
impl AsRef<Ref<BigNum>> for BigNum {
|
||||||
|
|
@ -803,7 +804,7 @@ mod tests {
|
||||||
fn test_prime_numbers() {
|
fn test_prime_numbers() {
|
||||||
let a = BigNum::from_u32(19029017).unwrap();
|
let a = BigNum::from_u32(19029017).unwrap();
|
||||||
let mut p = BigNum::new().unwrap();
|
let mut p = BigNum::new().unwrap();
|
||||||
BigNum::generate_prime(&mut p, 128, true, None, Some(&a)).unwrap();
|
p.generate_prime(128, true, None, Some(&a)).unwrap();
|
||||||
|
|
||||||
let mut ctx = BigNumContext::new().unwrap();
|
let mut ctx = BigNumContext::new().unwrap();
|
||||||
assert!(ctx.is_prime(&p, 100).unwrap());
|
assert!(ctx.is_prime(&p, 100).unwrap());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue