[libmath-prime-util-perl] 07/43: Shawe-Taylor random provable primes. No documentation.

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


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

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

commit 4eb186d88ee41723c6eb63f7e8d544d90e2c8d81
Author: Dana Jacobsen <dana at acm.org>
Date:   Wed Mar 5 18:34:22 2014 -0800

    Shawe-Taylor random provable primes.  No documentation.
---
 lib/Math/Prime/Util.pm              |   8 +++
 lib/Math/Prime/Util/RandomPrimes.pm | 100 ++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index ac134a3..7f5aba5 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -36,6 +36,7 @@ our @EXPORT_OK =
       random_prime random_ndigit_prime random_nbit_prime random_strong_prime
       random_proven_prime random_proven_prime_with_cert
       random_maurer_prime random_maurer_prime_with_cert
+      random_shawe_taylor_prime
       primorial pn_primorial consecutive_integer_lcm
       gcd lcm factor factor_exp all_factors divisors
       moebius mertens euler_phi jordan_totient exp_mangoldt liouville
@@ -335,6 +336,13 @@ sub random_maurer_prime {
   return Math::Prime::Util::RandomPrimes::random_maurer_prime($bits);
 }
 
+sub random_shawe_taylor_prime {
+  my($bits) = @_;
+  _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
+  require Math::Prime::Util::RandomPrimes;
+  return Math::Prime::Util::RandomPrimes::random_shawe_taylor_prime(@_);
+}
+
 sub random_maurer_prime_with_cert {
   my($bits) = @_;
   _validate_num($bits, 2) || _validate_positive_integer($bits, 2);
diff --git a/lib/Math/Prime/Util/RandomPrimes.pm b/lib/Math/Prime/Util/RandomPrimes.pm
index a7135e8..35b88ec 100644
--- a/lib/Math/Prime/Util/RandomPrimes.pm
+++ b/lib/Math/Prime/Util/RandomPrimes.pm
@@ -832,6 +832,106 @@ sub random_maurer_prime_with_cert {
   croak "Failure in random_maurer_prime, could not find a prime\n";
 } # End of random_maurer_prime
 
+sub random_shawe_taylor_prime {
+  my $k = shift;
+  my $which = shift;
+
+  my $seed;
+  {
+    # TODO: should go through RANDF
+    if (!defined $_BRS) {
+      require Bytes::Random::Secure;
+      $_BRS = Bytes::Random::Secure->new(NonBlocking=>1);
+    }
+    $seed = $_BRS->bytes(512/8);
+  }
+
+  my($status,$prime,$prime_seed,$prime_gen_counter)
+     = _ST_Random_prime($k, $seed);
+  croak "Shawe-Taylor random prime failure: loop overflow" unless $status;
+
+  return $prime;
+}
+
+sub _seed_plus_one {
+    my($s) = @_;
+    for (my $i = length($s)-1; $i >= 0; $i--) {
+        vec($s, $i, 8)++;
+        last unless vec($s, $i, 8) == 0;
+    }
+    return $s;
+}
+
+sub _ST_Random_prime {  # From FIPS 186-4
+  my($k, $input_seed) = @_;
+  croak "Shawe-Taylor random prime must have length >= 2"  if $k < 2;
+  $k = int("$k");
+
+  croak "Shawe-Taylor random prime, invalid input seed"
+     unless defined $input_seed && length($input_seed) >= 32;
+
+  if (!defined $Digest::SHA::VERSION) {
+    eval { require Digest::SHA; $Digest::SHA::VERSION >= 2.00; }
+      or do { croak "Must have Digest::SHA 2.00 or later"; };
+  }
+
+  my $k2 = Math::BigInt->new(2)->bpow($k-1);
+
+  if ($k < 33) {
+    my $seed = $input_seed;
+    my $prime_gen_counter = 0;
+    while (1) {
+      my $seedp1 = _seed_plus_one($seed);
+      my $cvec = Digest::SHA::sha256($seed) ^ Digest::SHA::sha256($seedp1);
+      my $c = Math::BigInt->from_hex('0x' . unpack("H*", $cvec));
+      $c = $k2 + ($c % $k2);
+      $c = (2 * ($c >> 1)) + 1;
+      $prime_gen_counter++;
+      $seed = _seed_plus_one($seedp1);
+      # c is small so we can provably test it.
+      return (1,$c,$seed,$prime_gen_counter) if is_prob_prime($c);
+      return (0,0,0,0) if $prime_gen_counter > 4*$k;
+    }
+  }
+  my($status,$c0,$seed,$prime_gen_counter)
+     = _ST_Random_prime( (($k+1)>>1)+1, $input_seed);
+  return (0,0,0,0) unless $status;
+  my $iterations = int(($k + 255) / 256) - 1;  # SHA256 generates 256 bits
+  my $old_counter = $prime_gen_counter;
+  my $xstr = '';
+  for my $i (0 .. $iterations) {
+    $xstr = Digest::SHA::sha256_hex($seed) . $xstr;
+    $seed = _seed_plus_one($seed);
+  }
+  my $x = Math::BigInt->from_hex('0x'.$xstr);
+  $x = $k2 + ($x % $k2);
+  my $t = ($x + 2*$c0 - 1) / (2*$c0);
+  while (1) {
+    if (2*$t*$c0 + 1 > 2*$k2) { $t = ($k2 + 2*$c0 - 1) / (2*$c0); }
+    my $c = 2*$t*$c0 + 1;
+    $prime_gen_counter++;
+    # Only do this if we're pretty sure the candidate is prime.
+    if (is_prob_prime($c)) {
+      my $astr = '';
+      for my $i (0 .. $iterations) {
+        $astr = Digest::SHA::sha256_hex($seed) . $astr;
+        $seed = _seed_plus_one($seed);
+      }
+      my $a = Math::BigInt->from_hex('0x'.$astr);
+      $a = ($a % ($c-3)) + 2;
+      my $z = $a->copy->bmodpow(2*$t,$c);
+      if (Math::BigInt::bgcd($z-1,$c)->is_one && $z->copy->bmodpow($c0,$c)->is_one) {
+        croak "Shawe-Taylor random prime failure at ($k): $c not prime"
+          unless is_prob_prime($c);
+        return (1, $c, $seed, $prime_gen_counter);
+      }
+    }
+    return (0,0,0,0) if $prime_gen_counter > 4*$k + $old_counter;
+    $t++;
+  }
+}
+
+
 # Gordon's algorithm for generating a strong prime.
 sub random_strong_prime {
   my $t = shift;

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