#!/usr/bin/env perl
use strict;
use warnings;
$| = 1;  # fast pipes

use Math::Prime::Util qw/random_nbit_prime znprimroot znlog powmod
                         csrand urandomm/;

# This test uses znlog with prime modulus, similar to FLINT's tests.
# Our znlog will handle non-primes, so another interesting test would
# be using random integer p values.
my $ebits = 64;
csrand(3);
#Math::Prime::Util::prime_set_config(verbose=>1);

print "1..",$ebits-3,"\n";
for my $bits (4 .. $ebits) {
  #Math::Prime::Util::prime_set_config(verbose=>1) if $bits > 50;
  my $ntests = ($bits < 30) ? 100 : ($bits < 40) ? 10 : ($bits < 45) ? 5 : 1;
  my $ok = "ok";
  for my $tn (1 .. $ntests) {
    my $p = random_nbit_prime( $bits );
    my $root = znprimroot($p);
    my $b = 1 + urandomm($p-2);
    #print "   znlog($b,$root,$p) ...";
    my $d = znlog($b, $root, $p);
    #print "   DONE\n";
    if (defined $d) {
      my $res = powmod($root, $d, $p);
      next if $res == $b;
      warn "FAIL $bits:  $root ^ $d mod $p = $res, not $b\n";
    } else {
      warn "FAIL $bits:  znlog($b, $root, $p) failed\n";
    }
    $ok = "not ok";
    #print "PASS $bits: $root ^ $d mod $p = $res\n";
  }
  print "$ok ",$bits-3," - znlog with $bits bits\n";
}
