[libmath-prime-util-perl] 07/29: Convenient primality proof random test
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:48:15 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 de8f5aa09db4c7b31667930b3ef251153a44ce8a
Author: Dana Jacobsen <dana at acm.org>
Date: Wed May 8 18:31:02 2013 -0700
Convenient primality proof random test
---
lib/Math/Prime/Util/PP.pm | 29 ++++++++++++++-----
xt/primality-proofs.pl | 72 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 7 deletions(-)
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index a1349f7..de34252 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1875,12 +1875,22 @@ sub primality_proof_bls75 {
my $B = $nm1->copy; # unfactored part
my @factors = (2);
croak "BLS75 error: n-1 not even" unless $nm1->is_even();
- while ($B->is_even) { $B /= 2; $A *= 2; }
- foreach my $f (3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79) {
- last if $f*$f > $B;
- if (($B % $f) == 0) {
- push @factors, $f;
- do { $B /= $f; $A *= $f; } while (($B % $f) == 0);
+ {
+ while ($B->is_even) { $B /= 2; $A *= 2; }
+ my $tlim = $_primes_small[-1];
+ if ($B > $tlim*$tlim) {
+ my @small_primes = @_primes_small[2 .. $#_primes_small];
+ foreach my $f (@small_primes) {
+ if (($B % $f) == 0) {
+ push @factors, $f;
+ do { $B /= $f; $A *= $f; } while (($B % $f) == 0);
+ last if $B <= $tlim*$tlim;
+ }
+ }
+ }
+ if ($B <= $tlim*$tlim) {
+ push @factors, factor($B);
+ $A *= $B; $B /= $B;
}
}
my @nstack;
@@ -1893,10 +1903,15 @@ sub primality_proof_bls75 {
} else {
push @nstack, $B;
}
+ my $using_theorem_7 = 0;
while (@nstack) {
my ($s,$r) = $B->copy->bdiv($A->copy->bmul(2));
my $fpart = ($A+1) * (2*$A*$A + ($r-1) * $A + 1);
last if $n < $fpart;
+ # Theorem 7....
+ # my $tlim = $_primes_small[-1];
+ # $fpart = ($A*$tlim+1) * (2*$A*$A + ($r-$tlim) * $A + 1);
+ # if ($n < $fpart) { $using_theorem_7 = 1; last; }
my $m = pop @nstack;
# Don't use bignum if it has gotten small enough.
@@ -1905,8 +1920,8 @@ sub primality_proof_bls75 {
my @ftry;
$_holf_r = 1;
foreach my $sub (@_fsublist) {
- last if scalar @ftry >= 2;
@ftry = $sub->($m);
+ last if scalar @ftry >= 2;
}
# If we couldn't find a factor, skip it.
next unless scalar @ftry > 1;
diff --git a/xt/primality-proofs.pl b/xt/primality-proofs.pl
new file mode 100644
index 0000000..580be8d
--- /dev/null
+++ b/xt/primality-proofs.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Math::Prime::Util ':all';
+use Math::BigInt lib=>"GMP";
+#use Crypt::Primes 'maurer';
+use Math::Pari qw/isprime/;
+use Crypt::Random 'makerandom';
+use Data::Dump 'dump';
+
+$|++;
+my $num = 71;
+my $size = 300;
+my $prime_method = 'pari'; # mpu, pari, or cpmaurer
+
+my @ns;
+print "Generate ";
+die "invalid size, must be > 4" unless $size > 4;
+foreach my $i (1..$num) {
+ my $bits = int(rand($size-4)) + 4;
+ my $n;
+
+ # How do we get random primes?
+ # MPU is the fastest, but it's our own code with identical primality tests.
+ # Pari + Crypt::Random works pretty well if you have them.
+ # Crypt::Primes::maurer will sometimes output composites (!!!).
+ if ($prime_method eq 'cpmaurer') {
+ $n = Crypt::Primes::maurer(Size=>$bits);
+ } elsif ($prime_method eq 'pari') {
+ do { $n = makerandom(Size=>$bits,Strength=>0); } while !isprime($n);
+ } elsif ($prime_method eq 'mpu') {
+ $n = random_nbit_prime($bits);
+ } else {
+ die "Unknown random prime generation method\n";
+ }
+
+ push @ns, Math::BigInt->new("$n");
+ # print a number corresponding to hundreds of bits
+ print int(3.322*length("$n")/100);
+}
+print "\n";
+
+my @certs;
+print "Prove ";
+foreach my $n (@ns) {
+ my ($isp,$cert) = is_provable_prime_with_cert($n);
+ die "$n is reported as $isp\n" unless $isp == 2;
+ push @certs, [$n, $cert];
+ print proof_mark($cert);
+}
+print "\n";
+
+print "Verify ";
+foreach my $certn (@certs) {
+ my $v = verify_prime($certn->[1]);
+ print proof_mark($certn->[1]);
+ next if $v;
+ print "\n\n$certn->[0] didn't verify!\n\n";
+ print dump($certn->[1]);
+ die;
+}
+print "\n";
+
+sub proof_mark {
+ my $cert = shift;
+ my $type = (scalar @$cert == 1) ? "bpsw" : $cert->[1];
+ if (!defined $type) { die "\nNo cert:\n\n", dump($cert); }
+ if ($type =~ /n-1/i) { return '1'; }
+ elsif ($type =~ /bpsw/i) { return '.'; }
+ elsif ($type =~ /ecpp|agkm/i) { return 'E'; }
+ return '?';
+}
--
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