File Coverage

blib/lib/Math/Prime/Util/RandomPrimes.pm
Criterion Covered Total %
statement 294 369 79.6
branch 121 236 51.2
condition 132 197 67.0
subroutine 28 32 87.5
pod 10 10 100.0
total 585 844 69.3


line stmt bran cond sub pod time code
1             package Math::Prime::Util::RandomPrimes;
2 4     4   32 use strict;
  4         9  
  4         252  
3 4     4   25 use warnings;
  4         8  
  4         292  
4 4     4   27 use Carp qw/carp croak confess/;
  4         9  
  4         590  
5 4         39 use Math::Prime::Util qw/ prime_get_config
6             verify_prime
7             is_provable_prime_with_cert
8             primorial prime_count nth_prime
9             is_prob_prime is_pseudoprime is_strong_pseudoprime
10             is_extra_strong_lucas_pseudoprime
11             next_prime prev_prime
12             urandomb urandomm random_bytes
13             addint subint add1int sub1int logint modint cmpint
14             mulint divint powint modint lshiftint rshiftint
15             sqrtint cdivint
16             powmod invmod
17             vecsum vecprod gcd is_odd fromdigits
18 4     4   30 /;
  4         10  
19              
20             BEGIN {
21 4     4   21 $Math::Prime::Util::RandomPrimes::AUTHORITY = 'cpan:DANAJ';
22 4         370 $Math::Prime::Util::RandomPrimes::VERSION = '0.74';
23             }
24              
25             BEGIN {
26             # TODO: remove this when everything uses tobigint
27 4 100   4   25 do { require Math::BigInt; Math::BigInt->import(try=>"GMP,GMPz,LTM,Pari"); }
  1         1792  
  1         66362  
28             unless defined $Math::BigInt::VERSION;
29              
30 4     4   34 use constant OLD_PERL_VERSION=> $] < 5.008;
  4         7  
  4         640  
31 4     4   33 use constant MPU_MAXBITS => (~0 == 4294967295) ? 32 : 64;
  4         9  
  4         277  
32 4     4   52 use constant MPU_64BIT => MPU_MAXBITS == 64;
  4         11  
  4         268  
33 4     4   27 use constant MPU_32BIT => MPU_MAXBITS == 32;
  4         10  
  4         328  
34 4     4   49 use constant MPU_MAXPARAM => MPU_32BIT ? 4294967295 : 18446744073709551615;
  4         27  
  4         304  
35 4     4   25 use constant MPU_MAXDIGITS => MPU_32BIT ? 10 : 20;
  4         21  
  4         320  
36 4     4   58 use constant MPU_USE_XS => prime_get_config->{'xs'};
  4         8  
  4         20  
37 4     4   25 use constant MPU_USE_GMP => prime_get_config->{'gmp'};
  4         29  
  4         24  
38              
39 4         43339 *_bigint_to_int = \&Math::Prime::Util::_bigint_to_int;
40 4         11 *tobigint = \&Math::Prime::Util::_to_bigint;
41 4         29566 *maybetobigint = \&Math::Prime::Util::_to_bigint_if_needed;
42             }
43              
44             ################################################################################
45              
46             # These are much faster than straightforward trial division when n is big.
47             # You'll want to first do a test up to and including 23.
48             my @_big_gcd;
49             my $_big_gcd_top = 20046;
50             my $_big_gcd_use = -1;
51             sub _make_big_gcds {
52 3 50   3   11 return if $_big_gcd_use >= 0;
53 3 50       14 if (prime_get_config->{'gmp'}) {
54 0         0 $_big_gcd_use = 0;
55 0         0 return;
56             }
57 3         15 my $biclass = prime_get_config()->{'bigintclass'};
58 3 50 33     46 if (defined $biclass && $biclass =~ /^Math::GMP/) {
    50          
59 0         0 $_big_gcd_use = 1;
60             } elsif (Math::BigInt->config()->{lib} !~ /^Math::BigInt::(GMP|Pari)/) {
61 3         492 $_big_gcd_use = 0;
62 3         6 return;
63             }
64 0         0 $_big_gcd_use = 1;
65 0         0 my($p0,$p1,$p2,$p3) = map { primorial($_) }
  0         0  
66             (520,2052,6028,$_big_gcd_top);
67 0         0 $_big_gcd[0] = divint($p0,223092870);
68 0         0 $_big_gcd[1] = divint($p1,$p0);
69 0         0 $_big_gcd[2] = divint($p2,$p1);
70 0         0 $_big_gcd[3] = divint($p3,$p2);
71             }
72              
73             ################################################################################
74              
75              
76             ################################################################################
77              
78              
79              
80             # For random primes, there are two good papers that should be examined:
81             #
82             # "Fast Generation of Prime Numbers and Secure Public-Key
83             # Cryptographic Parameters" by Ueli M. Maurer, 1995
84             # http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.26.2151
85             # related discussions:
86             # http://www.daimi.au.dk/~ivan/provableprimesproject.pdf
87             # Handbook of Applied Cryptography by Menezes, et al.
88             #
89             # "Close to Uniform Prime Number Generation With Fewer Random Bits"
90             # by Pierre-Alain Fouque and Mehdi Tibouchi, 2011
91             # http://eprint.iacr.org/2011/481
92             #
93             # Some things to note:
94             #
95             # 1) Joye and Paillier have patents on their methods. Never use them.
96             #
97             # 2) The easy method of next_prime(random number), known as PRIMEINC, is
98             # fast but gives a terrible distribution. It has a positive bias and
99             # most importantly the probability for a prime is proportional to its
100             # gap, meaning some numbers in the range will be thousands of times
101             # more likely than others). On the contrary however, nobody has a way
102             # to exploit this, and it's not-uncommon to see used.
103             #
104             # We use:
105             # TRIVIAL range within native integer size (2^32 or 2^64)
106             # FTA1 random_nbit_prime with 65+ bits
107             # INVA1 other ranges with 65+ bit range
108             # where
109             # TRIVIAL = monte-carlo method or equivalent, perfect uniformity.
110             # FTA1 = Fouque/Tibouchi A1, very close to uniform
111             # INVA1 = inverted FTA1, less uniform but works with arbitrary ranges
112             #
113             # The random_maurer_prime function uses Maurer's FastPrime algorithm.
114             #
115             # If Math::Prime::Util::GMP is installed, these functions will be many times
116             # faster than other methods (e.g. Math::Pari monte-carlo or Crypt::Primes).
117             #
118             # Timings on Macbook.
119             # The "with GMP" numbers use Math::Prime::Util::GMP 0.44.
120             # The "no GMP" numbers are with no Math::BigInt backend, so very slow in comparison.
121             # If another backend was used (GMP, Pari, LTM) it would be more comparable.
122             #
123             # random_nbit_prime random_maurer_prime
124             # n-bits no GMP w/ MPU::GMP no GMP w/ MPU::GMP
125             # ---------- -------- ----------- -------- -----------
126             # 24-bit 1uS same same same
127             # 64-bit 5uS same same same
128             # 128-bit 0.12s 70uS 0.29s 166uS
129             # 256-bit 0.66s 379uS 1.82s 800uS
130             # 512-bit 7.8s 0.0022s 16.2s 0.0044s
131             # 1024-bit ---- 0.019s ---- 0.037s
132             # 2048-bit ---- 0.23s ---- 0.35s
133             # 4096-bit ---- 2.4s ---- 5.2s
134             #
135             # Random timings for 10M calls on i4770K:
136             # 0.39 Math::Random::MTwist 0.13
137             # 0.41 ntheory <==== us
138             # 0.89 system rand
139             # 1.76 Math::Random::MT::Auto
140             # 5.35 Bytes::Random::Secure OO w/ISAAC::XS
141             # 7.43 Math::Random::Secure w/ISAAC::XS
142             # 12.40 Math::Random::Secure
143             # 12.78 Bytes::Random::Secure OO
144             # 13.86 Bytes::Random::Secure function w/ISAAC::XS
145             # 21.95 Bytes::Random::Secure function
146             # 822.1 Crypt::Random
147             #
148             # time perl -E 'use Math::Random::MTwist "irand32"; irand32() for 1..10000000;'
149             # time perl -E 'sub irand {int(rand(4294967296));} irand() for 1..10000000;'
150             # time perl -E 'use Math::Random::MT::Auto; sub irand { Math::Random::MT::Auto::irand() & 0xFFFFFFFF } irand() for 1..10000000;'
151             # time perl -E 'use Math::Random::Secure qw/irand/; irand() for 1..10000000;'
152             # time perl -E 'use Bytes::Random::Secure qw/random_bytes/; sub irand {return unpack("L",random_bytes(4));} irand() for 1..10000000;'
153             # time perl -E 'use Bytes::Random::Secure; my $rng = Bytes::Random::Secure->new(); sub irand {return $rng->irand;} irand() for 1..10000000;'
154             # time perl -E 'use Crypt::Random qw/makerandom/; sub irand {makerandom(Size=>32, Uniform=>1, Strength=>0)} irand() for 1..100_000;'
155             # > haveged daemon running to stop /dev/random blocking
156             # > Both BRS and CR have more features that this isn't measuring.
157             #
158             # To verify distribution:
159             # perl -Iblib/lib -Iblib/arch -MMath::Prime::Util=:all -E 'my %freq; $n=1000000; $freq{random_nbit_prime(6)}++ for (1..$n); printf("%4d %6.3f%%\n", $_, 100.0*$freq{$_}/$n) for sort {$a<=>$b} keys %freq;'
160             # perl -Iblib/lib -Iblib/arch -MMath::Prime::Util=:all -E 'my %freq; $n=1000000; $freq{random_prime(1260437,1260733)}++ for (1..$n); printf("%4d %6.3f%%\n", $_, 100.0*$freq{$_}/$n) for sort {$a<=>$b} keys %freq;'
161              
162             # Sub to call with low and high already primes and verified range.
163             my $_random_prime = sub {
164             my($low,$high) = @_;
165             my $prime;
166              
167             #{ my $bsize = 100; my @bins; my $counts = 10000000;
168             # for my $c (1..$counts) { $bins[ $_IRANDF->($bsize-1) ]++; }
169             # for my $b (0..$bsize) {printf("%4d %8.5f%%\n", $b, $bins[$b]/$counts);} }
170              
171             # low and high are both odds, and low < high.
172              
173             # This is fast for small values, low memory, perfectly uniform, and
174             # consumes the minimum amount of randomness needed. But it isn't feasible
175             # with large values. Also note that low must be a prime.
176             if ($high <= 262144 && MPU_USE_XS) {
177             my $li = prime_count(2, $low);
178             my $irange = prime_count($low, $high);
179             my $rand = urandomm($irange);
180             return nth_prime($li + $rand);
181             }
182              
183             $low-- if $low == 2; # Low of 2 becomes 1 for our program.
184             $low = tobigint($low) if ref($high);
185             confess "Invalid _random_prime parameters: $low, $high" if ($low % 2) == 0 || ($high % 2) == 0;
186              
187             # We're going to look at the odd numbers only.
188             my $oddrange = (($high - $low) >> 1) + 1;
189              
190             croak "Large random primes not supported on old Perl"
191             if OLD_PERL_VERSION && MPU_64BIT && $oddrange > 4294967295;
192              
193             # If $low is large (e.g. >10 digits) and $range is small (say ~10k), it
194             # would be fastest to call primes in the range and randomly pick one. I'm
195             # not implementing it now because it seems like a rare case.
196              
197             # If the range is reasonably small, generate using simple Monte Carlo
198             # method (aka the 'trivial' method). Completely uniform.
199             if ($oddrange < MPU_MAXPARAM) {
200             my $loop_limit = 2000 * 1000; # To protect against broken rand
201             if ($low > 11) {
202             while ($loop_limit-- > 0) {
203             $prime = $low + 2 * urandomm($oddrange);
204             next if !($prime % 3) || !($prime % 5) || !($prime % 7) || !($prime % 11);
205             return $prime if is_prob_prime($prime);
206             }
207             } else {
208             while ($loop_limit-- > 0) {
209             $prime = $low + 2 * urandomm($oddrange);
210             next if $prime > 11 && (!($prime % 3) || !($prime % 5) || !($prime % 7) || !($prime % 11));
211             return 2 if $prime == 1; # Remember the special case for 2.
212             return $prime if is_prob_prime($prime);
213             }
214             }
215             croak "Random function broken?";
216             }
217              
218             # We have an ocean of range, and a teaspoon to hold randomness.
219              
220             # Since we have an arbitrary range and not a power of two, I don't see how
221             # Fouque's algorithm A1 could be used (where we generate lower bits and
222             # generate random sets of upper). Similarly trying to simply generate
223             # upper bits is full of ways to trip up and get non-uniform results.
224             #
225             # What I'm doing here is:
226             #
227             # 1) divide the range into semi-evenly sized partitions, where each part
228             # is as close to $rand_max_val as we can.
229             # 2) randomly select one of the partitions.
230             # 3) iterate choosing random values within the partition.
231             #
232             # The downside is that we're skewing a _lot_ farther from uniformity than
233             # we'd like. Imagine we started at 0 with 1e18 partitions of size 100k
234             # each.
235             # Probability of '5' being returned =
236             # 1.04e-22 = 1e-18 (chose first partition) * 1/9592 (chose '5')
237             # Probability of '100003' being returned =
238             # 1.19e-22 = 1e-18 (chose second partition) * 1/8392 (chose '100003')
239             # Probability of '99999999999999999999977' being returned =
240             # 5.20e-22 = 1e-18 (chose last partition) * 1/1922 (chose '99...77')
241             # So the primes in the last partition will show up 5x more often.
242             # The partitions are selected uniformly, and the primes within are selected
243             # uniformly, but the number of primes in each bucket is _not_ uniform.
244             # Their individual probability of being selected is the probability of the
245             # partition (uniform) times the probability of being selected inside the
246             # partition (uniform with respect to all other primes in the same
247             # partition, but each partition is different and skewed).
248             #
249             # Partitions are typically much larger than 100k, but with a huge range
250             # we still see this (e.g. ~3x from 0-10^30, ~10x from 0-10^100).
251             #
252             # When selecting n-bit or n-digit primes, this effect is MUCH smaller, as
253             # the skew becomes approx lg(2^n) / lg(2^(n-1)) which is pretty close to 1.
254             #
255             #
256             # Another idea I'd like to try sometime is:
257             # pclo = prime_count_lower(low);
258             # pchi = prime_count_upper(high);
259             # do {
260             # $nth = random selection between pclo and pchi
261             # $prguess = nth_prime_approx($nth);
262             # } while ($prguess >= low) && ($prguess <= high);
263             # monte carlo select a prime in $prguess-2**24 to $prguess+2**24
264             # which accounts for the prime distribution.
265              
266             my($binsize, $nparts);
267             my $rand_part_size = 1 << (MPU_64BIT ? 32 : 31);
268             if (ref($oddrange)) {
269             my $nbins = cdivint($oddrange, $rand_part_size);
270             $binsize = cdivint($oddrange, $nbins);
271             $nparts = divint($oddrange, $binsize);
272             $low = tobigint($low) unless ref($low);
273             } else {
274             my $nbins = int($oddrange / $rand_part_size);
275             $nbins++ if $nbins * $rand_part_size != $oddrange;
276             $binsize = int($oddrange / $nbins);
277             $binsize++ if $binsize * $nbins != $oddrange;
278             $nparts = int($oddrange/$binsize);
279             }
280             $nparts-- if ($nparts * $binsize) == $oddrange;
281              
282             my $rpart = urandomm($nparts+1);
283              
284             my $primelow = addint($low,vecprod(2,$binsize,$rpart));
285             my $partsize = ($rpart < $nparts) ? $binsize
286             : $oddrange - ($nparts * $binsize);
287             $partsize = _bigint_to_int($partsize) if ref($partsize);
288             #warn "range $oddrange = $nparts * $binsize + ", $oddrange - ($nparts * $binsize), "\n";
289             #warn " chose part $rpart size $partsize\n";
290             #warn " primelow is $low + 2 * $binsize * $rpart = $primelow\n";
291             #die "Result could be too large" if ($primelow + 2*($partsize-1)) > $high;
292              
293             # Generate random numbers in the interval until one is prime.
294             my $loop_limit = 2000 * 1000; # To protect against broken rand
295              
296             # Simply things for non-bigints.
297             if (!ref($low)) {
298             while ($loop_limit-- > 0) {
299             my $rand = urandomm($partsize);
300             $prime = $primelow + $rand + $rand;
301             croak "random prime failure, $prime > $high" if $prime > $high;
302             if ($prime <= 23) {
303             $prime = 2 if $prime == 1; # special case for low = 2
304             next unless (0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1)[$prime];
305             return $prime;
306             }
307             next if !($prime % 3) || !($prime % 5) || !($prime % 7) || !($prime % 11);
308             # It looks promising. Check it.
309             next unless is_prob_prime($prime);
310             return $prime;
311             }
312             croak "Random function broken?";
313             }
314              
315             # By checking a wheel 30 mod, we can skip anything that would be a multiple
316             # of 2, 3, or 5, without even having to create the bigint prime.
317             my @w30 = (1,0,5,4,3,2,1,0,3,2,1,0,1,0,3,2,1,0,1,0,3,2,1,0,5,4,3,2,1,0);
318             my $primelow30 = modint($primelow, 30);
319              
320             # Big GCD's are hugely fast with GMP or Pari, but super slow with Calc.
321             _make_big_gcds() if $_big_gcd_use < 0;
322              
323             while ($loop_limit-- > 0) {
324             my $rand = urandomm($partsize);
325             # Check wheel-30 mod
326             my $rand30 = $rand % 30;
327             next if $w30[($primelow30 + 2*$rand30) % 30]
328             && ($rand > 3 || $primelow > 5);
329             # Construct prime
330             $prime = $primelow + $rand + $rand;
331             croak "random prime failure, $prime > $high" if $prime > $high;
332             if ($prime <= 23) {
333             $prime = 2 if $prime == 1; # special case for low = 2
334             next unless (0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1)[$prime];
335             return $prime;
336             }
337             # With GMP, the fastest thing to do is check primality.
338             if (MPU_USE_GMP) {
339             next unless Math::Prime::Util::GMP::is_prime($prime);
340             return $prime;
341             }
342             # No MPU:GMP, so primality checking is slow. Skip some composites here.
343             next unless gcd($prime,7436429) == 1;
344             if ($_big_gcd_use && $prime > $_big_gcd_top) {
345             next unless gcd($prime, $_big_gcd[0]) == 1;
346             next unless gcd($prime, $_big_gcd[1]) == 1;
347             next unless gcd($prime, $_big_gcd[2]) == 1;
348             next unless gcd($prime, $_big_gcd[3]) == 1;
349             }
350             # It looks promising. Check it.
351             next unless is_prob_prime($prime);
352             return $prime;
353             }
354             croak "Random function broken?";
355             };
356              
357             # Cache of tight bounds for each bit. Not used in current code path.
358             my @_random_nbit_ranges = (undef, undef, [2,3],[5,7] );
359              
360             # For fixed small ranges with XS, e.g. 6-digit, 18-bit
361             # mpu 'say join ",",map {($b,$e)=(next_prime(powint(10,$_-1)),prev_prime(powint(10,$_))); $s=prime_count($b); $c=prime_count($b,$e); "[$s,$c]";} 1..8'
362             my $_d_digits = [undef,[1,4],[5,21],[26,143],[169,1061],[1230,8363],[9593,68906],[78499,586081],[664580,5096876]];
363             # mpu 'say join ",",map {($b,$e)=(next_prime(powint(2,$_-1)),prev_prime(powint(2,$_))); $s=prime_count($b); $c=prime_count($b,$e); "[$s,$c]";} 2..24'
364             my $_d_bits = [undef,undef,[2,1],[3,2],[5,2],[7,5],[12,7],[19,13],[32,23],[55,43],[98,75],[173,137],[310,255],[565,464],[1029,872],[1901,1612],[3513,3030],[6543,5709],[12252,10749],[23001,20390],[43391,38635],[82026,73586],[155612,140336],[295948,268216],[564164,513708]];
365             sub _random_xscount_prime {
366 0     0   0 my($n, $data) = @_;
367 0         0 my $dv = $data->[$n];
368 0 0       0 croak "bad xscount data: $n" unless defined $dv;
369 0         0 return nth_prime($dv->[0] + urandomm($dv->[1]));
370             }
371              
372             my @_digit_loprime = qw/0 2 11 101 1009 10007 100003 1000003 10000019 100000007 1000000007 10000000019 100000000003 1000000000039 10000000000037 100000000000031 1000000000000037 10000000000000061 100000000000000003 1000000000000000003 10000000000000000051/;
373             my @_digit_hiprime = qw/0 7 97 997 9973 99991 999983 9999991 99999989 999999937 9999999967 99999999977 999999999989 9999999999971 99999999999973 999999999999989 9999999999999937 99999999999999997 999999999999999989 9999999999999999961 99999999999999999989/;
374             my $_max_native_prime = MPU_32BIT ? 4294967291 : 18446744073709551557;
375              
376             sub random_prime {
377 2     2 1 6 my($low,$high) = @_;
378 2 50 33     13 return undef if $high < 2 || $low > $high;
379              
380 2 50       280 if ($high-$low > 1000000000) {
381             # Range is large, just make them odd if needed.
382 2 50       420 $low = 2 if $low < 2;
383 2 50 33     139 $low++ if $low > 2 && ($low % 2) == 0;
384 2 50       463 $high-- if ($high % 2) == 0;
385             } else {
386             # Tighten the range to the nearest prime.
387 0 0       0 $low = ($low <= 2) ? 2 : next_prime($low-1);
388 0 0       0 $high = ($high == ~0) ? prev_prime($high) : prev_prime($high + 1);
389 0 0 0     0 return $low if ($low == $high) && is_prob_prime($low);
390 0 0       0 return undef if $low >= $high;
391             # At this point low and high are both primes, and low < high.
392             }
393              
394             # At this point low and high are both odds, and low < high.
395 2         372 return $_random_prime->($low, $high);
396             }
397              
398             sub random_ndigit_prime {
399 3     3 1 10 my($D) = @_;
400 3 50       43 croak "random_ndigit_prime, digits must be >= 1" unless $D >= 1;
401              
402 3 50 50     18 return _random_xscount_prime($D,$_d_digits) if $D <= 6 && MPU_USE_XS;
403              
404 3 100       218 $_digit_loprime[$D] = powint(10,$D-1)+1 unless defined $_digit_loprime[$D];
405 3 100       1510 $_digit_hiprime[$D] = powint(10,$D)-1 unless defined $_digit_hiprime[$D];
406 3 100 100     1386 my($lo,$hi) = map { $_ >= ~0 && !ref($_) ? addint($_,0) : $_ }
  6         763  
407             ($_digit_loprime[$D], $_digit_hiprime[$D]);
408              
409 3 100 66     836 if ($D >= MPU_MAXDIGITS && prime_get_config->{'nobigint'}) {
410 1 50       4 croak "random_ndigit_prime with -nobigint, digits out of range"
411             if $D > MPU_MAXDIGITS;
412 1         2 $hi = $_max_native_prime;
413             }
414 3         24 return $_random_prime->($lo, $hi);
415             }
416              
417             sub _set_premod {
418 15     15   49 my($arr, $b, $bits, @plist) = @_;
419 15         66 my $mod = vecprod(@plist);
420 15 50 33     83 croak "Bad mod $mod [@plist]" unless $mod <= ~0 && $mod*$plist[-1] < ~0;
421 15         135 my($bpremod,$twopremod) = (modint($b,$mod), powmod(2,$bits,$mod));
422 15         42 for my $p (@plist) {
423             # Find the value X where $twopremod * X + $bpremod % $p == 0
424 115         398 $arr->[$p] = (invmod($twopremod,$p) * ($p-$bpremod)) % $p;
425             }
426             }
427             sub _get_premod {
428 5     5   28 my($b, $bits, @plist) = @_;
429 5         39 my @premod;
430 5         18 my($fn,$fp,$bn) = MPU_32BIT ? (8,23,3) : (14,47,5);
431             # Do one initial mod with first $fn primes, then batches of $bn primes.
432 5 50 33     70 _set_premod(\@premod, $b, $bits, splice(@plist,0,$fn)) if @plist >= $fn && $plist[$fn-1] <= $fp;
433 5         39 _set_premod(\@premod, $b, $bits, splice(@plist,0,$bn)) while @plist;
434 5         90 @premod;
435             }
436              
437             sub random_nbit_prime {
438 14     14 1 43 my($bits) = @_;
439 14 50       52 croak "random_nbit_prime, bits must be >= 2" unless $bits >= 2;
440 14         43 $bits = int("$bits");
441              
442             # Very small size, use the nth-prime method
443 14 50 50     69 if ($bits <= 19 && MPU_USE_XS) {
444 0 0       0 if ($bits <= 4) {
445 0 0       0 return (2,3)[urandomb(1)] if $bits == 2;
446 0 0       0 return (5,7)[urandomb(1)] if $bits == 3;
447 0 0       0 return (11,13)[urandomb(1)] if $bits == 4;
448             }
449 0         0 return _random_xscount_prime($bits,$_d_bits);
450             }
451              
452 14         34 croak "Mid-size random primes not supported on broken old Perl"
453             if OLD_PERL_VERSION && MPU_64BIT && $bits > 49 && $bits <= 64;
454              
455             # Fouque and Tibouchi (2011) Algorithm 1 (basic)
456             # Modified to make sure the nth bit is always set.
457             #
458             # Example for random_nbit_prime(512) on 64-bit Perl:
459             # p: 1aaaaaaaabbbbbbbbbbbbbbbbbbbb1
460             # ^^ ^ ^--- Trailing 1 so p is odd
461             # || +--- 512-63-2 = 447 lower bits selected before loop
462             # |+--- 63 upper bits selected in loop, repeated until p is prime
463             # +--- upper bit is 1 so we generate an n-bit prime
464             # total: 1 + 63 + 447 + 1 = 512 bits
465             #
466             # Algorithm 2 is implemented in a previous commit on github. The problem
467             # is that it doesn't set the nth bit, and making that change requires a
468             # modification of the algorithm. It was not a lot faster than this A1
469             # with the native int trial division. If the irandf function was very
470             # slow, then A2 would look more promising.
471             #
472 14 100       53 if (1 && $bits > MPU_MAXBITS) {
473 5 100       21 my $l = (MPU_64BIT && $bits > 79) ? 63 : 31;
474 5 50 100     36 $l = 49 if $l == 63 && OLD_PERL_VERSION; # Fix for broken Perl 5.6
475 5 50       23 $l = $bits-2 if $bits-2 < $l;
476 5         14 my $lbits = $bits - $l - 1;
477              
478 5         70 my $brand = urandomb($bits-$l-2);
479 5         52 my $b = add1int(lshiftint($brand));
480              
481             # Precalculate some modulii so we can do trial division on native int
482 5         36 my @PM = _get_premod($b, $lbits, 3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89);
483 5 100       28 _make_big_gcds() if $_big_gcd_use < 0;
484 5         15 if (!MPU_USE_GMP) { require Math::Prime::Util::PP; }
  5         44  
485              
486 5         12 my $loop_limit = 1_000_000;
487 5         25 while ($loop_limit-- > 0) {
488 87         543 my $a = addint((1 << $l),urandomb($l));
489             # $a % s == $PM[s] => $p % s == 0 => p will be composite
490 87 100 100     2093 next if $a % 3 == $PM[ 3] || $a % 5 == $PM[ 5] || $a % 7 == $PM[ 7]
      100        
      100        
      100        
      66        
      100        
      100        
      100        
      100        
      100        
      66        
      66        
      33        
      66        
      100        
      100        
      66        
      100        
      66        
      66        
      66        
      66        
491             || $a % 11 == $PM[11] || $a % 13 == $PM[13] || $a % 17 == $PM[17]
492             || $a % 19 == $PM[19] || $a % 23 == $PM[23] || $a % 29 == $PM[29]
493             || $a % 31 == $PM[31] || $a % 37 == $PM[37] || $a % 41 == $PM[41]
494             || $a % 43 == $PM[43] || $a % 47 == $PM[47] || $a % 53 == $PM[53]
495             || $a % 59 == $PM[59] || $a % 61 == $PM[61] || $a % 67 == $PM[67]
496             || $a % 71 == $PM[71] || $a % 73 == $PM[73] || $a % 79 == $PM[79]
497             || $a % 83 == $PM[83] || $a % 89 == $PM[89];
498 20         2472 my $p = addint(lshiftint($a,$lbits), $b);
499             #die " $a $b $p" if $a % 11 == $premod[11] && $p % 11 != 0;
500             #die "!$a $b $p" if $a % 11 != $premod[11] && $p % 11 == 0;
501 20         5503 if (MPU_USE_GMP) {
502             next unless Math::Prime::Util::GMP::is_prime($p);
503             } else {
504 20 50 33     120 if ($_big_gcd_use && $p > $_big_gcd_top) {
505 0 0       0 next unless gcd($p, $_big_gcd[0]) == 1;
506 0 0       0 next unless gcd($p, $_big_gcd[1]) == 1;
507 0 0       0 next unless gcd($p, $_big_gcd[2]) == 1;
508 0 0       0 next unless gcd($p, $_big_gcd[3]) == 1;
509             }
510             # We know we don't have GMP and are > 2^64, so go directly to this.
511 20 100       93 next unless Math::Prime::Util::PP::is_bpsw_prime($p);
512             }
513 5         470 return $p;
514             }
515 0         0 croak "Random function broken?";
516             }
517              
518             # The Trivial method. Great uniformity, and fine for small sizes. It
519             # gets very slow as the bit size increases, but that is why we have the
520             # method above for bigints.
521 9         18 if (1) {
522              
523 9         19 my $loop_limit = 2_000_000;
524 9 50       30 if ($bits > MPU_MAXBITS) {
525 0         0 my $p = add1int(lshiftint(1,$bits-1));
526 0         0 while ($loop_limit-- > 0) {
527 0         0 my $n = addint(lshiftint(urandomb($bits-2)), $p);
528 0 0       0 return $n if is_prob_prime($n);
529             }
530             } else {
531 9         24 my $p = (1 << ($bits-1)) + 1;
532 9         57 while ($loop_limit-- > 0) {
533 112         446 my $n = $p + (urandomb($bits-2) << 1);
534 112 100       842 return $n if is_prob_prime($n);
535             }
536             }
537 0         0 croak "Random function broken?";
538              
539             } else {
540              
541             # Send through the generic random_prime function. Decently fast, but
542             # quite a bit slower than the F&T A1 method above.
543             if (!defined $_random_nbit_ranges[$bits]) {
544             if ($bits > MPU_MAXBITS) {
545             my $low = powint(2,$bits-1);
546             my $high = powint(2,$bits);
547             # Don't pull the range in to primes, just odds
548             $_random_nbit_ranges[$bits] = [$low+1, $high-1];
549             } else {
550             my $low = 1 << ($bits-1);
551             my $high = ($bits == MPU_MAXBITS)
552             ? ~0-1
553             : ~0 >> (MPU_MAXBITS - $bits);
554             $_random_nbit_ranges[$bits] = [next_prime($low-1),prev_prime($high+1)];
555             # Example: bits = 7.
556             # low = 1<<6 = 64. next_prime(64-1) = 67
557             # high = ~0 >> (64-7) = 127. prev_prime(127+1) = 127
558             }
559             }
560             my ($low, $high) = @{$_random_nbit_ranges[$bits]};
561             return $_random_prime->($low, $high);
562              
563             }
564             }
565              
566              
567             # For stripping off the header on certificates so they can be combined.
568             sub _strip_proof_header {
569 0     0   0 my $proof = shift;
570 0         0 $proof =~ s/^\[MPU - Primality Certificate\]\nVersion \S+\n+Proof for:\nN (\d+)\n+//ms;
571 0         0 return $proof;
572             }
573              
574              
575             sub random_maurer_prime {
576 0     0 1 0 my $k = shift;
577 0 0       0 croak "random_maurer_prime, bits must be >= 2" unless $k >= 2;
578 0         0 $k = int("$k");
579              
580 0 0 0     0 return random_nbit_prime($k) if $k <= MPU_MAXBITS && !OLD_PERL_VERSION;
581              
582 0         0 my ($n, $cert) = random_maurer_prime_with_cert($k);
583 0 0       0 croak "maurer prime $n failed certificate verification!"
584             unless verify_prime($cert);
585 0         0 return $n;
586             }
587              
588             sub random_maurer_prime_with_cert {
589 6     6 1 20 my $k = shift;
590 6 50       33 croak "random_maurer_prime, bits must be >= 2" unless $k >= 2;
591 6         20 $k = int("$k");
592              
593             # This should never happen. Trap now to prevent infinite loop.
594 6 50       26 croak "number of bits must not be a bigint" if ref($k) eq 'Math::BigInt';
595              
596             # Results for random_nbit_prime are proven for all native bit sizes.
597 6         13 my $p0 = MPU_MAXBITS;
598 6         12 $p0 = 49 if OLD_PERL_VERSION && MPU_MAXBITS > 49;
599              
600 6 100       20 if ($k <= $p0) {
601 3         16 my $n = random_nbit_prime($k);
602 3         22 my ($isp, $cert) = is_provable_prime_with_cert($n);
603 3 50       12 croak "small nbit prime could not be proven" if $isp != 2;
604 3         10 return ($n, $cert);
605             }
606              
607             # Set verbose to 3 to get pretty output like Crypt::Primes
608 3         14 my $verbose = prime_get_config->{'verbose'};
609 3 50       14 local $| = 1 if $verbose > 2;
610              
611 3 100       10 do { require Math::BigFloat; Math::BigFloat->import(); }
  1         3208  
  1         58460  
612             if !defined $Math::BigFloat::VERSION;
613              
614             # Ignore Maurer's g and c that controls how much trial division is done.
615 3         202 my $r = Math::BigFloat->new("0.5"); # relative size of the prime q
616 3         1216 my $m = 20; # makes sure R is big enough
617              
618             # Generate a random prime q of size $r*$k, where $r >= 0.5. Try to
619             # cleverly select r to match the size of a typical random factor.
620 3 50       19 if ($k > 2*$m) {
621 3         21 do {
622 9         477455 my $s = Math::Prime::Util::drand();
623 9         45 $r = Math::BigFloat->new(2)->bpow($s-1);
624             } while ($k*$r >= $k-$m);
625             }
626              
627             # I've seen +0, +1, and +2 here. Maurer uses +0. Menezes uses +1.
628             # We can use +1 because we're using BLS75 theorem 3 later.
629 3         242311 my $smallk = int(($r * $k)->bfloor->bstr) + 1;
630 3         2181 my ($q, $qcert) = random_maurer_prime_with_cert($smallk);
631 3         463 my $I = divint(powint(2,$k-2),$q);
632 3 50 33     23 print "r = $r k = $k q = $q I = $I\n" if $verbose && $verbose != 3;
633 3 50       47 $qcert = cmpint($q,"18446744073709551615") <= 0
634             ? "" : _strip_proof_header($qcert);
635              
636             # Big GCD's are hugely fast with GMP or Pari, but super slow with Calc.
637 3 100       16 _make_big_gcds() if $_big_gcd_use < 0;
638              
639 3         10 my $loop_limit = 1_000_000 + $k * 1_000;
640 3         13 while ($loop_limit-- > 0) {
641             # R is a random number between $I+1 and 2*$I
642             #my $R = $I + 1 + urandomm( $I );
643 58         2052 my $R = addint($I, add1int(urandomm($I)));
644             #my $n = 2 * $R * $q + 1;
645 58         4360 my $nm1 = vecprod(2,$R,$q);
646 58         9741 my $n = add1int($nm1);
647             # We constructed a promising looking $n. Now test it.
648 58 50       9454 print "." if $verbose > 2;
649 58         106 if (MPU_USE_GMP) {
650             # MPU::GMP::is_prob_prime has fast tests built in.
651             next unless Math::Prime::Util::GMP::is_prob_prime($n);
652             } else {
653             # No GMP, so first do trial divisions, then a SPSP test.
654 58 100       229 next unless gcd($n, 111546435) == 1;
655 25 50 33     96 if ($_big_gcd_use && $n > $_big_gcd_top) {
656 0 0       0 next unless gcd($n, $_big_gcd[0]) == 1;
657 0 0       0 next unless gcd($n, $_big_gcd[1]) == 1;
658 0 0       0 next unless gcd($n, $_big_gcd[2]) == 1;
659 0 0       0 next unless gcd($n, $_big_gcd[3]) == 1;
660             }
661 25 50       55 print "+" if $verbose > 2;
662 25 100       100 next unless is_strong_pseudoprime($n, 3);
663             }
664 3 50       14 print "*" if $verbose > 2;
665              
666             # We could pick a random generator by doing:
667             # Step 1: pick a random r
668             # Step 2: compute g = r^((n-1)/q) mod p
669             # Step 3: if g == 1, goto Step 1.
670             # Note that n = 2*R*q+1, hence the exponent is 2*R.
671              
672             # We could set r = 0.3333 earlier, then use BLS75 theorem 5 here.
673             # The chain would be shorter, requiring less overall work for
674             # large inputs. Maurer's paper discusses the idea.
675              
676             # Use BLS75 theorem 3. This is easier and possibly faster than
677             # BLS75 theorem 4 (Pocklington) used by Maurer's paper.
678              
679             # Check conditions -- these should be redundant.
680 3         18 my $m = mulint(2,$R);
681 3 50 33     276 if (! (is_odd($q) && $q > 2 && $m > 0 &&
      33        
      33        
      33        
682             mulint($m,$q) + 1 == $n && mulint(2,$q)+1 > sqrtint($n)) ) {
683 0         0 carp "Maurer prime failed BLS75 theorem 3 conditions. Retry.";
684 0         0 next;
685             }
686             # Find a suitable a. Move on if one isn't found quickly.
687 3         30 foreach my $a (2, 3, 5, 7, 11, 13) {
688             # m/2 = R (n-1)/2 = (2*R*q)/2 = R*q
689 10 50       1834 next unless powmod($a, $R, $n) != $nm1;
690 10 100       3714 next unless powmod($a, mulint($R,$q), $n) == $nm1;
691 3 50       972 print "($k)" if $verbose > 2;
692 3 50       30 croak "Maurer prime $n=2*$R*$q+1 failed BPSW" unless is_prob_prime($n);
693 3         1264 my $cert = "[MPU - Primality Certificate]\nVersion 1.0\n\n" .
694             "Proof for:\nN $n\n\n" .
695             "Type BLS3\nN $n\nQ $q\nA $a\n" .
696             $qcert;
697 3         376 return ($n, $cert);
698             }
699             # Didn't pass the selected a values. Try another R.
700             }
701 0         0 croak "Failure in random_maurer_prime, could not find a prime\n";
702             } # End of random_maurer_prime
703              
704              
705             sub random_shawe_taylor_prime_with_cert {
706 1     1 1 3 my $k = shift;
707              
708 1         8 my $seed = random_bytes(512/8);
709              
710 1         7 my($status,$prime,$prime_seed,$prime_gen_counter,$cert)
711             = _ST_Random_prime($k, $seed);
712 1 50       6 croak "Shawe-Taylor random prime failure" unless $status;
713 1 50       6 croak "Shawe-Taylor random prime failure: prime $prime failed certificate verification!" unless verify_prime($cert);
714              
715 1         11 return ($prime,$cert);
716             }
717              
718             sub _seed_plus_one {
719 12     12   36 my($s) = @_;
720 12         49 for (my $i = length($s)-1; $i >= 0; $i--) {
721 12         56 vec($s, $i, 8)++;
722 12 50       51 last unless vec($s, $i, 8) == 0;
723             }
724 12         37 return $s;
725             }
726              
727             sub _ST_Random_prime { # From FIPS 186-4
728 3     3   10 my($k, $input_seed) = @_;
729 3 50       12 croak "Shawe-Taylor random prime must have length >= 2" if $k < 2;
730 3         11 $k = int("$k");
731              
732 3 50 33     17 croak "Shawe-Taylor random prime, invalid input seed"
733             unless defined $input_seed && length($input_seed) >= 32;
734              
735 3 50       78 if (!defined $Digest::SHA::VERSION) {
736 0         0 eval { require Digest::SHA;
737 0         0 my $version = $Digest::SHA::VERSION;
738 0         0 $version =~ s/[^\d.]//g;
739 0         0 $version >= 4.00; }
740 0 0       0 or do { croak "Must have Digest::SHA 4.00 or later"; };
  0         0  
741             }
742              
743 3         142 my $k2 = tobigint(powint(2,$k-1)); # $k2 is a bigint
744              
745 3 100       11 if ($k < 33) {
746 1         4 my $seed = $input_seed;
747 1         2 my $prime_gen_counter = 0;
748 1         4 my $kmask = 0xFFFFFFFF >> (32-$k); # Does the mod operation
749 1         4 my $kstencil = (1 << ($k-1)) | 1; # Sets high and low bits
750 1         3 while (1) {
751 2         8 my $seedp1 = _seed_plus_one($seed);
752 2         38 my $cvec = Digest::SHA::sha256($seed) ^ Digest::SHA::sha256($seedp1);
753             # my $c = Math::BigInt->from_hex('0x' . unpack("H*", $cvec));
754             # $c = $k2 + ($c % $k2);
755             # $c = (2 * ($c >> 1)) + 1;
756 2         11 my($c) = unpack("N*", substr($cvec,-4,4));
757 2         5 $c = ($c & $kmask) | $kstencil;
758 2         3 $prime_gen_counter++;
759 2         6 $seed = _seed_plus_one($seedp1);
760 2         10 my ($isp, $cert) = is_provable_prime_with_cert($c);
761 2 100       15 return (1,$c,$seed,$prime_gen_counter,$cert) if $isp;
762 1 50       6 return (0,0,0,0) if $prime_gen_counter > 10000 + 16*$k;
763             }
764             }
765 2         59 my($status,$c0,$seed,$prime_gen_counter,$cert)
766             = _ST_Random_prime( (($k+1)>>1)+1, $input_seed);
767 2 50       10 return (0,0,0,0) unless $status;
768 2 50       19 $cert = cmpint($c0,"18446744073709551615") <= 0
769             ? "" : _strip_proof_header($cert);
770 2         10 my $iterations = int(($k + 255) / 256) - 1; # SHA256 generates 256 bits
771 2         5 my $old_counter = $prime_gen_counter;
772 2         8 my $c02 = lshiftint($c0); # $c02 = 2*$c0
773 2         5 my $xstr = '';
774 2         26 for my $i (0 .. $iterations) {
775 2         26 $xstr = Digest::SHA::sha256_hex($seed) . $xstr;
776 2         8 $seed = _seed_plus_one($seed);
777             }
778 2         223 my $x = fromdigits($xstr,16);
779 2         556 $x = $k2 + ($x % $k2);
780 2         1660 my $t = cdivint($x, $c02);
781 2 50       127 _make_big_gcds() if $_big_gcd_use < 0;
782 2         5 while (1) {
783 6         410 my $c = add1int(mulint($t,$c02));
784 6 50       1360 if ($c > 2*$k2) {
785 0         0 $t = cdivint($k2, $c02);
786 0         0 $c = add1int(mulint($t,$c02));
787             }
788 6         2940 $prime_gen_counter++;
789              
790             # Don't do the Pocklington check unless the candidate looks prime
791 6         13 my $looks_prime = 0;
792 6         13 if (MPU_USE_GMP) {
793             # MPU::GMP::is_prob_prime has fast tests built in.
794             $looks_prime = Math::Prime::Util::GMP::is_prob_prime($c);
795             } else {
796             # No GMP, so first do trial divisions, then a SPSP test.
797 6         77 $looks_prime = gcd($c, 111546435) == 1;
798 6 50 66     40 if ($looks_prime && $_big_gcd_use && $c > $_big_gcd_top) {
      33        
799 0   0     0 $looks_prime = gcd($c, $_big_gcd[0]) == 1 &&
800             gcd($c, $_big_gcd[1]) == 1 &&
801             gcd($c, $_big_gcd[2]) == 1 &&
802             gcd($c, $_big_gcd[3]) == 1;
803             }
804 6 100 100     36 $looks_prime = 0 if $looks_prime && !is_strong_pseudoprime($c, 3);
805             }
806              
807 6 100       110 if ($looks_prime) {
808             # We could use a in (2,3,5,7,11,13), but pedantically use FIPS 186-4.
809 2         6 my $astr = '';
810 2         8 for my $i (0 .. $iterations) {
811 2         25 $astr = Digest::SHA::sha256_hex($seed) . $astr;
812 2         10 $seed = _seed_plus_one($seed);
813             }
814 2         204 my $a = fromdigits($astr,16);
815 2         390 $a = addint(modint($a,$c-3),2);
816 2         183 my $z = powmod($a, lshiftint($t), $c);
817 2 50 33     221 if (gcd($z-1,$c) == 1 && powmod($z, $c0, $c) == 1) {
818 2 50       54 croak "Shawe-Taylor random prime failure at ($k): $c not prime"
819             unless is_prob_prime($c);
820 2         13 $cert = "[MPU - Primality Certificate]\nVersion 1.0\n\n" .
821             "Proof for:\nN $c\n\n" .
822             "Type Pocklington\nN $c\nQ $c0\nA $a\n" .
823             $cert;
824 2         123 return (1, $c, $seed, $prime_gen_counter, $cert);
825             }
826             } else {
827             # Update seed "as if" we performed the Pocklington check from FIPS 186-4
828 4         15 for my $i (0 .. $iterations) {
829 4         89 $seed = _seed_plus_one($seed);
830             }
831             }
832 4 50       44 return (0,0,0,0) if $prime_gen_counter > 10000 + 16*$k + $old_counter;
833 4         17 $t++;
834             }
835             }
836              
837             sub random_safe_prime {
838 2     2 1 10 my $bits = int("$_[0]");
839 2 50       10 croak "random_safe_prime, bits must be >= 3" unless $bits >= 3;
840 2 50       8 return (5,7)[urandomb(1)] if $bits == 3;
841 2 50       9 return 11 if $bits == 4;
842 2 50       9 return 23 if $bits == 5;
843 2 50       8 return (47,59)[urandomb(1)] if $bits == 6;
844 2 50       7 return (83,107)[urandomb(1)] if $bits == 7;
845              
846             # Without GMP (e.g. Calc), this can be significantly faster.
847             # With GMP, they are about the same.
848 2 50       19 return _random_safe_prime_large($bits) if $bits > 35;
849              
850 0         0 my($p,$q);
851 0         0 while (1) {
852 0         0 $q = Math::Prime::Util::random_nbit_prime($bits-1);
853 0         0 my $qm = modint($q, 1155); # a nice native int
854 0 0 0     0 next if ($qm % 3) != 2
      0        
      0        
855             || ($qm % 5) == 2 || ($qm % 7) == 3 || ($qm % 11) == 5;
856 0         0 $p = mulint(2, $q) + 1;
857             # This is sufficient, but we'll do the full test including pre-tests.
858             #last if is_pseudoprime($p,2); # p is prime if q is prime
859 0 0       0 last if is_prob_prime($p);
860             }
861 0         0 return $p;
862             }
863              
864             sub _random_safe_prime_large {
865 2     2   5 my $bits = shift;
866 2 50       9 croak "Not enough bits for large random_safe_prime" if $bits <= 35;
867              
868             # Set first and last two bits
869 2         188 my $base = addint(lshiftint(1, $bits-1),3);
870             # Fill in lower portion with random bits, leaving 32 upper
871 2         668 $base = addint($base, lshiftint(urandomb($bits - 35), 2));
872              
873 2         576 while (1) {
874 548         40312 my($p,$q,$qmod,$pmod);
875             # 1. generate random nbit p
876 548         53721 $p = lshiftint(urandomb(32), $bits-33);
877 548         135700 $p = addint($base, $p);
878              
879             # 2. p = 2q+1 => q = p>>1
880 548         137621 $q = rshiftint($p);
881              
882             # 3. Force q mod 6 = 5
883 548         134315 $qmod = modint(add1int($q),6);
884 548 100       5248 if ($qmod > 0) {
885 363         2236 $q = subint($q,$qmod);
886 363 50       87723 $q = addint($q,12) if 1+logint($q,2) != $bits-1;
887 363         2188 $p = add1int(lshiftint($q));
888             }
889              
890             # 4. Fast compositeness pre-tests for q and p
891 548         91651 $pmod = modint($p, 5*7*11*13*17*19*23*37);
892 548 100 100     10061 next if (($pmod % 5) >> 1) == 0 ||
      100        
      100        
      100        
      100        
      100        
      100        
893             (($pmod % 7) >> 1) == 0 ||
894             (($pmod % 11) >> 1) == 0 ||
895             (($pmod % 13) >> 1) == 0 ||
896             (($pmod % 17) >> 1) == 0 ||
897             (($pmod % 19) >> 1) == 0 ||
898             (($pmod % 23) >> 1) == 0 ||
899             (($pmod % 37) >> 1) == 0;
900 110         695 $pmod = modint($p, 29*31*41*43*47*53);
901 110 100 100     2503 next if (($pmod % 29) >> 1) == 0 ||
      100        
      100        
      100        
      100        
902             (($pmod % 31) >> 1) == 0 ||
903             (($pmod % 41) >> 1) == 0 ||
904             (($pmod % 43) >> 1) == 0 ||
905             (($pmod % 47) >> 1) == 0 ||
906             (($pmod % 53) >> 1) == 0;
907 86         525 $pmod = modint($p, 59*61*67*71*73);
908 86 100 66     1601 next if (($pmod % 59) >> 1) == 0 ||
      100        
      100        
      100        
909             (($pmod % 61) >> 1) == 0 ||
910             (($pmod % 67) >> 1) == 0 ||
911             (($pmod % 71) >> 1) == 0 ||
912             (($pmod % 73) >> 1) == 0;
913              
914             # 6. Primality testing on p and q
915              
916             # Use Pocklington's theorem for p, BPSW for q.
917             # If we find an 'a' such that
918             # 1. a^(p-1) = 1 mod p (This is a Fermat test base 'a')
919             # 2. gcd(a^(p-1)/q - 1, p) = 1 => gcd(a^2-1, p) = 1
920             # then p is prime if q is prime.
921             # Choose a=2.
922             # Then p is prime if:
923             # - q is prime
924             # - p passes a base 2 Fermat test
925             # - p is not divisible by 3
926              
927 78 100       482 next unless is_pseudoprime($p, 2);
928              
929             # Now strong testing on q. Split in two.
930 12 100       112 next unless is_strong_pseudoprime($q, 2);
931 2 50       20 next unless is_extra_strong_lucas_pseudoprime($q);
932 2 50       710 croak "random safe prime internal failure" unless $p == 2*$q+1;
933              
934             # q passes BPSW, p passes Fermat base 2. p is prime if q is prime.
935 2         1586 return $p;
936             }
937             }
938              
939              
940             # Gordon's algorithm for generating a strong prime.
941             sub random_strong_prime {
942 1     1 1 3 my $t = shift;
943 1 50       5 croak "random_strong_prime, bits must be >= 128" unless $t >= 128;
944 1         4 $t = int("$t");
945              
946 1         2 croak "Random strong primes must be >= 173 bits on old Perl"
947             if OLD_PERL_VERSION && MPU_64BIT && $t < 173;
948              
949 1         23 my $l = (($t+1) >> 1) - 2;
950 1         4 my $lp = ($t >> 1) - 20;
951 1         2 my $lpp = $l - 20;
952 1         4 while (1) {
953 1         8 my $qp = random_nbit_prime($lp);
954 1         6 my $qpp = random_nbit_prime($lpp);
955 1         8 my $qp2 = mulint(2,$qp);
956 1         275 my $qpp2 = mulint(2,$qpp);
957 1         391 my $il = cdivint(sub1int(lshiftint(1,$l-1)),$qpp2);
958 1         108 my $iu = divint(subint(lshiftint(2,$l),2),$qpp2);
959 1         19 my $istart = addint($il, urandomm($iu - $il + 1));
960 1         7 for (my $i = $istart; $i <= $iu; $i=add1int($i)) { # Search for q
961 42         7493 my $q = add1int(mulint($i,$qpp2));
962 42 100       12252 next unless is_prob_prime($q);
963 1         10 my $qqp2 = mulint($q,$qp2);
964 1         283 my $pp = sub1int(mulint($qp2, powmod($qp, $q-2, $q)));
965 1         380 my $jl = cdivint(subint(lshiftint(1,$t-1),$pp), $qqp2);
966 1         105 my $ju = divint(subint(lshiftint(1,$t),$pp+1), $qqp2);
967 1         21 my $jstart = addint($jl, urandomm($ju - $jl + 1));
968 1         7 for (my $j = $jstart; $j <= $ju; $j=add1int($j)) { # Search for p
969 12         2151 my $p = addint($pp, mulint($j,$qqp2));
970 12 100       3652 return $p if is_prob_prime($p);
971             }
972             }
973             }
974             }
975              
976             sub random_proven_prime {
977 0     0 1 0 my $k = shift;
978 0         0 my ($n, $cert) = random_proven_prime_with_cert($k);
979 0 0       0 croak "random_proven_prime $n failed certificate verification!"
980             unless verify_prime($cert);
981 0         0 return $n;
982             }
983              
984             sub random_proven_prime_with_cert {
985 1     1 1 4 my $k = shift;
986              
987 1 50 33     5 if (prime_get_config->{'gmp'} && $k <= 450) {
988 0         0 my $n = random_nbit_prime($k);
989 0         0 my ($isp, $cert) = is_provable_prime_with_cert($n);
990 0 0       0 croak "small nbit prime could not be proven" if $isp != 2;
991 0         0 return ($n, $cert);
992             }
993 1         7 return random_maurer_prime_with_cert($k);
994             }
995              
996             1;
997              
998             __END__