pumpkin 2.0.1

A cryptographically secure prime number generator
//! Generates [safe prime numbers](https://www.wikiwand.com/en/Sophie_Germain_prime).

use ramp::Int;
use rand::OsRng;

pub use common::{gen_prime, is_prime};
use error::{Error, Result};

/// Constructs a new `SafePrime` with a size of `bit_length` bits.
///
/// This will initialize an `OsRng` instance and call the
/// `SafePrime::from_rng()` method.
///
/// Note: the `bit_length` MUST be at least 512-bits.
pub fn new(bit_length: usize) -> Result {
    if bit_length < 512 {
        Err(Error::BitLength(bit_length))
    } else {
        let mut rngesus = try!(OsRng::new());
        Ok(try!(from_rng(bit_length, &mut rngesus)))
    }
}

/// Constructs a new `SafePrime` with the size of `bit_length` bits, sourced
/// from an already-initialized `OsRng`.
pub fn from_rng(bit_length: usize, mut rngesus: &mut OsRng) -> Result {
    if bit_length < 512 {
        Err(Error::BitLength(bit_length))
    } else {
        let mut candidate: Int;

        loop {
            candidate = try!(gen_prime(bit_length, &mut rngesus));

            let mut candidate_p = (&candidate).clone();
            candidate_p -= 1_usize;
            candidate_p /= 2_usize;

            if is_prime(&candidate_p) {
                break;
            }
        }

        Ok(candidate)
    }
}

#[cfg(test)]
mod tests {
    use super::new;

    #[test]
    fn test_safe_prime_bit_length_too_small() {
        let sp = new(511);
        assert_eq!(false, match sp {
            Ok(_) => true,
            Err(_) => false
        });
    }

    #[test]
    fn test_safe_prime() {
        let sp = new(512);
        assert_eq!(true, match sp {
            Ok(_) => true,
            Err(_) => false
        });
    }
}