1#!/usr/bin/perl
2
3use strict;
4BEGIN {
5	$|  = 1;
6	$^W = 1;
7}
8use Test::More;
9use Crypt::DSA;
10use Crypt::DSA::KeyChain;
11
12BEGIN {
13	if ( not $INC{'Math/BigInt/GMP.pm'} and not $INC{'Math/BigInt/Pari.pm'} ) {
14		plan( skip_all => 'Test is excessively slow without GMP or Pari' );
15	} else {
16		plan( tests => 9 );
17	}
18}
19
20## Test with data from fips 186 (appendix 5) doc (using SHA1
21## instead of SHA digests).
22my @seed_hex   = "d5014e4b60ef2ba8b6211b4062ba3224e0427dd3" =~ /(..)/g;
23my $start_seed = join '', map chr hex, @seed_hex;
24my $expected_p = "7434410770759874867539421675728577177024889699586189000788950934679315164676852047058354758883833299702695428196962057871264685291775577130504050839126673";
25my $expected_q = "1138656671590261728308283492178581223478058193247";
26my $expected_g = "5154978420348751798752390524304908179080782918903280816528537868887210221705817467399501053627846983235883800157945206652168013881208773209963452245182466";
27
28## We'll need this later to sign and verify.
29my $dsa = Crypt::DSA->new;
30ok($dsa, 'Crypt::DSA->new worked');
31
32## Create a keychain to generate our keys. Generally you
33## don't need to be this explicit (just call keygen), but if
34## you want the extra state data (counter, h, seed) you need
35## to use the actual methods themselves.
36my $keychain = Crypt::DSA::KeyChain->new;
37ok($keychain, 'Crypt::DSA::KeyChain->new worked');
38
39diag('This takes a couple of minutes on slower machines.');
40
41## generate_params builds p, q, and g.
42my($key, $counter, $h, $seed) = $keychain->generate_params(
43	Size => 512,
44	Seed => $start_seed,
45);
46is("@{[ $key->p ]}", $expected_p, '->p returns expected value');
47is("@{[ $key->q ]}", $expected_q, '->q returns expected value');
48is("@{[ $key->g ]}", $expected_g, '->g returns expected value');
49
50## Explanation: p should have been found when the counter was at
51## 105; g should have been found when h was 2; and g should have
52## been discovered directly from the start seed.
53is($counter, 105, 'Consistency check 1');
54is($h, 2, 'Consistency check 2');
55is($seed, $start_seed, 'Consistency check 3');
56
57## Generate random public and private keys.
58$keychain->generate_keys($key);
59
60my $str1 = "12345678901234567890";
61
62## Test key generation by signing and verifying a message.
63my $sig = $dsa->sign(Message => $str1, Key => $key);
64ok($dsa->verify(Message => $str1, Key => $key, Signature => $sig), 'Signing and verifying ok');
65