Added another Prime generator function
This commit is contained in:
parent
11fdbb8c8e
commit
01cccc03e1
4 changed files with 64 additions and 80 deletions
72
Cargo.lock
generated
72
Cargo.lock
generated
|
@ -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"
|
|
||||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -8,7 +8,14 @@ keywords = ["prime", "number", "cryptography", "generator"]
|
||||||
license = "Unlicense/MIT"
|
license = "Unlicense/MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
custom_derive = "0.1.2"
|
custom_derive = "0.1.*"
|
||||||
newtype_derive = "0.1.2"
|
newtype_derive = "0.1.*"
|
||||||
ramp = "0.1.*"
|
ramp = "0.1.*"
|
||||||
rand = "0.3.11"
|
rand = "0.3.*"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "pumpkin"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
unstable = []
|
||||||
|
|
40
README.md
40
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
|
program will be performative. In our testing, primes were generated anywhere
|
||||||
between 1s and 5s on average, though of course your mileage may vary.
|
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
|
## Example
|
||||||
|
|
||||||
```rust
|
```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
|
## Explanation
|
||||||
`Prime`s are generated much the same way that large primes are generated by
|
`Prime`s are generated much the same way that large primes are generated by
|
||||||
`GnuPG`:
|
`GnuPG`:
|
||||||
|
|
19
src/prime.rs
19
src/prime.rs
|
@ -107,13 +107,22 @@ impl Prime {
|
||||||
/// The `bit_length` must be at least 2. While it doesn't make much sense
|
/// 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.
|
/// to only generate a 2-bit random number, them's the rules.
|
||||||
pub fn new(bit_length: usize) -> Prime {
|
pub fn new(bit_length: usize) -> Prime {
|
||||||
assert!(bit_length >= 2);
|
debug_assert!(bit_length >= 2);
|
||||||
let one = Int::one();
|
|
||||||
let two = &one + &one;
|
|
||||||
let mut rngesus = match OsRng::new() {
|
let mut rngesus = match OsRng::new() {
|
||||||
Ok(rng) => rng,
|
Ok(rng) => rng,
|
||||||
Err(reason) => panic!("Error initializing RNG: {}", reason)
|
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);
|
let mut candidate = rngesus.gen_uint(bit_length);
|
||||||
|
|
||||||
// Make sure candidate is odd before continuing...
|
// Make sure candidate is odd before continuing...
|
||||||
|
@ -186,14 +195,14 @@ fn miller_rabin(candidate: &Int) -> bool {
|
||||||
let one = Int::one();
|
let one = Int::one();
|
||||||
let two = (&one).add(&one);
|
let two = (&one).add(&one);
|
||||||
|
|
||||||
for _ in (0..5) {
|
for _ in 0..5 {
|
||||||
let basis = thread_rng().gen_int_range(&two, candidate);
|
let basis = thread_rng().gen_int_range(&two, candidate);
|
||||||
let mut x = mod_exp(&basis, &d, candidate);
|
let mut x = mod_exp(&basis, &d, candidate);
|
||||||
|
|
||||||
if x.eq(&one) || x.eq(&(candidate.sub(&one))) {
|
if x.eq(&one) || x.eq(&(candidate.sub(&one))) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
for _ in (one.clone() .. s.sub(&one)) {
|
for _ in one.clone() .. s.sub(&one) {
|
||||||
x = mod_exp(&x, &two, candidate);
|
x = mod_exp(&x, &two, candidate);
|
||||||
if x == one.clone() {
|
if x == one.clone() {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue