Compare commits

...
Sign in to create a new pull request.

41 commits

Author SHA1 Message Date
Atul Bhosale
301bdac7f9 Format code using 'cargo fmt' 2020-03-29 12:55:06 -04:00
Michael Lodder
28387362bc Fixed is_prime (#11)
Signed-off-by: Michael Lodder <redmike7@gmail.com>
2019-01-25 12:34:21 -05:00
Michael Lodder
c3629c9e30 Fixed is_prime (#10)
Signed-off-by: Michael Lodder <redmike7@gmail.com>
2019-01-08 08:42:32 -05:00
Zach Dziura
9bec3d8036
Merge pull request #9 from mikelodder7/master
Update rand; ramp. Optimize is_prime and gen_safe_prime
2018-12-28 16:57:38 -05:00
Michael Lodder
c87f57141f Update rand; ramp. Optimize is_prime and gen_safe_prime
Signed-off-by: Michael Lodder <redmike7@gmail.com>
2018-12-20 13:51:00 -07:00
Zachary Dziura
280ae3877a Release v2.0.1
Update `ramp` dependency to latest version, to fix compilation errors
with latest Rust compiler.
2018-03-19 10:50:20 -04:00
Zach Dziura
da4b3b60b5 Moved tests into their appropriate files 2016-06-11 15:58:28 -04:00
Zach Dziura
ec63237e41 Implemented custom Error and Result types to be returned
Like a good library ought to be, Pumpkin now returns actual Errors, rather
than panicking.
2016-06-08 23:05:06 -04:00
Zach Dziura
b6134a6cfd Refactored source code into separate modules
Now each of the various modules (prime and safe_prime) exist within their
own modules. The prime generation logic is now found within the common
module.
2016-06-01 00:35:51 -04:00
Zach Dziura
7c6a418f3e Merge pull request #4 from tiehuis/master
Add SafePrime initial implementation
2016-05-23 09:52:17 -04:00
tiehuis
253583eb0a Add SafePrime initial implementation
This provides an interface for generating safe primes. Currently
implemented using a naive random scan.
2016-05-22 17:29:52 +12:00
Zach Dziura
bc91896510 v1.0.1
Fixed issue where the wrapped "Int" member of "Prime" was marked as
private, rather than public.
2016-05-10 23:30:18 -04:00
Zach Dziura
a60c1f63a1 V1.0
Since the last major version, a bunch of additional trait implementations
have been added, including various displays and bitwise operations. The
library should be better documented as well. I feel comfortable
stabilizing the API for future use.
2016-05-10 18:08:42 -04:00
Zach Dziura
2ef937f193 Fixing Travis CI bugs, take 4 2016-05-10 17:55:54 -04:00
Zach Dziura
c6d3086fe9 Fixing Travis CI bugs, take 3
God I hate this...
2016-05-10 17:53:12 -04:00
Zach Dziura
5651feb156 Fix Travis CI Bugs, take 2 2016-05-10 17:50:26 -04:00
Zach Dziura
94e6c4c8c6 Fix Travis Bugs
I hate setting up Travis CI...
2016-05-10 17:47:44 -04:00
Zach Dziura
ef608490ff Adding Travis CI support 2016-05-10 17:45:42 -04:00
Zach Dziura
c49b66c7e1 Add homepages entry to Cargo.toml 2016-05-10 15:16:40 -04:00
Zach Dziura
2965e9e7e7 Clean up project code and add better documentation 2016-05-10 15:07:49 -04:00
Zach Dziura
53329646ab v0.3
Increased required Prime bit-length to at least 512-bits. Also updated the
candidate checking process to increment the candidate by 2 only 500 times
before the candidate is reseeded from the OS.
2016-05-05 13:05:22 -04:00
Zach Dziura
248e2549dd Added arithmetic operations for Ints 2015-11-10 15:06:17 -05:00
Zach Dziura
56acd7a8c9 Bump version number to v0.2.1 2015-10-29 15:45:17 -04:00
Zach Dziura
01fb0959c9 Bumping ramp version 2015-10-27 14:00:11 -04:00
Zach Dziura
6cdb9a1034 Fixed formatting in README 2015-10-22 17:21:42 -04:00
Zach Dziura
82d9678a7e v0.2 2015-10-22 17:17:55 -04:00
Zach Dziura
01cccc03e1 Added another Prime generator function 2015-10-22 17:14:05 -04:00
Zach Dziura
11fdbb8c8e Merge pull request #1 from ddworken/master
println is a macro not a function
2015-10-21 21:34:57 -04:00
David Dworken
559b1de008 println is a macro not a function 2015-10-21 20:58:10 -04:00
Zach Dziura
52f871c627 v0.1.0 2015-10-20 22:07:33 -04:00
Zach Dziura
afe5b2e8cb ...Yep, more README changes 2015-10-13 00:24:59 -04:00
Zach Dziura
4d11410a41 Slight README changes 2015-10-13 00:24:09 -04:00
Zach Dziura
e46c5e580b Added README 2015-10-13 00:23:01 -04:00
Zach Dziura
0bcfeb3efe Created examples 2015-10-12 22:01:09 -04:00
Zach Dziura
81ed7f8c9a Added custom operator implementations 2015-10-08 00:49:01 -04:00
Zach Dziura
b901d7962b Added rustdoc for lib file 2015-10-06 23:12:26 -04:00
Zach Dziura
c4c7a07218 Added rustdoc for the Prime struct 2015-10-05 23:03:41 -04:00
Zach Dziura
deef6fd911 Added benchmarking 2015-10-05 08:17:53 -04:00
Zach Dziura
80049c332e Completed first pass of the primegen algorithm 2015-10-04 21:32:25 -04:00
Zach Dziura
0201205532 Completed initial primes stub 2015-09-28 00:25:30 -04:00
Zach Dziura
fdefbe453c Added stub files for Cargo 2015-09-24 14:34:12 -04:00
15 changed files with 898 additions and 28 deletions

4
.gitignore vendored
View file

@ -7,5 +7,9 @@
# Executables
*.exe
# Folders
.idea
# Generated by Cargo
/target/
Cargo.lock

18
.travis.yml Normal file
View file

@ -0,0 +1,18 @@
language: rust
rust:
- nightly
before_script:
- |
pip install 'travis-cargo<0.2' --user &&
export PATH=$HOME/.local/bin:$PATH
script:
- |
travis-cargo build &&
travis-cargo test &&
travis-cargo bench
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev

26
Cargo.toml Normal file
View file

@ -0,0 +1,26 @@
[package]
name = "pumpkin"
version = "2.0.1"
authors = ["Zach Dziura <zcdziura@gmail.com>"]
description = "A cryptographically secure prime number generator"
repository = "https://github.com/zcdziura/pumpkin"
homepage = "https://zcdziura.github.io/pumpkin/pumpkin"
keywords = ["prime", "number", "cryptography", "generator"]
license = "Unlicense/MIT"
readme = "README.md"
[dependencies]
clippy = {version = "0.0.*", optional = true}
custom_derive = "0.1"
newtype_derive = "0.1"
ramp = "0.5"
rand = "0.6"
[lib]
name = "pumpkin"
path = "src/lib.rs"
doctest = false
[features]
dev = ["clippy"]
unstable = []

28
LICENSE
View file

@ -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.

25
LICENSE.md Normal file
View file

@ -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.

120
README.md Normal file
View file

@ -0,0 +1,120 @@
# Pumpkin
A random number generator for generating large prime numbers, suitable for cryptography.
## What's up with the name?
Since I began writing this library around Halloween of 2015, I wanted to choose
a name that was vaguely related to the holiday. Because "pumpkin" and "prime"
both begin with the letter 'p', I decided to use that.
## Purpose
`pumpkin` is a cryptographically-secure, random number generator, useful for
generating large prime numbers (at least 512-bits long). On the back-end,
`pumpkin` uses the wonderful [ramp](https://crates.io/crates/ramp) library for
storing the large numbers. `pumpkin` generates primes very quickly. 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 = "2.0.*"
```
Note that `pumpkin` requires the `nightly` Rust compiler.
## Example
```rust
extern crate pumpkin;
use pumpkin::Prime;
fn main() {
let p = Prime::new(2048); // Generate a new 2048-bit prime number
let q = Prime::new(2048);
let e = p * q;
println!("{}", e);
/*
* 75222035638256552797269351238215022250546763213674706... Some massive
* 4096-bit number.
*/
}
```
You can also initialize your own `OsRng` and generate `Prime`s from that.
```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
`Primes` are generated in much the same way as primes generated by `GnuPG`:
1) Create a large candidate number of a given bit-length. All `Primes` must
be at least 512-bits long.
2) Divide the candidate number by the first 1,000 prime numbers.
3) Test the candidate number with [Fermat's Little
Theorem](https://www.wikiwand.com/en/Fermat's_little_theorem).
4) Finally, run five iterations of the [Miller-Rabin Primality
Test](https://www.wikiwand.com/en/Miller%E2%80%93Rabin_primality_test).
`Primes` are seeded by `rand::OsRng`, which receives its entropy via the
operating system's entropy source (such as `/dev/urandom`). Thus, because we
can be confident that the generated candidate number is truly random (or as
close to truly random as the user can hope), we don't need to do more than five
iterations of the Miller-Rabin test to ensure primality.
`Primes` are simple "newtype" structs; that is, it is a tuple-like struct
surrounding `ramp's` `Int` type. `Primes` have all of the basic algebraic and logical
operators implemented, thus allowing you to do any operation that you would
require.
## Contributing
`pumpkin` is dual-licenced under the MIT and Unlicense. Should you wish to
contribute updates to the project, please consider signing the included `WAVER`
file with your cryptographic digital signature (as allowed by your country's
laws). Doing so will release your changes back into the public domain to be used
freely by all. I did so with this project, and it would mean a lot if you did
too!
To sign the `WAIVER`, execute the following commands:
```
$ gpg -sba -u $YOUR_SIGNING_KEY WAIVER
$ cat WAIVER.asc >> WAIVER.sigs && rm WAIVER.asc
```

27
UNLICENSE.md Normal file
View file

@ -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 &lt;<http://unlicense.org/>&gt;

5
WAIVER Normal file
View file

@ -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.

19
WAIVER.sigs Normal file
View file

@ -0,0 +1,19 @@
@zcdziura's signature
keyserver: sks-keyservers.net
fingerprint: 0xC936A812AF607321
-----BEGIN PGP SIGNATURE-----
iQIcBAABCgAGBQJXK3Z2AAoJENNfKjTk1jvtfTQP/0PnIWai7tpg+8YfTf+FTBjI
hH8X1KquM6Kt58m+9bSpJAyaA42MYRmPd0UlyKq0UfR9EV9Dyme72cQCUQlNEkuh
tXp1mqQ9wSTy7SGy43vGje2F76WPjGYR9zwrS/+EN771LbQEaYvsI75uIc5ynWnN
op6w9XA9jLDdLPiXb+lli/7uAiSOZgLBqj6M8nTs6ii94kkHgEgZyHpyYe8kJNRq
SUbldrJmH//vKbS7HSvgkPJ/ok2c04ZmZ7B3sa0997r36ubwM/SscqWTvZkGy3uj
PCJh4m+gcHLiNasWucSL/y2oym7Px7DzmCibvT2pA0wa7zcjhIRc5ksnSDXfYafe
XrTeuy/6cP5Trep9jzDf4wnAWhRzLZzy0LGHGYsSd5//6n3qFn2XFNyy769qYLu6
8anCbpk40XNDLyEDlHB+lFCCe0KG/K5sg49CoxTsdLoiwyKqGpC7cjEQ15RoFtRQ
JEvVJKs36fcAYalkfa4+OWt5TeoTAm/kg1erz6SwnNiL9n4MQ+0hLjm0WtpEpJqG
V2XYi7tSIpfVFi+lvtxfoOGL+9nZpd6s6JarhdBPFFFang70I9wpXwVZDbSML89q
KYnx3XVTxBhV6sumlJQ40wBGAisXLfJ4VpS1uj5JIx01d36Lgv6z80i6CiHTnIvz
HFbm9XcS6pooPZOOxTrp
=LwYG
-----END PGP SIGNATURE-----

11
examples/multiply.rs Normal file
View file

@ -0,0 +1,11 @@
extern crate pumpkin;
use pumpkin::prime;
fn main() {
let p = prime::new(1024).unwrap();
let q = prime::new(1024).unwrap();
let n = p * q;
println!("The product of 'p' and 'q' is: {}", n);
}

333
src/common.rs Normal file
View file

@ -0,0 +1,333 @@
use ramp::traits::Integer;
use ramp::{Int, RandomInt};
use rand::rngs::OsRng;
use rand::thread_rng;
use error::{Error, Result};
pub fn two() -> Int {
Int::from(2_usize)
}
pub fn three() -> Int {
Int::from(3_usize)
}
static SMALL_PRIMES: [u32; 2047] = [
3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307,
311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547,
557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929,
937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039,
1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153,
1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,
1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409,
1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499,
1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613,
1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741,
1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873,
1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999,
2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113,
2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251,
2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371,
2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477,
2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647,
2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731,
2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857,
2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001,
3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163,
3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299,
3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407,
3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659,
3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793,
3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919,
3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051,
4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201,
4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327,
4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463,
4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603,
4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733,
4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903,
4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009,
5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153,
5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303,
5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441,
5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569,
5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701,
5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843,
5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987,
6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131,
6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269,
6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373,
6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553,
6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691,
6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829,
6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967,
6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109,
7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247,
7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451,
7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559,
7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687,
7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841,
7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993,
8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147,
8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287,
8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431,
8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599,
8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719,
8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849,
8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007,
9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157,
9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293,
9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431,
9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551,
9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721,
9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851,
9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973, 10007,
10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 10103, 10111, 10133,
10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333, 10337,
10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, 10477,
10487, 10499, 10501, 10513, 10529, 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613,
10627, 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729,
10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 10861,
10867, 10883, 10889, 10891, 10903, 10909, 10937, 10939, 10949, 10957, 10973, 10979, 10987,
10993, 11003, 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117,
11119, 11131, 11149, 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, 11369,
11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491,
11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621, 11633,
11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 11743, 11777, 11779, 11783,
11789, 11801, 11807, 11813, 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 11897,
11903, 11909, 11923, 11927, 11933, 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987,
12007, 12011, 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 12107, 12109, 12113,
12119, 12143, 12149, 12157, 12161, 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373, 12377,
12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 12479, 12487,
12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541, 12547, 12553, 12569, 12577, 12583,
12589, 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697,
12703, 12713, 12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 12823,
12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917, 12919, 12923, 12941, 12953,
12959, 12967, 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, 13037, 13043, 13049,
13063, 13093, 13099, 13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291, 13297, 13309, 13313,
13327, 13331, 13337, 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 13441, 13451,
13457, 13463, 13469, 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591,
13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691, 13693, 13697,
13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, 13807,
13829, 13831, 13841, 13859, 13873, 13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921,
13931, 13933, 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057, 14071,
14081, 14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 14327, 14341, 14347, 14369, 14387,
14389, 14401, 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489,
14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563, 14591, 14593, 14621,
14627, 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 14713, 14717, 14723, 14731,
14737, 14741, 14747, 14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827,
14831, 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929, 14939, 14947,
14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 15077, 15083, 15091,
15101, 15107, 15121, 15131, 15137, 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307, 15313,
15319, 15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 15413, 15427,
15439, 15443, 15451, 15461, 15467, 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559,
15569, 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667,
15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 15787,
15791, 15797, 15803, 15809, 15817, 15823, 15859, 15877, 15881, 15887, 15889, 15901, 15907,
15913, 15919, 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061,
16063, 16067, 16069, 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 16253, 16267, 16273, 16301, 16319,
16333, 16339, 16349, 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, 16433, 16447,
16451, 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567, 16573,
16603, 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 16673, 16691, 16693, 16699,
16703, 16729, 16741, 16747, 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871,
16879, 16883, 16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981,
16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 17077, 17093, 17099,
17107, 17117, 17123, 17137, 17159, 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377,
17383, 17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 17471, 17477,
17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551, 17569, 17573, 17579, 17581, 17597,
17599, 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737,
17747, 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
];
/// Constructs a new prime number with the size of `bit_length` bits, sourced
/// from an already-initialized `OsRng`.
pub fn gen_prime(bit_length: usize, rngesus: &mut OsRng) -> Result {
if bit_length < 512 {
Err(Error::BitLength(bit_length))
} else {
let mut candidate: Int;
// In order to remove as much bias from the system as possible, test
// 500 potential candidates at a time before re-seeding the candidate
// with a new random number.
loop {
candidate = rngesus.gen_uint(bit_length);
// We first want to make sure that the candidate is in the appropriate
// size range before continuing. This can easily be done by setting the
// two most significant bits of the candidate number to 1.
candidate.set_bit(1, true);
candidate.set_bit(2, true);
// Next, flip the least significant bit to 1, to make sure the candidate
// is odd (no sense in testing primality on an even number, after all).
candidate.set_bit(bit_length as u32, true);
if is_prime(&candidate) {
return Ok(candidate);
}
}
}
}
/// Runs the following three tests on a given `candidate` to determine
/// primality:
///
/// 1. Divide the candidate by the first 2048 small prime numbers.
/// 2. Run Fermat's Little Theorem against the candidate.
/// 3. Run fifteen rounds of the Miller-Rabin test on the candidate.
///
/// Should the candidate number pass all three tests, then you can be
/// reasonably sure that the candidate is prime.
pub fn is_prime(candidate: &Int) -> bool {
// First, iterate through the array of small primes and divide the
// candidate. If the candidate divides any of them, then we know the number
// is a multiple of that prime; that is, the candidate is composite.
if *candidate == Int::from(2) {
return true;
}
if !candidate.is_odd() {
return false;
}
for p in SMALL_PRIMES.into_iter() {
let prime: Int = Int::from(*p);
let (_, r) = candidate.divmod(&prime);
if r == Int::zero() {
return *candidate == prime;
}
}
// Second, do a Fermat test on the candidate
if !fermat(candidate) {
return false;
}
// Finally, do a Miller-Rabin test
// See https://eprint.iacr.org/2018/749.pdf for good choices on appropriate number of tests
if !miller_rabin(candidate, 15) {
return false;
}
true
}
fn fermat(candidate: &Int) -> bool {
// Perform Fermat's little theorem on the candidate to determine probable
// primality.
let random = thread_rng().gen_int_range(&Int::one(), candidate);
let result = mod_exp(&random, &(candidate - 1), candidate);
result == Int::one()
}
fn mod_exp(base: &Int, exponent: &Int, modulus: &Int) -> Int {
let mut result = Int::one();
let mut base = base.clone();
let mut exponent = exponent.clone();
while exponent > Int::zero() {
if exponent.trailing_zeros() == 0 {
result = (&base * result) % modulus;
}
base = base.pow_mod(&two(), modulus);
exponent >>= 1;
}
result
}
fn miller_rabin(candidate: &Int, limit: usize) -> bool {
// Perform the Miller-Rabin test on the candidate, 'limit' times.
let (s, d) = rewrite(candidate);
for _ in 0..limit {
let basis = thread_rng().gen_int_range(&two(), candidate);
let mut x = mod_exp(&basis, &d, candidate);
if x == Int::one() || x == (candidate - 1) {
continue;
} else {
for _ in Int::one()..s - 1 {
x = mod_exp(&x, &two(), candidate);
if x == Int::one() {
return false;
} else if x == candidate - 1 {
break;
}
}
return false;
}
}
true
}
fn rewrite(candidate: &Int) -> (Int, Int) {
let mut d = candidate - 1_usize;
let mut s = Int::zero();
while d.trailing_zeros() == 0 {
//
d = &d >> 1;
s = &s + 1;
}
(s, d)
}
#[cfg(test)]
mod tests {
extern crate ramp;
use super::{fermat, miller_rabin};
use ramp::Int;
#[test]
fn test_fermat_prime() {
let candidate = Int::from(65537);
let result = fermat(&candidate);
assert_eq!(result, true);
}
#[test]
fn test_fermat_not_prime() {
let candidate = Int::from(65535);
let result = fermat(&candidate);
assert_eq!(result, false);
}
#[test]
fn test_miller_rabin_prime() {
let candidate = Int::from(65537);
let result = miller_rabin(&candidate, 64);
assert_eq!(result, true);
}
#[test]
fn test_miller_rabin_not_prime() {
let candidate = Int::from(65535);
let result = miller_rabin(&candidate, 64);
assert_eq!(result, false);
}
}

49
src/error.rs Normal file
View file

@ -0,0 +1,49 @@
//! More coming soon
use ramp::Int;
use rand;
use std::{error, fmt, result};
/// Goddamn docs
pub type Result = result::Result<Int, Error>;
/// More goddamn docs
#[derive(Debug)]
pub enum Error {
/// Docs for a variant, are you kidding me??
OsRngInitialization(rand::Error),
/// Jesus fuck, people
BitLength(usize),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::OsRngInitialization(ref err) => {
write!(f, "Error initializing the random number generator: {}", err)
}
Error::BitLength(length) => write!(
f,
"The given bit length is too small; must be at least 512: {}",
length
),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::OsRngInitialization(ref err) => err.description(),
Error::BitLength(_) => "The given bit length was less than 512",
}
}
}
impl From<rand::Error> for Error {
fn from(err: rand::Error) -> Error {
Error::OsRngInitialization(err)
}
}

99
src/lib.rs Normal file
View file

@ -0,0 +1,99 @@
#![feature(test)]
#![deny(
missing_docs,
missing_debug_implementations,
missing_copy_implementations,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unused_import_braces,
unused_qualifications
)]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]
//! A crate for generating large, cryptographically secure prime numbers.
//! These numbers are seeded from the operating system's main source of
//! entropy, ensuring proper randomness.
//!
//! Numbers are verified to be prime by running the following three tests
//! during initialization:
//!
//! 1. Dividing the initial prime number candidate by the first 1,000 prime
//! numbers, checking the remainder. Should the remainder ever be zero, then
//! add two to the candidate and try again.
//!
//! 2. Run a Fermat Primality Test on the candidate. If it doesn't pass, add
//! two to the candidate and goto Step 1.
//!
//! 3. Finally, complete five rounds of the Miller-Rabin Primality Test.
//! Should any of the tests pass, add two to the candidate and goto Step 1.
//!
//! The preceding steps mirror those used by GnuPG, a leading PGP implementation
//! used by thousands of users all across the world.
//!
//! The prime numbers must be AT LEAST 512-bits long. Attempting to generate a
//! number less than 512-bits long will cause a panic.
//!
//! ## Example
//!
//! ```
//! extern crate pumpkin;
//!
//! use pumpkin::prime;
//!
//! fn main() {
//! // Generate 2, 2048-bit primes
//! let p = prime::new(2048);
//! let q = prime::new(2048);
//!
//! let n = p * q;
//! println!("{}", n); // Some 4096-bit composite number
//! }
//! ```
#[allow(unused_imports)]
#[macro_use]
extern crate custom_derive;
#[allow(unused_imports)]
#[macro_use]
extern crate newtype_derive;
extern crate ramp;
extern crate rand;
extern crate test;
mod common;
pub mod error;
pub mod prime;
pub mod safe_prime;
#[cfg(test)]
mod tests {
use super::{prime, safe_prime};
use rand::rngs::OsRng;
use test::Bencher;
#[bench]
fn bench_generate_512_bit_prime(b: &mut Bencher) {
let mut rngesus = OsRng::new().unwrap();
b.iter(|| prime::from_rng(512, &mut rngesus));
}
#[bench]
fn bench_generate_1024_bit_prime(b: &mut Bencher) {
let mut rngesus = OsRng::new().unwrap();
b.iter(|| prime::from_rng(1024, &mut rngesus));
}
#[bench]
fn bench_generate_2048_bit_prime(b: &mut Bencher) {
let mut rngesus = OsRng::new().unwrap();
b.iter(|| prime::from_rng(2048, &mut rngesus));
}
#[bench]
fn bench_generate_512_bit_safe_prime(b: &mut Bencher) {
let mut rngesus = OsRng::new().unwrap();
b.iter(|| safe_prime::from_rng(512, &mut rngesus));
}
}

50
src/prime.rs Normal file
View file

@ -0,0 +1,50 @@
//! Generates cryptographically secure prime numbers.
use rand::rngs::OsRng;
pub use common::gen_prime as from_rng;
use error::{Error, Result};
/// Constructs a new prime number with a size of `bit_length` bits.
///
/// This will initialize an `OsRng` instance and call the
/// `from_rng()` function.
///
/// 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 = OsRng::new()?;
Ok(from_rng(bit_length, &mut rngesus)?)
}
}
#[cfg(test)]
mod tests {
use super::new;
#[test]
fn test_prime_bit_length_too_small() {
let p = new(511);
assert_eq!(
false,
match p {
Ok(_) => true,
Err(_) => false,
}
);
}
#[test]
fn test_prime() {
let p = new(512);
assert_eq!(
true,
match p {
Ok(_) => true,
Err(_) => false,
}
);
}
}

112
src/safe_prime.rs Normal file
View file

@ -0,0 +1,112 @@
//! Generates [safe prime numbers](https://www.wikiwand.com/en/Sophie_Germain_prime).
use ramp::Int;
use rand::rngs::OsRng;
pub use common::{gen_prime, is_prime};
use common::{three, two};
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 = OsRng::new()?;
Ok(from_rng(bit_length, &mut rngesus)?)
}
}
/// Checks if number is a safe prime
pub fn is_safe_prime(candidate: &Int) -> bool {
// according to https://eprint.iacr.org/2003/186.pdf
// a safe prime is congruent to 2 mod 3
if (candidate % three()) == two() {
if is_prime(&candidate) {
// a safe prime satisfies (p-1)/2 is prime. Since a
// prime is odd, We just need to divide by 2
let candidate_p = candidate >> 1;
return is_prime(&candidate_p);
}
}
false
}
/// 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 = gen_prime(bit_length, &mut rngesus)?;
if is_safe_prime(&candidate) {
break;
}
candidate <<= 1;
candidate += 1;
if is_prime(&candidate) {
break;
}
}
Ok(candidate)
}
}
#[cfg(test)]
mod tests {
use super::{is_safe_prime, new};
use ramp::Int;
#[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,
}
);
}
#[test]
fn test_is_safe_prime() {
//Numbers pulled from https://github.com/mikelodder7/cunningham_chain/blob/master/findings.md
//p0 is sophie german prime
let p0 = Int::from_str_radix("37313426856874901938110133384605074194791927500210707276948918975046371522830901596065044944558427864187196889881993164303255749681644627614963632713725183364319410825898054225147061624559894980555489070322738683900143562848200257354774040241218537613789091499134051387344396560066242901217378861764936185029", 10).unwrap();
assert!(!is_safe_prime(&p0));
let p1 = Int::from_str_radix("74626853713749803876220266769210148389583855000421414553897837950092743045661803192130089889116855728374393779763986328606511499363289255229927265427450366728638821651796108450294123249119789961110978140645477367800287125696400514709548080482437075227578182998268102774688793120132485802434757723529872370059", 10).unwrap();
assert!(is_safe_prime(&p1));
let p2 = Int::from_str_radix("149253707427499607752440533538420296779167710000842829107795675900185486091323606384260179778233711456748787559527972657213022998726578510459854530854900733457277643303592216900588246498239579922221956281290954735600574251392801029419096160964874150455156365996536205549377586240264971604869515447059744740119", 10).unwrap();
assert!(is_safe_prime(&p2));
let p3 = Int::from_str_radix("298507414854999215504881067076840593558335420001685658215591351800370972182647212768520359556467422913497575119055945314426045997453157020919709061709801466914555286607184433801176492996479159844443912562581909471201148502785602058838192321929748300910312731993072411098755172480529943209739030894119489480239", 10).unwrap();
assert!(is_safe_prime(&p3));
let p4 = Int::from_str_radix("4806876214089177439121678559764069543282270755154137981051366776821330958611719328037311759924923156830623290278296826263863902327008664143707117531049168010908663795201825132050017581985031718536424081509084930569115857201636971728388275433540277562846153879803474020036767852693656753257597801227199822164846876100177774044259379232968071371318658371230787073384750022830829873718254139779006439569882904712552834431199870749249168775012460891012776977366721903", 10).unwrap();
assert!(is_safe_prime(&p4));
}
}