[libmath-prime-util-perl] 05/16: Add random_strong_prime, update to 0.18

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:46:50 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.19
in repository libmath-prime-util-perl.

commit a522f78d3d165f3ea13b3c50779085c48027bca9
Author: Dana Jacobsen <dana at acm.org>
Date:   Mon Jan 14 02:28:19 2013 -0800

    Add random_strong_prime, update to 0.18
---
 Changes                | 11 +++++++
 Makefile.PL            |  8 +++--
 README                 |  2 +-
 TODO                   |  3 ++
 lib/Math/Prime/Util.pm | 79 +++++++++++++++++++++++++++++++++++++++++++++++---
 t/81-bignum.t          |  8 ++++-
 6 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/Changes b/Changes
index 5f361fa..ff596b5 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,16 @@
 Revision history for Perl extension Math::Prime::Util.
 
+0.18  14 January 2012
+
+    - Add random_strong_prime.
+
+    - Fix builds with Solaris 9 and older.
+
+    - Add some debug info to perhaps find out why old ActiveState Perls are
+      dying in Math::BigInt::Calc, as if they were using really old versions
+      that run out of memory trying to calculate '2 ** 66'.
+      http://code.activestate.com/ppm/Math-Prime-Util/
+
 0.17  20 December 2012
 
     - Perl 5.8.1 - 5.8.7 miscalculates 12345 ** 4, which I used in a test.
diff --git a/Makefile.PL b/Makefile.PL
index 27629f9..a89dd6a 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -33,9 +33,11 @@ WriteMakefile1(
                       'Math::BigFloat'   => '1.59',
                     },
     META_MERGE   => {
-                      recommends => { 'Math::Prime::Util::GMP' => 0.06, },
-                      recommends => { 'Math::BigInt::GMP' => 0, },
-                      recommends => { 'Math::MPFR' => 0, },
+                      recommends => {
+                        'Math::Prime::Util::GMP' => 0.06,
+                        'Math::BigInt::GMP'      => 0,
+                        'Math::MPFR'             => 2.03,
+                      },
                     },
 
     MIN_PERL_VERSION => 5.006002,
diff --git a/README b/README
index be92e29..efb7df9 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Math::Prime::Util version 0.17
+Math::Prime::Util version 0.18
 
 A set of utilities related to prime numbers.  These include multiple sieving
 methods, is_prime, prime_count, nth_prime, approximations and bounds for
diff --git a/TODO b/TODO
index 55b7ef0..e6c364e 100644
--- a/TODO
+++ b/TODO
@@ -45,3 +45,6 @@
   tinymt32, seed it using the system rand (multiple calls, just use 8-bits
   each), then use it to get 32-bit irands.  This would only be used if they
   didn't give us a RNG (so they don't care about strict crypto).
+
+- Perfect power from Dietzfelbinger algorithm 2.3.5 works a bit better.
+  Newton's method would be even better.
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 7156271..ad82c3f 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -5,7 +5,7 @@ use Carp qw/croak confess carp/;
 
 BEGIN {
   $Math::Prime::Util::AUTHORITY = 'cpan:DANAJ';
-  $Math::Prime::Util::VERSION = '0.17';
+  $Math::Prime::Util::VERSION = '0.18';
 }
 
 # parent is cleaner, and in the Perl 5.10.1 / 5.12.0 core, but not earlier.
@@ -22,7 +22,8 @@ our @EXPORT_OK = qw(
                      next_prime  prev_prime
                      prime_count prime_count_lower prime_count_upper prime_count_approx
                      nth_prime nth_prime_lower nth_prime_upper nth_prime_approx
-                     random_prime random_ndigit_prime random_nbit_prime random_maurer_prime
+                     random_prime random_ndigit_prime random_nbit_prime
+                     random_strong_prime random_maurer_prime
                      primorial pn_primorial
                      factor all_factors
                      moebius euler_phi jordan_totient
@@ -788,7 +789,7 @@ sub primes {
     _validate_positive_integer($bits, 2);
 
     if (!defined $_random_nbit_ranges[$bits]) {
-      my $bigbits = $bits > $_Config{'maxbits'};
+      my $bigbits = $bits > $_Config{'maxbits'}; # || ($] < 5.8 && $bits > 49);
       if ($bigbits) {
         if (!defined $Math::BigInt::VERSION) {
           eval { require Math::BigInt; Math::BigInt->import(try=>'GMP,Pari'); 1; }
@@ -821,6 +822,7 @@ sub primes {
     # could go even higher if we used is_provable_prime or looked for is_prime
     # returning 2.  This should be reasonably fast to ~128 bits with MPU::GMP.
     my $p0 = $_Config{'maxbits'};
+    $p0 = 32 if $] < 5.8 && $p0 > 32;
 
     return random_nbit_prime($k) if $k <= $p0;
 
@@ -938,6 +940,45 @@ sub primes {
     croak "Failure in random_maurer_prime, could not find a prime\n";
   } # End of random_maurer_prime
 
+  # Gordon's algorithm for generating a strong prime.
+  sub random_strong_prime {
+    my($t) = @_;
+    _validate_positive_integer($t, 128);
+
+    if (!defined $Math::BigInt::VERSION) {
+      eval { require Math::BigInt; Math::BigInt->import(try=>'GMP,Pari'); 1; }
+      or do { croak "Cannot load Math::BigInt"; };
+    }
+    my $irandf = _get_rand_func();
+
+    my $l   = (($t+1) >> 1) - 2;
+    my $lp  = int($t/2) - 20;
+    my $lpp = $l - 20;
+    while (1) {
+      my $qp  = random_nbit_prime($lp);
+      my $qpp = random_nbit_prime($lpp);
+      $qp  = Math::BigInt->new("$qp")  unless ref($qp)  eq 'Math::BigInt';
+      $qpp = Math::BigInt->new("$qpp") unless ref($qpp) eq 'Math::BigInt';
+      my ($il, $rem) = Math::BigInt->new(2)->bpow($l-1)->bsub(1)->bdiv(2*$qpp);
+      $il++ if $rem > 0;
+      my $iu = Math::BigInt->new(2)->bpow($l)->bsub(2)->bdiv(2*$qpp);
+      my $istart = $il + $irandf->($iu - $il);
+      for (my $i = $istart; $i <= $iu; $i++) {  # Search for q
+        my $q = 2 * $i * $qpp + 1;
+        next unless is_prob_prime($q);
+        my $pp = $qp->copy->bmodpow($q-2, $q)->bmul(2)->bmul($qp)->bsub(1);
+        my ($jl, $rem) = Math::BigInt->new(2)->bpow($t-1)->bsub($pp)->bdiv(2*$q*$qp);
+        $jl++ if $rem > 0;
+        my $ju = Math::BigInt->new(2)->bpow($t)->bsub(1)->bsub($pp)->bdiv(2*$q*$qp);
+        my $jstart = $jl + $irandf->($ju - $jl);
+        for (my $j = $jstart; $j <= $ju; $j++) {  # Search for p
+          my $p = $pp + 2 * $j * $q * $qp;
+          return $p if is_prob_prime($p);
+        }
+      }
+    }
+  }
+
 } # end of the random prime section
 
 sub primorial {
@@ -1744,7 +1785,7 @@ Math::Prime::Util - Utilities related to prime numbers, including fast sieves an
 
 =head1 VERSION
 
-Version 0.17
+Version 0.18
 
 
 =head1 SYNOPSIS
@@ -1847,6 +1888,7 @@ Version 0.17
   my $rand_prime = random_prime(100, 10000); # random prime within a range
   my $rand_prime = random_ndigit_prime(6);   # random 6-digit prime
   my $rand_prime = random_nbit_prime(128);   # random 128-bit prime
+  my $rand_prime = random_strong_prime(256); # random 256-bit strong prime
   my $rand_prime = random_maurer_prime(256); # random 256-bit provable prime
 
 
@@ -2442,6 +2484,35 @@ bit size.  For better performance with very large bit sizes, install
 L<Math::BigInt::GMP>.
 
 
+=head2 random_strong_prime
+
+  my $bigprime = random_strong_prime(512);
+
+Constructs an n-bit strong prime using Gordon's algorithm.  We consider a
+strong prime I<p> to be one where
+
+=over
+
+=item * I<p> is large.   This function uses 128 as a minimum.
+
+=item * I<p-1> has a large prime factor I<r>.
+
+=item * I<p+1> has a large prime factor I<s>
+
+=item * I<r-1> has a large prime factor I<t>
+
+=back
+
+Using a strong prime in cryptography guards against easy factoring with
+algorithms like Pollard's Rho.  Rivest and Silverman (1999) present a case
+that using strong primes is unnecessary, and most modern cryptographic systems
+agree.  First, the smoothness does not affect more modern factoring methods
+such as ECM.  Second, modern factoring methods like GNFS are far faster than
+either method so make the point moot.  Third, due to key size growth and
+advances in factoring and attacks, for practical purposes, using large random
+primes offer security equivalent to using strong primes.
+
+
 =head2 random_maurer_prime
 
   my $bigprime = random_maurer_prime(512);
diff --git a/t/81-bignum.t b/t/81-bignum.t
index f8fe390..7fcc956 100644
--- a/t/81-bignum.t
+++ b/t/81-bignum.t
@@ -69,7 +69,7 @@ plan tests =>  0
              + scalar(keys %factors)
              + scalar(keys %allfactors)
              + 2   # moebius, euler_phi
-             + 12  # random primes
+             + 15  # random primes
              + 0;
 
 # Using GMP makes these tests run about 2x faster on some machines
@@ -102,6 +102,7 @@ use Math::Prime::Util qw/
   random_prime
   random_ndigit_prime
   random_nbit_prime
+  random_strong_prime
   random_maurer_prime
 /;
 # TODO:  is_strong_lucas_pseudoprime
@@ -208,6 +209,11 @@ cmp_ok( $randprime, '>', 2**79, "random 80-bit prime isn't too small");
 cmp_ok( $randprime, '<', 2**80, "random 80-bit prime isn't too big");
 ok( is_prime($randprime), "random 80-bit prime is prime");
 
+$randprime = random_strong_prime(256);
+cmp_ok( $randprime, '>', 2**255, "random 256-bit strong prime isn't too small");
+cmp_ok( $randprime, '<', 2**256, "random 256-bit strong prime isn't too big");
+ok( is_prime($randprime), "random 80-bit strong prime is prime");
+
 SKIP: {
   skip "Your 64-bit Perl is broken, skipping maurer prime", 3 if $broken64;
   $randprime = random_maurer_prime(80);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list