[libmath-prime-util-perl] 19/29: More verbose/error output consistency for verify_prime. Tests.
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:48:17 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.27
in repository libmath-prime-util-perl.
commit 738a95316119849b6187465320e6c907b84a1004
Author: Dana Jacobsen <dana at acm.org>
Date: Fri May 17 12:30:20 2013 -0700
More verbose/error output consistency for verify_prime. Tests.
---
Makefile.PL | 1 +
lib/Math/Prime/Util.pm | 40 +++++++++-------
t/23-primality-proofs.t | 125 +++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 142 insertions(+), 24 deletions(-)
diff --git a/Makefile.PL b/Makefile.PL
index 02ee4b1..c4251a6 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -20,6 +20,7 @@ WriteMakefile1(
BUILD_REQUIRES=>{
'Test::More' => '0.45',
+ 'Test::Warn' => 0,
'bignum' => '0.22', # 'use bigint' in tests
},
PREREQ_PM => {
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index ce2c220..91802b5 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -1745,7 +1745,7 @@ sub verify_prime {
if ($method eq 'Pratt' || $method eq 'Lucas') {
# Based on Lucas primality test, which requires full n-1 factorization.
if (scalar @pdata != 2 || (ref($pdata[0]) ne 'ARRAY') || (ref($pdata[1]) eq 'ARRAY')) {
- print "verify_prime: incorrect Pratt format, must have factors and a value\n" if $verbose;
+ carp "verify_prime: incorrect Pratt format, must have factors and a value\n";
return 0;
}
my @factors = @{shift @pdata};
@@ -1776,7 +1776,7 @@ sub verify_prime {
$factors_seen{"$f"} = 1;
}
if ($B != 1) {
- print "verify_prime: n-1 not completely factored" if $verbose;
+ print "primality fail: n-1 not completely factored" if $verbose;
return 0;
}
@@ -1804,7 +1804,7 @@ sub verify_prime {
if ($method eq 'n-1') {
# BLS75 or generalized Pocklington
# http://www.ams.org/journals/mcom/1975-29-130/S0025-5718-1975-0384673-1/S0025-5718-1975-0384673-1.pdf
- # Pull of optional theorem 7 data
+ # Pull off optional theorem 7 data
my ($theorem, $t7_B1, $t7_B, $t7_a) = (5, undef, undef, undef);
if (scalar @pdata == 3 && ref($pdata[0]) eq 'ARRAY' && $pdata[0]->[0] =~ /^(B|T7|Theorem\s*7)$/i) {
$theorem = 7;
@@ -1812,13 +1812,13 @@ sub verify_prime {
$t7_B = Math::BigInt->new("$t7_B");
}
if (scalar @pdata != 2 || (ref($pdata[0]) ne 'ARRAY') || (ref($pdata[1]) ne 'ARRAY')) {
- warn "verify_prime: incorrect n-1 format, must have factors and a values\n";
+ carp "verify_prime: incorrect n-1 format, must have factors and a values\n";
return 0;
}
my @factors = @{shift @pdata};
my @as = @{shift @pdata};
if ($#factors != $#as) {
- warn "verify_prime: incorrect n-1 format, must have a value for each factor\n";
+ carp "verify_prime: incorrect n-1 format, must have a value for each factor\n";
return 0;
}
@@ -1940,24 +1940,24 @@ sub verify_prime {
# Ux,Uy should be 600992528322000913770, 206075883056439332684
# Vx,Vy should be 0, 1
if (scalar @pdata < 1) {
- warn "verify_prime: incorrect AGKM format\n";
+ carp "verify_prime: incorrect AGKM format\n";
return 0;
}
my ($ni, $a, $b, $m, $P);
my ($qval, $q) = ($n, $n);
foreach my $block (@pdata) {
if (ref($block) ne 'ARRAY' || scalar @$block != 6) {
- warn "verify_prime: incorrect AGKM block format\n";
+ carp "verify_prime: incorrect AGKM block format\n";
return 0;
}
if (Math::BigInt->new("$block->[0]") != Math::BigInt->new("$q")) {
- warn "verify_prime: incorrect AGKM block format: block n != q\n";
+ carp "verify_prime: incorrect AGKM block format: block n != q\n";
return 0;
}
($ni, $a, $b, $m, $qval, $P) = @$block;
$q = ref($qval) eq 'ARRAY' ? $qval->[0] : $qval;
if (ref($P) ne 'ARRAY' || scalar @$P != 2) {
- warn "verify_prime: incorrect AGKM block point format\n";
+ carp "verify_prime: incorrect AGKM block point format\n";
return 0;
}
my($Px, $Py) = @$P;
@@ -1969,16 +1969,16 @@ sub verify_prime {
$Px = $n->copy->bzero->badd("$Px") unless ref($Px) eq 'Math::BigInt';
$Py = $n->copy->bzero->badd("$Py") unless ref($Py) eq 'Math::BigInt';
if (Math::BigInt::bgcd($ni, 6) != 1) {
- warn "verify_prime: AGKM block n '$ni' is divisible by 2 or 3\n";
+ print "primality fail: AGKM block n '$ni' is divisible by 2 or 3\n" if $verbose;
return 0;
}
my $c = $a*$a*$a * 4 + $b*$b * 27;
if (Math::BigInt::bgcd($c, $ni) != 1) {
- warn "verify_prime: AGKM block gcd 4a^3+27b^2,n incorrect\n";
+ print "primality fail: AGKM block gcd 4a^3+27b^2,n incorrect\n" if $verbose;
return 0;
}
if ($q <= $ni->copy->broot(4)->badd(1)->bpow(2)) {
- warn "verify_prime: AGKM block q is too small\n";
+ print "primality fail: AGKM block q is too small\n" if $verbose;
return 0;
}
# Final check, check that we've got a bound above and below (Hasse)
@@ -1990,13 +1990,13 @@ sub verify_prime {
# Compute U = (m/q)P, check U != point at infinity
$ECP->mul( $m->copy->bdiv($q)->as_int );
if ($ECP->is_infinity) {
- warn "verify_prime: AGKM point does not multiply correctly.\n";
+ print "primality fail: AGKM point does not multiply correctly (1).\n" if $verbose;
return 0;
}
# Compute V = qU, check V = point at infinity
$ECP->mul( $q );
if (! $ECP->is_infinity) {
- print "verify_prime: AGKM point does not multiply correctly.\n" if $verbose;
+ print "primality fail: AGKM point does not multiply correctly (2).\n" if $verbose;
return 0;
}
}
@@ -2007,7 +2007,7 @@ sub verify_prime {
return 1;
}
- print "verify_prime: Unknown method: '$method'.\n" if $verbose;
+ carp "verify_prime: Unknown method: '$method'.\n";
return 0;
}
@@ -2894,8 +2894,14 @@ array reference if the result is not 2 (definitely prime).
Given an array representing a certificate of primality, returns either 0 (not
verified), or 1 (verified). The computations are all done using pure Perl
-Math::BigInt and should not be time consuming (the Pari or GMP backends will
-help with large inputs).
+Math::BigInt. Lucas/Pratt and n-1 proofs are not time consuming, but ECPP
+proofs can be rather slow, especially without the GMP or Pari backends.
+
+If the certificate is malformed, the routine will carp a warning in addition
+to returning 0. If the C<verbose> option is set (see L</prime_set_config>)
+then if the validation fails, the reason for the failure is printed in
+addition to returning 0. If the C<verbose> option is set to 2 or higher, then
+a message indicating success and the certificate type is also printed.
A certificate is an array holding an C<n-cert>. An C<n-cert> is one of:
diff --git a/t/23-primality-proofs.t b/t/23-primality-proofs.t
index 470039c..d525fbe 100644
--- a/t/23-primality-proofs.t
+++ b/t/23-primality-proofs.t
@@ -3,6 +3,7 @@ use strict;
use warnings;
use Test::More;
+use Test::Warn;
use Math::Prime::Util qw/is_prime is_provable_prime is_provable_prime_with_cert
prime_certificate verify_prime
prime_get_config
@@ -30,10 +31,14 @@ my @plist = qw/20907001 809120722675364249 677826928624294778921
@plist;
plan tests => 0
- + 2 # is_provable_prime
+ + 2 # is_provable_prime
+ 6 * scalar(@plist)
- + 6 # hand-done proofs
- + 17 # verification failures
+ + 6 # hand-done proofs
+ + 28 # borked up certificates generating warnings
+ + 6 # verification failures (tiny/BPSW)
+ + 8 # verification failures (Lucas/Pratt)
+ + 12 # verification failures (n-1)
+ + 7 # verification failures (ECPP)
+ 0;
is( is_provable_prime(871139809), 0, "871139809 is composite" );
@@ -107,16 +112,79 @@ SKIP: {
}
# Failures for verify_prime
+
+# First, let's get the borked up formats, which is should warn about.
+{
+ my $result;
+ warning_like { $result = verify_prime([1490266103, 'INVALID', 1, 2, 3]) }
+ { carped => qr/^verify_prime: / },
+ "warning for unknown method";
+ is( $result, 0, " ...and returns 0" );
+
+ warning_like { $result = verify_prime([1490266103, 'Pratt', 1, 2, 3]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid Lucas/Pratt";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'Pratt', 1, [2], 3]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid Lucas/Pratt";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'Pratt', [1], 2, 3]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid Lucas/Pratt";
+ is( $result, 0, " ...and returns 0" );
+
+ warning_like { $result = verify_prime([1490266103, 'n-1', 1, 2, 3]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid n-1 (too many arguments)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'n-1', 1, 2]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid n-1 (non-array f,a)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'n-1', [1], 2]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid n-1 (non-array a)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'n-1', [2, 13, 19, 1597, 1889], [2, 2, 2, 2]]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid n-1 (too few a values)";
+ is( $result, 0, " ...and returns 0" );
+
+ warning_like { $result = verify_prime([1490266103, 'ECPP']) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (no n-certs)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'ECPP', 15]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (non-array block)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'ECPP', [15,16,17]]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (wrong size block)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'ECPP', [694361, 694358, 0, 695162, 26737, [348008, 638945]]]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (block n != q)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'ECPP', [1490266103, 1442956066, 1025050760, 1490277784, 2780369, 531078754]]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (block point wrong format)";
+ is( $result, 0, " ...and returns 0" );
+ warning_like { $result = verify_prime([1490266103, 'ECPP', [1490266103, 1442956066, 1025050760, 1490277784, 2780369, [531078754, 0, 195830554]]]) }
+ { carped => qr/^verify_prime: / },
+ "warning for invalid ECPP (block point wrong format)";
+ is( $result, 0, " ...and returns 0" );
+}
+
is( verify_prime([]), 0, "verify null is composite" );
is( verify_prime([2]), 1, "verify [2] is prime" );
is( verify_prime([9]), 0, "verify [9] is composite" );
is( verify_prime([14]), 0, "verify [14] is composite" );
is( verify_prime(['28446744073709551615']), 0, "verify BPSW with n > 2^64 fails" );
is( verify_prime([871139809]), 0, "verify BPSW with composite fails" );
-is( verify_prime([1490266103, 'INVALID', 1, 2, 3]), 0, "unknown method" );
-is( verify_prime([1490266103, 'Pratt', 1, 2, 3]), 0, "Pratt with wrong count" );
-is( verify_prime([1490266103, 'Pratt', 1, [2]]), 0, "Pratt with non-array arguments" );
-is( verify_prime([1490266103, 'Pratt', [1], [2]]), 0, "Pratt with non-array arguments" );
+
+is( verify_prime([1490266103, 'Pratt', [2,13,19,1597,1889], 5]), 1, "Lucas/Pratt proper" );
is( verify_prime([1490266103, 'Pratt', [4,13,19,1597,1889], 5]), 0, "Pratt with non-prime factors" );
is( verify_prime([1490266103, 'Pratt', [[4],13,19,1597,1889], 5]), 0, "Pratt with non-prime factors" );
is( verify_prime([1490266103, 'Pratt', [2,13,29,1597,1889], 5]), 0, "Pratt with wrong factors" );
@@ -124,3 +192,46 @@ is( verify_prime([1490266103, 'Pratt', [2,13,19,1597], 5]), 0, "Pratt with not e
is( verify_prime([1490266103, 'Pratt', [2,13,19,1597,1889], 1490266103]), 0, "Pratt with coprime a" );
is( verify_prime([185156263, 'Pratt', [2,3,3,10286459], 2]), 0, "Pratt with non-psp a" );
is( verify_prime([1490266103, 'Pratt', [2,13,19,1597,1889], 3]), 0, "Pratt with a not valid for all f" );
+
+is( verify_prime([1490266103, 'n-1', [2, 13, 19, 1597, 1889], [5, 2, 2, 2, 2]]), 1, "n-1 proper" );
+is( verify_prime([1490266103, 'n-1', [2, 23, 19, 1597, 1889], [5, 2, 2, 2, 2]]), 0, "n-1 with wrong factors" );
+is( verify_prime([1490266103, 'n-1', [13, 19, 1597, 1889], [2, 2, 2, 2]]), 0, "n-1 without 2 as a factor" );
+is( verify_prime([1490266103, 'n-1', [2, 13, 1889, 30343], [5, 2, 2, 2]]), 0, "n-1 with a non-prime factor" );
+is( verify_prime([1490266103, 'n-1', [2, 13, 1889, [30343]], [5, 2, 2, 2]]), 0, "n-1 with a non-prime array factor" );
+# I don't know how to make F and R (A and B) to not be coprime
+is( verify_prime(['9848131514359', 'n-1', ["B", 20000, 890588851, 2], [2, 3, 19, 97], [3, 5, 2, 2]]), 1, "n-1 T7 proper" );
+is( verify_prime(['9848131514359', 'n-1', ["B", 20000, 890588951, 2], [2, 3, 19, 97], [3, 5, 2, 2]]), 0, "n-1 T7 with misfactor" );
+is( verify_prime(['9848131514359', 'n-1', ["B", 0, 890588851, 2], [2, 3, 19, 97], [3, 5, 2, 2]]), 0, "n-1 T7 with B < 1" );
+is( verify_prime(['9848131514359', 'n-1', ["B", 20000, 16921188169, 2], [2, 3, 97], [3, 5, 2]]), 0, "n-1 T7 with wrong B" );
+is( verify_prime([1490266103, 'n-1', [2, 13], [5, 2]]), 0, "n-1 without enough factors" );
+is( verify_prime([914144252447488195, 'n-1', [2, 3, 11, 17, 1531], [2, 2, 2, 2, 2]]), 0, "n-1 with bad BLS75 r/s" );
+is( verify_prime([1490266103, 'n-1', [2, 13, 19, 1597, 1889], [3, 2, 2, 2, 2]]), 0, "n-1 with bad a value" );
+
+is( verify_prime([1490266103, "ECPP",
+ [1490266103, 1442956066, 1025050760, 1490277784, 2780369, [531078754, 195830554]],
+ [2780369, 2780360, 0, 2777444, 694361, [2481811, 1317449]],
+ [694361, 694358, 0, 695162, 26737, [348008, 638945]]]),
+ 1, "ECPP proper" );
+is( verify_prime([1490266103, "ECPP",
+ [1490266103, 1442956066, 1025050760, 1490277784, 5560738, [531078754, 195830554]],
+ [5560738, 2780360, 0, 2777444, 694361, [2481811, 1317449]]]),
+ 0, "ECPP q is divisible by 2" );
+is( verify_prime([74468183, "ECPP",
+ [74468183, 89, 1629, 74475075, 993001, [47943960, 8832604]],
+ [993001, 0, 992984, 994825, 3061, [407531, 231114]]]),
+ 0, "ECPP a/b invalid" );
+is( verify_prime([1490266103, "ECPP",
+ [1490266103, 1442956066, 1025050760, 1490277784, 536, [531078754, 195830554]],
+ [536, 2780360, 0, 2777444, 694361, [2481811, 1317449]]]),
+ 0, "ECPP q is too small" );
+is( verify_prime([694361, "ECPP",
+ [694361, 694358, 0, 30, 26737, [264399, 59977]]]),
+ 0, "ECPP multiplication wrong (infinity)" );
+is( verify_prime([694361, "ECPP",
+ [694361, 694358, 0, 695161, 26737, [264399, 59977]]]),
+ 0, "ECPP multiplication wrong (not infinity)" );
+is( verify_prime([1490266103, "ECPP",
+ [1490266103, 1442956066, 1025050760, 1490277784, 2780369, [531078754, 195830554]],
+ [2780369, 2780360, 0, 2777444, 694361, [2481811, 1317449]],
+ [694361, 694358, 0, 695162, [26737, "n-1", [2],[2]], [348008, 638945]]]),
+ 0, "ECPP non-prime last q" );
--
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