[libmath-prime-util-perl] 148/181: znlog tests and PP placeholder
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:51:16 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.
commit c62ac0deb6f51737537f0cc0a7624ff1b85232bf
Author: Dana Jacobsen <dana at acm.org>
Date: Thu Jan 9 00:34:07 2014 -0800
znlog tests and PP placeholder
---
lib/Math/Prime/Util.pm | 16 ++++++++++++++++
lib/Math/Prime/Util/PP.pm | 16 ++++++++++++++++
t/19-moebius.t | 23 ++++++++++++++++++++++-
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index b263fbb..e10e6bc 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -118,6 +118,7 @@ BEGIN {
*divisor_sum = \&Math::Prime::Util::_generic_divisor_sum;
*znorder = \&Math::Prime::Util::PP::znorder;
*znprimroot = \&Math::Prime::Util::_generic_znprimroot;
+ *znlog = \&Math::Prime::Util::PP::znlog;
*legendre_phi = \&Math::Prime::Util::PP::legendre_phi;
*gcd = \&Math::Prime::Util::PP::gcd;
*lcm = \&Math::Prime::Util::PP::lcm;
@@ -1091,6 +1092,12 @@ sub primes {
}
print "*" if $verbose > 2;
+ # We could pick a random generator by doing:
+ # Step 1: pick a random r
+ # Step 2: compute g = r^((n-1)/q) mod p
+ # Step 3: if g == 1, goto Step 1.
+ # Note that n = 2*R*q+1, hence the exponent is 2*R.
+
# We could set r = 0.3333 earlier, then use BLS75 theorem 5 here.
# The chain would be shorter, requiring less overall work for
# large inputs. Maurer's paper discusses the idea.
@@ -3479,6 +3486,15 @@ the primitive root exists, while L<OEIS A046145|http://oeis.org/A046145>
is a list of the smallest primitive roots, which is what this function
produces.
+=head2 znlog
+
+ $k = znlog($b, $g, $p)
+
+Returns the integer C<k> that solves the equation C<b^k = g mod p>, or
+undef if no solution is found. This is the discrete logarithm problem.
+The implementation in this version is not very useful, but may be improved.
+
+
=head2 legendre_phi
$phi = legendre_phi(1000000000, 41);
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index 34ab778..1eaca36 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1245,6 +1245,22 @@ sub znorder {
return $k;
}
+sub znlog {
+ my($a,$g,$p) = @_;
+ # This is just a stupid brute force search.
+ $a = Math::BigInt->new("$a") unless ref($a) eq 'Math::BigInt';
+ $g = Math::BigInt->new("$g") unless ref($g) eq 'Math::BigInt';
+ $p = Math::BigInt->new("$p") unless ref($p) eq 'Math::BigInt';
+ for (my $n = BONE->copy; $n < $p; $n->binc) {
+ my $t = $g->copy->bmodpow($n, $p);
+ if ($t == $a) {
+ $n = _bigint_to_int($n) if $n->bacmp(''.~0) <= 0;
+ return $n;
+ }
+ }
+ return;
+}
+
# Find first D in sequence (5,-7,9,-11,13,-15,...) where (D|N) == -1
sub _lucas_selfridge_params {
my($n) = @_;
diff --git a/t/19-moebius.t b/t/19-moebius.t
index 502cec8..dd56fe6 100644
--- a/t/19-moebius.t
+++ b/t/19-moebius.t
@@ -6,7 +6,7 @@ use Test::More;
use Math::Prime::Util
qw/moebius mertens euler_phi jordan_totient divisor_sum exp_mangoldt
chebyshev_theta chebyshev_psi carmichael_lambda znorder liouville
- znprimroot kronecker legendre_phi gcd lcm
+ znprimroot znlog kronecker legendre_phi gcd lcm
/;
my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
@@ -325,6 +325,19 @@ if ($use64) {
push @lcms, [ [267220708,143775143,261076], 15015659316963449908];
}
+my @znlogs = (
+ [ [5,2,1019], 10],
+ [ [2,4,17], undef],
+ [ [7,3,8], undef],
+ [ [3,3,8], 1],
+ [ [10,2,101], 25],
+ [ [2,55,101], 73], # 2 = 55^73 mod 101
+ [ [3061666278, 499998, 3332205179], 22],
+);
+if ($usexs) {
+ push @znlogs, [ [5678,5,10007], 8620]; # 5678 = 5^8620 mod 10007
+}
+
# These are slow with XS, and *really* slow with PP.
if (!$usexs) {
%big_mertens = map { $_ => $big_mertens{$_} }
@@ -355,6 +368,7 @@ plan tests => 0 + 1
+ scalar(@gcds)
+ scalar(@lcms)
+ scalar(@mult_orders)
+ + scalar(@znlogs)
+ scalar(@legendre_sums)
+ scalar(keys %primroots) + 2
+ scalar(keys %jordan_totients)
@@ -527,6 +541,13 @@ while (my($n, $root) = each (%primroots)) {
}
is( znprimroot("-100000898"), 31, "znprimroot(\"-100000898\") == 31" );
is( znprimroot("+100000898"), 31, "znprimroot(\"+100000898\") == 31" );
+###### znlog
+foreach my $arg (@znlogs) {
+ my($aref, $exp) = @$arg;
+ my ($a, $g, $p) = @$aref;
+ my $k = znlog($a,$g,$p);
+ is( $k, $exp, "znlog($a,$g,$p) = " . ((defined $exp) ? $exp : "<undef>") );
+}
###### liouville
foreach my $i (@liouville_pos) {
is( liouville($i), 1, "liouville($i) = 1" );
--
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