CryptX
view release on metacpan or search on metacpan
t/digest_kangarootwelve.t view on Meta::CPAN
use strict;
use warnings;
use Test::More tests => 20;
use Crypt::Digest::KangarooTwelve;
# RFC 9861 test vectors - https://www.rfc-editor.org/rfc/rfc9861
# Input pattern: ptn(n) = bytes 0x00, 0x01, ..., (each mod 0xfb)
sub ptn { join("", map { chr($_ % 0xfb) } 0..$_[0]-1) }
{ ### KangarooTwelve 128-bit security
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(128)->done(32)),
'1ac2d450fc3b4205d19da7bfca1b37513c0803577ac7167f06fe2ce1f0ef39e5',
'K12-128 empty input, no customization, 32 bytes');
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(128)->add(ptn(1))->done(32)),
'2bda92450e8b147f8a7cb629e784a058efca7cf7d8218e02d345dfaa65244a1f',
'K12-128 ptn(1) input, no customization, 32 bytes');
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(128)->customization(ptn(1))->done(32)),
'fab658db63e94a246188bf7af69a133045f46ee984c56e3c3328caaf1aa1a583',
'K12-128 empty input, ptn(1) customization, 32 bytes');
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(128)->add(ptn(17))->done(32)),
'6bf75fa2239198db4772e36478f8e19b0f371205f6a9a93a273f51df37122888',
'K12-128 ptn(17) input, no customization, 32 bytes');
}
{ ### KangarooTwelve 256-bit security
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(256)->done(64)),
'b23d2e9cea9f4904e02bec06817fc10ce38ce8e93ef4c89e6537076af8646404' .
'e3e8b68107b8833a5d30490aa33482353fd4adc7148ecb782855003aaebde4a9',
'K12-256 empty input, no customization, 64 bytes');
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(256)->add(ptn(1))->done(64)),
'0d005a194085360217128cf17f91e1f71314efa5564539d444912e3437efa17f' .
'82db6f6ffe76e781eaa068bce01f2bbf81eacb983d7230f2fb02834a21b1ddd0',
'K12-256 ptn(1) input, no customization, 64 bytes');
is(unpack('H*', Crypt::Digest::KangarooTwelve->new(256)->customization(ptn(1))->done(64)),
'9280f5cc39b54a5a594ec63de0bb99371e4609d44bf845c2f5b8c316d72b1598' .
'11f748f23e3fabbe5c3226ec96c62186df2d33e9df74c5069ceecbb4dd10eff6',
'K12-256 empty input, ptn(1) customization, 64 bytes');
}
{ ### streaming done() and clone
my $d1 = Crypt::Digest::KangarooTwelve->new(128);
my $out1 = $d1->done(16) . $d1->done(16);
my $out2 = Crypt::Digest::KangarooTwelve->new(128)->done(32);
is($out1, $out2, 'K12-128 streaming done');
my $d2 = Crypt::Digest::KangarooTwelve->new(128)->add(ptn(17));
my $d3 = $d2->clone;
is($d2->done(32), $d3->done(32), 'K12-128 clone');
eval { $d2->add("x"); 1 };
like($@, qr/^FATAL: cannot add after done; call reset first\b/, 'K12 add after done croaks');
eval { $d3->customization("ctx"); 1 };
like($@, qr/^FATAL: cannot add after done; call reset first\b/, 'K12 customization after done croaks');
my $d4 = Crypt::Digest::KangarooTwelve->new(128)->add(ptn(17))->customization("ctx");
my $first = $d4->done(32);
is($d4->reset->add(ptn(17))->customization("ctx")->done(32), $first, 'K12 reset re-enables add/customization');
}
{
my @cases = (
{
label => 'done(-1)',
action => sub { Crypt::Digest::KangarooTwelve->new(128)->done(-1) },
re => qr/^FATAL: output length too large\b/,
},
{
label => 'done(1000000001)',
action => sub { Crypt::Digest::KangarooTwelve->new(128)->done(1000000001) },
re => qr/^FATAL: output length too large\b/,
},
{
label => 'done(0)',
action => sub { Crypt::Digest::KangarooTwelve->new(128)->done(0) },
re => qr/^FATAL: invalid output length\b/,
},
{
label => 'done(1.5)',
action => sub { Crypt::Digest::KangarooTwelve->new(128)->done(1.5) },
len => 1,
},
);
for my $case (@cases) {
my $out;
my $ok = eval { $out = $case->{action}->(); 1 };
if (exists $case->{len}) {
ok($ok, "$case->{label} succeeds");
is(length($out), $case->{len}, "$case->{label} output length");
}
else {
ok(!$ok, "$case->{label} croaks");
like($@, $case->{re}, "$case->{label} croak text");
}
}
}
( run in 1.526 second using v1.01-cache-2.11-cpan-140bd7fdf52 )