Added another Prime generator function

This commit is contained in:
Zach Dziura 2015-10-22 17:14:05 -04:00
parent 11fdbb8c8e
commit 01cccc03e1
4 changed files with 64 additions and 80 deletions

72
Cargo.lock generated
View file

@ -1,72 +0,0 @@
[root]
name = "pumpkin"
version = "0.1.0"
dependencies = [
"custom_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"newtype_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ramp 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "advapi32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "custom_derive"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "newtype_derive"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ramp"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

View file

@ -8,7 +8,14 @@ keywords = ["prime", "number", "cryptography", "generator"]
license = "Unlicense/MIT"
[dependencies]
custom_derive = "0.1.2"
newtype_derive = "0.1.2"
custom_derive = "0.1.*"
newtype_derive = "0.1.*"
ramp = "0.1.*"
rand = "0.3.11"
rand = "0.3.*"
[lib]
name = "pumpkin"
path = "src/lib.rs"
[features]
unstable = []

View file

@ -20,6 +20,16 @@ numbers. `pumpkin` generates numbers very quickly, so you can be sure that your
program will be performative. In our testing, primes were generated anywhere
between 1s and 5s on average, though of course your mileage may vary.
## Installation
Add the following to your `Cargo.toml` file:
```
pumpkin = "0.2.0"
```
Note that `pumpkin` requires the `nightly` Rust compiler.
## Example
```rust
@ -41,6 +51,36 @@ fn main() {
}
```
You can also initialize your own `OsRng` and generate `Prime`s from that. Doing
so will reduce some runtime overhead.
```rust
extern crate pumpkin;
extern crate rand;
use pumpkin::Prime;
use rand::OsRng;
fn main() {
let mut rngesus = match OsRng::new() {
Ok(rng) => rng,
Err(e) => panic!("Error trying to initializing RNG: {}", e)
};
let p = Prime::from_rng(2048, &mut rngesus);
let q = Prime::from_rng(2048, &mut rngesus);
let e = p * q;
println!("{}", e);
/*
* 75222035638256552797269351238215022250546763213674706... Some massive
* 4096-bit number.
*/
}
## Explanation
`Prime`s are generated much the same way that large primes are generated by
`GnuPG`:

View file

@ -107,13 +107,22 @@ impl Prime {
/// The `bit_length` must be at least 2. While it doesn't make much sense
/// to only generate a 2-bit random number, them's the rules.
pub fn new(bit_length: usize) -> Prime {
assert!(bit_length >= 2);
let one = Int::one();
let two = &one + &one;
debug_assert!(bit_length >= 2);
let mut rngesus = match OsRng::new() {
Ok(rng) => rng,
Err(reason) => panic!("Error initializing RNG: {}", reason)
};
Prime::from_rng(bit_length, &mut rngesus)
}
/// Constructs a new `Prime` with the size of `bit_length` bits, sourced
/// from an already-created `OsRng`. Not that you can **ONLY** use an
/// `OsRng`, as it uses the operating system's secure source of entropy.
pub fn from_rng(bit_length: usize, rngesus: &mut OsRng) -> Prime {
debug_assert!(bit_length >= 2);
let one = Int::one();
let two = &one + &one;
let mut candidate = rngesus.gen_uint(bit_length);
// Make sure candidate is odd before continuing...
@ -186,14 +195,14 @@ fn miller_rabin(candidate: &Int) -> bool {
let one = Int::one();
let two = (&one).add(&one);
for _ in (0..5) {
for _ in 0..5 {
let basis = thread_rng().gen_int_range(&two, candidate);
let mut x = mod_exp(&basis, &d, candidate);
if x.eq(&one) || x.eq(&(candidate.sub(&one))) {
continue;
} else {
for _ in (one.clone() .. s.sub(&one)) {
for _ in one.clone() .. s.sub(&one) {
x = mod_exp(&x, &two, candidate);
if x == one.clone() {
return false;