diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..1ee36af --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,56 @@ +[root] +name = "pumpkin" +version = "0.1.0" +dependencies = [ + "num 0.1.27 (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 = "libc" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.16 (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 = "rustc-serialize" +version = "0.3.16" +source = "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 622c879..b9aebd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,3 +2,7 @@ name = "pumpkin" version = "0.1.0" authors = ["Zach Dziura "] + +[dependencies] +num = "0.1.27" +rand = "0.3.11" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index aeff992..0000000 --- a/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2015, Zach Dziura -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of pumpkin nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..62654dc --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +Copyright © `2015` `Zachary Dziura` + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/UNLICENSE.md b/UNLICENSE.md new file mode 100644 index 0000000..368c4aa --- /dev/null +++ b/UNLICENSE.md @@ -0,0 +1,27 @@ +Unlicense (Public Domain) +============================ + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to <> diff --git a/WAIVER b/WAIVER new file mode 100644 index 0000000..154385b --- /dev/null +++ b/WAIVER @@ -0,0 +1,5 @@ +I dedicate any and all copyright interest in this software to the +public domain. I make this dedication for the benefit of the public at +large and to the detriment of my heirs and successors. I intend this +dedication to be an overt act of relinquishment in perpetuity of all +present and future rights to this software under copyright law. diff --git a/src/lib.rs b/src/lib.rs index e69de29..7b8b3a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -0,0 +1,4 @@ +extern crate num; +extern crate rand; + +pub mod primes; diff --git a/src/primes.rs b/src/primes.rs new file mode 100644 index 0000000..63e15cc --- /dev/null +++ b/src/primes.rs @@ -0,0 +1,108 @@ +use num::{BigUint, FromPrimitive, One, Zero, pow}; +use num::bigint::RandBigInt; +use num::integer::Integer; + +use rand::{OsRng, thread_rng}; + +pub fn generate_prime() -> BigUint { + /* Generates a large prime number within the range [2^2048, 2^2049); + * that is, generates a large prime number between 2^2048 inclusive and + * 2^2049 exclusive. + */ + + // Generate the RNG, which will be sourced from the OS's secure source + // of entropy. Also, give it a sweet name. + let one: BigUint = One::one(); + let two = one.clone() + one.clone(); + let mut rngesus = match OsRng::new() { + Ok(o) => o, + Err(err) => panic!("Error initializing RNG: {}", err) + }; + + let lower_bound = pow(BigUint::from_u8(2).unwrap(), 2048); + let upper_bound = pow(BigUint::from_u8(2).unwrap(), 2049); + + let mut candidate = rngesus.gen_biguint_range(&lower_bound, + &upper_bound); + if candidate.is_even() { + candidate = candidate + one.clone(); + } + while !test_prime(&candidate, 128) { + candidate = candidate + two.clone(); + } + + candidate +} + +fn test_prime(candidate: &BigUint, limit: u8) -> bool { + let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one()); + let two = one.clone() + one.clone(); + + if *candidate < two { + false + } else if *candidate == two { + true + } else if candidate.is_even() { + false + } else { + let (s, d) = rewrite(&(candidate - one.clone())); + let mut k = 0; + + while k < limit { + let basis = thread_rng().gen_biguint_range(&two, candidate); + let mut v = modulo(&basis, &d, candidate); + + if v != one.clone() && v != (candidate - one.clone()) { + let mut i = zero.clone(); + loop { + v = modulo(&v, &two, candidate); + if v == (candidate - one.clone()) { + break + } else if v == one.clone() || i == (s.clone() - one.clone()) { + return false; + } + + i = i + one.clone(); + } + } + + k = k + 2; + } + + true + } +} + +fn rewrite(n: &BigUint) -> (BigUint, BigUint) { + let mut d = n.clone(); + let mut s: BigUint = Zero::zero(); + let one: BigUint = One::one(); + let two = one.clone() + one.clone(); + + while d.is_even() { + d = d.clone() / two.clone(); + s = s.clone() + one.clone(); + } + + (s, d) +} + +fn modulo(base: &BigUint, exponent: &BigUint, modulus: &BigUint) -> BigUint { + // Modular exponentiation function, with BigUints! + // Warning!! Ahead, thar be clones! + let (zero, one): (BigUint, BigUint) = (Zero::zero(), One::one()); + let mut result = one.clone(); + let mut b = base.clone(); + let mut e = exponent.clone(); + + while e > zero { + if (exponent & one.clone()) == one { + result = (result * b.clone()) % modulus; + } + + b = (b.clone() * b.clone()) % modulus; + e = e >> 1; + } + + result +}