#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use Digest::SHA qw/sha1/;

# Testing interoperability with Crypt::DSA.

BEGIN {
  if ( ! $ENV{RELEASE_TESTING} ) {
    plan skip_all => 'tests tests are for release candidate testing';
  } elsif ( eval { require Crypt::DSA; 1; } ) {
    plan tests => 4;
  } else {
    plan skip_all => 'Requires Crypt::DSA';
  }
}

use Crypt::DSA::GMP;
use Crypt::DSA::GMP::Util qw/bin2mp mp2bin/;

my $message = "This prime validation algorithm is used to validate that the integers p and q were generated by the prime generation algorithm given in Appendix A.1.1.2.  The validation algorithm requires the values of p, q, domain_parameter_seed and counter, which were output from the prime generation algorithm.  Let Hash() be the hash function used to generate p and q, and let outlen be its output block length.";

{
  my $valid;
  my $hash = sha1($message);

  my $dsa1 = Crypt::DSA->new;
  my $key1 = $dsa1->keygen( Size => 256 );
  my $sigobj1 = $dsa1->sign(Key=>$key1,Digest=>$hash);
  my $sig1 = [$sigobj1->r, $sigobj1->s];
  $valid = $dsa1->verify(Key=>$key1,Digest=>$hash,Signature=>$sigobj1);
  ok($valid, "Crypt::DSA isn't obviously broken");

  my $dsa2 = Crypt::DSA::GMP->new;
  my $key2 = $dsa2->keyset( p => $key1->p,
                            q => $key1->q,
                            g => $key1->g,
                            x => $key1->priv_key,
                            y => $key1->pub_key );
  my $sigobj2 = $dsa2->sign(Key=>$key2,Digest=>$hash);
  my $sig2 = [$sigobj2->r, $sigobj2->s];
  $valid = $dsa2->verify(Key=>$key2,Digest=>$hash,Signature=>$sigobj2);
  ok($valid, "Crypt::DSA::GMP isn't obviously broken");

  # Now for the real work.

  # First let's kill off the private keys.  They should not be needed
  # for verify, so let's make sure they're gone.
  $key1->priv_key(undef);
  $key2->priv_key(undef);
  {
    my $sig = Crypt::DSA::GMP::Signature->new;
    $sig->r($sig1->[0]);   $sig->s($sig1->[1]);
    $valid = $dsa2->verify(Key=>$key2,Digest=>$hash,Signature=>$sig);
    ok($valid, "Crypt::DSA::GMP can verify using the Crypt::DSA signature");
  }
  {
    my $sig = Crypt::DSA::Signature->new;
    $sig->r($sig2->[0]);   $sig->s($sig2->[1]);
    $valid = $dsa1->verify(Key=>$key1,Digest=>$hash,Signature=>$sig);
    ok($valid, "Crypt::DSA can verify using the Crypt::DSA::GMP signature");
  }
}
