[libmath-prime-util-perl] 19/35: Improve test coverage

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


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

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

commit 7bca5883d64ed00ff2656a397a3920e02408ed37
Author: Dana Jacobsen <dana at acm.org>
Date:   Tue Oct 29 20:52:51 2013 -0700

    Improve test coverage
---
 lib/Math/Prime/Util/PP.pm | 35 +++++++++++------------------------
 primality.c               |  5 -----
 t/16-randomprime.t        | 36 +++++++++++++++++++++++++++++++++---
 t/17-pseudoprime.t        | 16 ++++++++++++++++
 t/23-primality-proofs.t   | 34 ++++++++++++++++++++++++++++++++++
 t/32-iterators.t          | 26 ++++++++++++++++++++------
 t/80-pp.t                 | 40 ++++++++++++++++++++++++++++++++++------
 t/81-bignum.t             |  9 +++++++++
 8 files changed, 157 insertions(+), 44 deletions(-)

diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index f6de4a6..65ac6d6 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -733,11 +733,6 @@ sub _gcd_ui {
   $x;
 }
 
-sub _lcm_ui {
-  my($x, $y) = @_;
-  return (abs($x) / _gcd_ui($x, $y)) * abs($y);
-}
-
 sub _is_perfect_power {
   my $n = shift;
   return 0 if $n <= 3 || $n != int($n);
@@ -763,14 +758,6 @@ sub _order {
   return $lim+1;
 }
 
-# same result as:  int($n->blog(2)->floor->bstr)
-sub _log2 {
-  my $n = shift;
-  my $log2n = 0;
-  $log2n++ while ($n >>= 1);
-  $log2n;
-}
-
 
 
 sub is_pseudoprime {
@@ -1246,17 +1233,17 @@ sub _poly_new {
   return \@poly;
 }
 
-sub _poly_print {
-  my($poly) = @_;
-  carp "poly has null top degree" if $#$poly > 0 && !$poly->[-1];
-  foreach my $d (reverse 1 .. $#$poly) {
-    my $coef = $poly->[$d];
-    print "", ($coef != 1) ? $coef : "", ($d > 1) ? "x^$d" : "x", " + "
-      if $coef;
-  }
-  my $p0 = $poly->[0] || 0;
-  print "$p0\n";
-}
+#sub _poly_print {
+#  my($poly) = @_;
+#  carp "poly has null top degree" if $#$poly > 0 && !$poly->[-1];
+#  foreach my $d (reverse 1 .. $#$poly) {
+#    my $coef = $poly->[$d];
+#    print "", ($coef != 1) ? $coef : "", ($d > 1) ? "x^$d" : "x", " + "
+#      if $coef;
+#  }
+#  my $p0 = $poly->[0] || 0;
+#  print "$p0\n";
+#}
 
 sub _poly_mod_mul {
   my($px, $py, $r, $n) = @_;
diff --git a/primality.c b/primality.c
index 2711e3a..80f6252 100644
--- a/primality.c
+++ b/primality.c
@@ -11,11 +11,6 @@
 
 /* Primality related functions, including Montgomery math */
 
-/* TODO:
- *      - Convert F-U test to Montgomery
- *      - Convert Lucas tests to Montgomery
- */
-
 static const UV mr_bases_const2[1] = {2};
 
 /******************************************************************************
diff --git a/t/16-randomprime.t b/t/16-randomprime.t
index 0c577d2..7624c8a 100644
--- a/t/16-randomprime.t
+++ b/t/16-randomprime.t
@@ -7,8 +7,8 @@ use Test::More;
 #use Math::Random::MT::Auto qw/rand/;
 #sub rand { return 0.5; }
 use Math::Prime::Util qw/random_prime random_ndigit_prime random_nbit_prime
-                         random_maurer_prime is_prime
-                         prime_set_config/;
+                         random_maurer_prime random_proven_prime
+                         is_prime prime_set_config/;
 
 my $use64 = Math::Prime::Util::prime_get_config->{'maxbits'} > 32;
 my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
@@ -64,7 +64,8 @@ plan tests => 13+3+3+3
               + (2 * scalar (keys %ranges))
               + (2 * scalar @random_to)
               + (1 * scalar @random_ndigit_tests)
-              + (2 * scalar @random_nbit_tests)
+              + (3 * scalar @random_nbit_tests)
+              + 3 + 4
               + 0;
 
 my $infinity = 20**20**20;
@@ -163,6 +164,7 @@ SKIP: {
 foreach my $bits ( @random_nbit_tests ) {
   check_bits( random_nbit_prime($bits), $bits, "nbit" );
   check_bits( random_maurer_prime($bits), $bits, "Maurer" );
+  check_bits( random_proven_prime($bits), $bits, "proven" );
 }
 
 sub check_bits {
@@ -173,3 +175,31 @@ sub check_bits {
   ok ( $n >= $min && $n <= $max && is_prime($n),
        "$bits-bit random $what prime is in range and prime");
 }
+prime_set_config(nobigint=>0);
+
+# Now check with custom irand
+{
+  my $seed = 1;
+  sub mysrand { $seed = $_[0]; }
+  #sub irand { $seed = (1103515245*$seed + 12345) % 4294967296; }
+  sub irand { $seed = ( 16807 * $seed ) % 2147483647; }
+  prime_set_config( irand => \&irand );
+}
+is( random_nbit_prime(10), 571, "random 10-bit prime with custom irand" );
+is( random_nbit_prime(20), 558769, "random 20-bit prime with custom irand" );
+is( random_ndigit_prime(9), 756473437, "random 9-digit with custom irand" );
+
+{
+  my $n = random_nbit_prime(80);
+  is( ref($n), 'Math::BigInt', "random 80-bit prime returns a BigInt" );
+  ok(    $n >= Math::BigInt->new(2)->bpow(79)
+      && $n <= Math::BigInt->new(2)->bpow(80),
+      "random 80-bit prime is in range" );
+}
+{
+  my $n = random_ndigit_prime(30);
+  is( ref($n), 'Math::BigInt', "random 30-digit prime returns a BigInt" );
+  ok(    $n >= Math::BigInt->new(10)->bpow(29)
+      && $n <= Math::BigInt->new(10)->bpow(30),
+      "random 30-digit prime is in range" );
+}
diff --git a/t/17-pseudoprime.t b/t/17-pseudoprime.t
index 93dffe5..0cc9456 100644
--- a/t/17-pseudoprime.t
+++ b/t/17-pseudoprime.t
@@ -73,6 +73,17 @@ my %pseudoprimes = (
  aeslucas1  => [ qw/989 3239 5777 10469 10877 27971 29681 30739 31631 39059 72389 73919 75077 100127 113573 125249 137549 137801 153931 154697 155819/ ],
  aeslucas2  => [ qw/3239 4531 5777 10877 12209 21899 31631 31831 32129 34481 36079 37949 47849 50959 51641 62479 73919 75077 97109 100127 108679 113573 116899 154697 161027/ ],
 );
+
+if ($use64) {
+  push @{$pseudoprimes{psp3}}, 4398117272641;
+  push @{$pseudoprimes{3}}, 1099558795087;
+  push @{$pseudoprimes{lucas}}, 2199055761527;
+  push @{$pseudoprimes{slucas}}, 12598021314449;
+  push @{$pseudoprimes{eslucas}}, 10099386070337;
+  push @{$pseudoprimes{aeslucas1}}, 10071551814917;
+  push @{$pseudoprimes{aeslucas2}}, 34372519409;
+}
+
 my $num_pseudoprimes = 0;
 foreach my $ppref (values %pseudoprimes) {
   $num_pseudoprimes += scalar @$ppref;
@@ -105,6 +116,7 @@ plan tests => 0 + 3
                 + scalar @small_lucas_trials
                 + scalar(keys %lucas_sequences)
                 + 1  # frob-underwood
+                + 2*$use64  # frob-underwood
                 + 1*$extra;
 
 ok(!eval { is_strong_pseudoprime(2047); }, "MR with no base fails");
@@ -216,3 +228,7 @@ while (my($params, $expect) = each (%lucas_sequences)) {
   }
   is($fufail, 0, "is_frobenius_underwood_pseudoprime matches is_prime");
 }
+if ($use64) {
+  is( is_frobenius_underwood_pseudoprime(2727480595375747), 1, "frobenius with 52-bit prime" );
+  is( is_frobenius_underwood_pseudoprime(10099386070337), 0, "frobenius with 44-bit lucas pseudoprime" );
+}
diff --git a/t/23-primality-proofs.t b/t/23-primality-proofs.t
index c4b2a54..9915d3a 100644
--- a/t/23-primality-proofs.t
+++ b/t/23-primality-proofs.t
@@ -46,6 +46,7 @@ plan tests => 0
             + 8  # verification failures (Lucas/Pratt)
             + 11 # verification failures (n-1)
             + 7  # verification failures (ECPP)
+            + 3  # Verious other types
             + 0;
 
 is( is_provable_prime(871139809), 0, "871139809 is composite" );
@@ -259,3 +260,36 @@ is( verify_prime([1490266103, "ECPP",
                  [2780369, 2780360, 0, 2777444, 694361, [2481811, 1317449]],
                  [694361, 694358, 0, 695162, [26737, "n-1", [2],[2]], [348008, 638945]]]),
                  0, "ECPP non-prime last q" );
+
+my $header = "[MPU - Primality Certificate]\nVersion 1.0\nProof for:";
+{
+  my $cert = join "\n", $header,
+                       "N 2297612322987260054928384863",
+                       "Type Pocklington",
+                       "N  2297612322987260054928384863",
+                       "Q  16501461106821092981",
+                       "A  5";
+  is( verify_prime($cert), 1, "Verify Pocklington");
+}
+{
+  my $cert = join "\n", $header,
+                       "N 5659942549665396263282978117",
+                       "Type BLS15",
+                       "N  5659942549665396263282978117",
+                       "Q  42941814754495493",
+                       "LP 2",
+                       "LQ 3";
+  is( verify_prime($cert), 1, "Verify BLS15");
+}
+{
+  my $cert = join "\n", $header,
+                       "N 43055019307158602560279",
+                       "Type ECPP3",
+                       "N 43055019307158602560279",
+                       "S 106563369",
+                       "R 404032076977387",
+                       "A 0",
+                       "B 4",
+                       "T 1";
+  is( verify_prime($cert), 1, "Verify ECPP3");
+}
diff --git a/t/32-iterators.t b/t/32-iterators.t
index c16440f..ec7779c 100644
--- a/t/32-iterators.t
+++ b/t/32-iterators.t
@@ -6,15 +6,19 @@ use Test::More;
 use Math::Prime::Util qw/primes prev_prime next_prime
                          forprimes prime_iterator prime_iterator_object/;
 use Math::BigInt try => "GMP,Pari";
+use Math::BigFloat;
 
 my $use64 = Math::Prime::Util::prime_get_config->{'maxbits'} > 32;
 
-plan tests => 8 + 5
-            + 12
-            + 3 + 7
-            + 2
-            + 3 + 7
-            + 25
+plan tests => 8        # forprimes errors
+            + 12 + 5   # forprimes simple
+            + 3        # iterator errors
+            + 7        # iterator simple
+            + 2        # forprimes/iterator nesting
+            + 2        # forprimes BigInt/BigFloat
+            + 3        # oo iterator errors
+            + 7        # oo iterator simple
+            + 25       # oo iterator methods
             + 0;
 
 ok(!eval { forprimes { 1 } undef; },   "forprimes undef");
@@ -108,6 +112,16 @@ ok(!eval { prime_iterator(4.5); }, "iterator 4.5");
   is_deeply( [@t], [qw/23 29 31 29 31 37 31 37 41 37 41 43 47 53 59 61 59 61 67 71 73 79 73 79 83 79 83 89/], "triple nested iterator" );
 }
 
+# With BigInt and BigFloat objects
+{ my @t;
+  forprimes { push @t, $_ } Math::BigInt->new("5"), Math::BigInt->new("11");
+  is_deeply( [@t], [5,7,11], "forprimes with BigInt range" );
+}
+{ my @t;
+  forprimes { push @t, $_ } Math::BigFloat->new("5"), Math::BigFloat->new("11");
+  is_deeply( [@t], [5,7,11], "forprimes with BigFloat range" );
+}
+
 # Test new object iterator
 ok(!eval { prime_iterator_object(-2); }, "iterator -2");
 ok(!eval { prime_iterator_object("abc"); }, "iterator abc");
diff --git a/t/80-pp.t b/t/80-pp.t
index e4b2c8a..788c532 100644
--- a/t/80-pp.t
+++ b/t/80-pp.t
@@ -55,7 +55,13 @@ my %pseudoprimes = (
   37 => [ qw/9 451 469 589 685 817 1333 3781 8905 9271 18631 19517 20591 25327 34237 45551 46981 47587 48133 59563 61337 68101 68251 73633 79381 79501 83333 84151 96727/ ],
   61 => [ qw/217 341 1261 2701 3661 6541 6697 7613 13213 16213 22177 23653 23959 31417 50117 61777 63139 67721 76301 77421 79381 80041/ ],
   73 => [ qw/205 259 533 1441 1921 2665 3439 5257 15457 23281 24617 26797 27787 28939 34219 39481 44671 45629 64681 67069 76429 79501 93521/ ],
- lucas      => [ qw/5459 5777 10877 16109 18971 22499 24569 25199 40309 58519 75077 97439/ ],
+ psp2       => [ qw/341 561 645 1105 1387 1729 1905 2047 2465 2701 2821 3277 4033 4369 4371 4681 5461 6601 7957 8321 8481 8911 10261 10585/ ],
+ psp3       => [ qw/91 121 286 671 703 949 1105 1541 1729 1891 2465 2665 2701 2821 3281 3367 3751 4961 5551 6601 7381 8401 8911 10585 11011/ ],
+ lucas      => [ qw/9179 10877 11419 11663 13919 14839 16109 16211 18407 18971 19043/ ],
+ slucas     => [ qw/5459 5777 10877 16109 18971 22499 24569 25199 40309 58519 75077/ ],
+ eslucas    => [ qw/989 3239 5777 10877 27971 29681 30739 31631 39059 72389 73919 75077 100127/ ],
+ aeslucas1  => [ qw/989 3239 5777 10469 10877 27971 29681 30739 31631 39059 72389 73919 75077 100127/ ],
+ aeslucas2  => [ qw/3239 4531 5777 10877 12209 21899 31631 31831 32129 34481 36079 37949 47849 50959/ ],
 );
 # Test a pseudoprime larger than 2^32.
 push @{$pseudoprimes{2}}, 75792980677 if $use64;
@@ -251,8 +257,8 @@ plan tests => 2 +
               1 + 1 +    # factor
               10 + 8*3 + # factoring subs
               10 +       # AKS
-              2 +        # Lucas and BLS75 primality proofs
-              3 +        # M-R and Lucas on bigint
+              3 +        # Lucas and BLS75 primality proofs
+              4 +        # M-R and Lucas on bigint
               13 +       # Misc util.pm functions
               scalar(keys %ipp) +
               1;
@@ -279,8 +285,13 @@ require_ok 'Math::Prime::Util::PrimalityProving';
     *next_prime     = \&Math::Prime::Util::PP::next_prime;
     *prev_prime     = \&Math::Prime::Util::PP::prev_prime;
 
-    *is_strong_lucas_pseudoprime = \&Math::Prime::Util::PP::is_strong_lucas_pseudoprime;
+    *is_pseudoprime = \&Math::Prime::Util::PP::is_pseudoprime;
     *miller_rabin   = \&Math::Prime::Util::PP::miller_rabin;
+    *is_lucas_pseudoprime = \&Math::Prime::Util::PP::is_lucas_pseudoprime;
+    *is_strong_lucas_pseudoprime = \&Math::Prime::Util::PP::is_strong_lucas_pseudoprime;
+    *is_extra_strong_lucas_pseudoprime = \&Math::Prime::Util::PP::is_extra_strong_lucas_pseudoprime;
+    *is_almost_extra_strong_lucas_pseudoprime = \&Math::Prime::Util::PP::is_almost_extra_strong_lucas_pseudoprime;
+    *is_frobenius_underwood_pseudoprime = \&Math::Prime::Util::PP::is_frobenius_underwood_pseudoprime;
     *is_aks_prime   = \&Math::Prime::Util::PP::is_aks_prime;
 
     *factor         = \&Math::Prime::Util::PP::factor;
@@ -396,8 +407,21 @@ while (my($base, $ppref) = each (%pseudoprimes)) {
   my $npseudos = scalar @$ppref;
   my @expmr = map { 1 } @$ppref;
   my @gotmr;
-  if ($base eq 'lucas') { @gotmr = map { is_strong_lucas_pseudoprime($_) } @$ppref; }
-  else                  { @gotmr = map { miller_rabin($_, $base) } @$ppref;         }
+  if ($base =~ /^psp(\d+)/) {
+     my $pbase = $1;
+     @gotmr = map { is_pseudoprime($_, $pbase) } @$ppref;
+  } elsif ($base =~ /^aeslucas(\d+)/) {
+     my $inc = $1;
+     @gotmr = map { is_almost_extra_strong_lucas_pseudoprime($_, $inc) } @$ppref;
+  } elsif ($base eq 'eslucas') {
+     @gotmr = map { is_extra_strong_lucas_pseudoprime($_) } @$ppref;
+  } elsif ($base eq 'slucas') {
+     @gotmr = map { is_strong_lucas_pseudoprime($_) } @$ppref;
+  } elsif ($base eq 'lucas') {
+     @gotmr = map { is_lucas_pseudoprime($_) } @$ppref;
+  } else {
+     @gotmr = map { miller_rabin($_, $base) } @$ppref;
+  }
   is_deeply(\@gotmr, \@expmr, "$npseudos pseudoprimes (base $base)");
 }
 
@@ -575,12 +599,16 @@ is_deeply( [Math::Prime::Util::PrimalityProving::primality_proof_lucas(100003)],
 is_deeply( [Math::Prime::Util::PrimalityProving::primality_proof_bls75(1490266103)],
            [2, "[MPU - Primality Certificate]\nVersion 1.0\n\nProof for:\nN 1490266103\n\nType BLS5\nN 1490266103\nQ[1] 13\nQ[2] 19\nQ[3] 1597\nQ[4] 1889\nA[0] 5\n----\n"],
            "primality_proof_bls75(1490266103)" );
+is_deeply( [Math::Prime::Util::PrimalityProving::primality_proof_bls75(27141057803)],
+           [2, "[MPU - Primality Certificate]\nVersion 1.0\n\nProof for:\nN 27141057803\n\nType BLS5\nN 27141057803\nQ[1] 47533\nQ[2] 285497\n----\n"],
+           "primality_proof_bls75(27141057803)" );
 
 {
   my $n = Math::BigInt->new("168790877523676911809192454171451");
   is( miller_rabin( $n, 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47), 1, "168790877523676911809192454171451 looks prime with bases 2..52" );
   is( miller_rabin( $n, 53), 0, "168790877523676911809192454171451 found composite with base 53" );
   is ( is_strong_lucas_pseudoprime($n), 0, "168790877523676911809192454171451 is not a strong Lucas pseudoprime" );
+  is ( is_frobenius_underwood_pseudoprime($n), 0, "168790877523676911809192454171451 is not a Frobenius pseudoprime" );
 }
 
 {
diff --git a/t/81-bignum.t b/t/81-bignum.t
index 8fdd9c5..3dd376f 100644
--- a/t/81-bignum.t
+++ b/t/81-bignum.t
@@ -78,6 +78,7 @@ plan tests =>  0
              + 7   # moebius, euler_phi, jordan totient, divsum, znorder
              + 2   # liouville
              + 15  # random primes
+             + 2   # miller-rabin random
              + 0;
 
 # Using GMP makes these tests run about 2x faster on some machines
@@ -118,6 +119,7 @@ use Math::Prime::Util qw/
   random_nbit_prime
   random_strong_prime
   random_maurer_prime
+  miller_rabin_random
   verify_prime
 /;
 # TODO:  is_strong_lucas_pseudoprime
@@ -270,6 +272,13 @@ SKIP: {
 
 ###############################################################################
 
+$randprime = random_nbit_prime(80);
+is( miller_rabin_random( $randprime, 20 ), 1, "80-bit prime passes Miller-Rabin with 20 random bases" );
+$randprime += 2 while is_prime($randprime);
+is( miller_rabin_random( $randprime, 40 ), 0, "80-bit composite fails Miller-Rabin with 40 random bases" );
+
+###############################################################################
+
 
 sub check_pcbounds {
   my ($n, $expn, $percent, $percentrh) = @_;

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