1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
use ramp::{Int, RandomInt};

use rand::{OsRng, thread_rng};

static SMALL_PRIMES: [u32; 999] = [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];

/// An arbitrarily-length prime number, suitable for cryptographic purposes.
///
/// All `Prime`s are initially seeded from the `rand::OsRng` random number
/// generator, which itself uses the operating system's main source of entropy.
///
/// Primes are verified to be prime by running the following three checks
/// during initialization:
///
///     1) Dividing the initial "prime number candidate" by the first 1,000
///     prime numbers, and 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. Because the intial prime
/// number candidate is generated from the operating system's source of
/// entropy, we can be reasonably sure that the generated `Prime` is, in fact,
/// prime.
///
/// `Prime`s are built upon the `Int` type as defined in the `ramp` crate. In
/// fact, all operations that you can do with `Int`s, you can do with `Prime`s
/// as well. `Prime`s simply claim that the number you're dealing with is a
/// prime number.
custom_derive! {
    /// A cryptographically secure prime number.
    #[derive(NewtypeDebug, NewtypeDisplay, NewtypeBinary, NewtypeOctal,
        NewtypeLowerHex, NewtypeUpperHex, NewtypeAdd, NewtypeAdd(Int),
        NewtypeSub, NewtypeSub(Int), NewtypeMul, NewtypeMul(Int), NewtypeDiv,
        NewtypeDiv(Int), NewtypeRem, NewtypeRem(Int), NewtypeBitAnd,
        NewtypeBitAnd(Int), NewtypeBitOr, NewtypeBitOr(Int), NewtypeBitXor,
        NewtypeBitXor(Int)
    )]
    pub struct Prime(pub Int);
}

impl Prime {
    /// Constructs a new `Prime` with a size of `bit_length` bits.
    ///
    /// This will initialize an `OsRng` instance and call the
    /// `Prime::from_rng()` method.
    ///
    /// Note: the `bit_length` MUST be at least 512-bits.
    pub fn new(bit_length: usize) -> Prime {
        debug_assert!(bit_length >= 512);
        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 >= 512);
        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 {
            let mut counter = 0;
            let mut found_prime = true;
            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.
            // Note that Ints are stored in most-significant-bit format, so we
            // will right-shift in order to set the two most significant bits.
            candidate = &candidate | (Int::from(3) >> (bit_length - 2));

            // 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 = &candidate | 1_usize;

            // Now run through the actual primality check!
            while !is_prime(&candidate) {
                candidate += 2_usize;
                counter += 1;

                if counter > 499 {
                    found_prime = false;
                    break;
                }
            }

            if found_prime {
                break;
            }
        }

        Prime(candidate)
    }
}

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 > 0_usize {
        if &exponent & 1_usize == 1_usize {
            result = (&base * result) % modulus;
        }

        base = (&base.pow(2)) % modulus;
        exponent = &exponent >> 1;
    }

    result
}

fn rewrite(candidate: &Int) -> (Int, Int) {
    let mut d = candidate - 1_usize;
    let mut s = Int::zero();

    while &d & 1 == 1_usize {
        d = &d >> 1_usize;
        s = &s + 1_usize;
    }

    (s, d)
}

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.

    for p in SMALL_PRIMES.into_iter() {
        let prime: Int = Int::from(*p);
        let (_, r) = candidate.divmod(&prime);

        if r != 0_usize {
            continue;
        } else {
            return false;
        }
    }

    // Second, do a Fermat test on the candidate
    if !fermat(candidate) {
        return false;
    }

    // Finally, do a Miller-Rabin test
    if !miller_rabin(candidate) {
        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_usize), candidate);

    result == 1_usize
}

fn miller_rabin(candidate: &Int) -> bool {
    // Perform five iterations of the Miller-Rabin test on the candidate.
    let (s, d) = rewrite(candidate);

    for _ in 0..5 {
        let basis = thread_rng().gen_int_range(&Int::from(2), candidate);
        let mut x = mod_exp(&basis, &d, candidate);

        if x == 1_usize || x == (candidate - 1_usize) {
            continue;
        } else {
            for _ in Int::one()..s - 1_usize {
                x = mod_exp(&x, &Int::from(2), candidate);
                if x == 1_usize {
                    return false;
                } else if x == candidate - 1_usize {
                    break;
                }
            }
            return false;
        }
    }

    true
}

#[cfg(test)]
mod tests {
    use ramp::Int;
    use super::{fermat, miller_rabin};

    #[test]
    fn test_fermat_pass() {
        assert!(fermat(&Int::from(7919)));
    }

    #[test]
    #[should_panic]
    fn test_fermat_fail() {
        assert!(fermat(&Int::from(7920)));
    }

    #[test]
    fn test_miller_rabin_pass() {
        assert!(miller_rabin(&Int::from(7919)));
    }

    #[test]
    #[should_panic]
    fn test_miller_rabin_fail() {
        assert!(miller_rabin(&Int::from(7920)));
    }
}