diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index c4545df..0000000 --- a/Cargo.lock +++ /dev/null @@ -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" - diff --git a/Cargo.toml b/Cargo.toml index 7da8655..b9dacda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 = [] diff --git a/README.md b/README.md index cfbe3dc..c77b87a 100644 --- a/README.md +++ b/README.md @@ -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`: diff --git a/src/prime.rs b/src/prime.rs index 8c7b2b4..1294b7d 100644 --- a/src/prime.rs +++ b/src/prime.rs @@ -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;