#!/usr/bin/perl
use FindBin;
use warnings;
use strict;
use Test::More tests => 520 + 1;
use Test::NoWarnings;
use Math::BigInt try => 'GMP';
use Math::EllipticCurve::Prime;
use Math::EllipticCurve::Prime::Point;
my $test_file = "$FindBin::Bin/data/nisttv";
sub load_tests {
my %tests;
my $curve;
my $collected = {};
open(my $fh, "<", $test_file);
while (<$fh>) {
$curve = $1 if /^\s*Curve:\s*(\S+)/;
if (/^\s*$/) {
push @{$tests{$curve}}, $collected
if defined $curve && scalar keys %$collected;
$collected = {};
next;
}
$collected->{$1} = $2 if /^([kxy])\s+=\s+([A-Fa-f0-9]+)\s*$/;
}
close($fh);
return \%tests;
}
my $tests = load_tests();
foreach my $curvename (sort keys %$tests) {
my $curve = Math::EllipticCurve::Prime->new(name => $curvename);
next unless $curve;
foreach my $test (@{$tests->{$curvename}}) {
my $k = Math::BigInt->new($test->{k});
my $g = $curve->g;
my $x = Math::BigInt->new("0x$test->{x}");
my $y = Math::BigInt->new("0x$test->{y}");
my $point = $g->copy->bmul($k);
is($point->x->as_hex, $x->as_hex, "curve $curvename k $k x coordinate matches");
is($point->y->as_hex, $y->as_hex, "curve $curvename k $k y coordinate matches");
}
}