1#!/usr/bin/env perl
2use strict;
3use warnings;
4
5use Benchmark qw(timethese);
6use Getopt::Long qw(GetOptions :config no_ignore_case);
7use List::Util qw(max);
8
9# Install Task::Digest
10use Crypt::RIPEMD160      ();
11use Digest::BLAKE         ();
12use Digest::BMW           ();
13use Digest::CubeHash::XS  ();
14use Digest::ECHO          ();
15use Digest::Fugue         ();
16use Digest::GOST          ();
17use Digest::Groestl       ();
18use Digest::Hamsi         ();
19use Digest::JH            ();
20use Digest::Keccak        ();
21use Digest::Luffa         ();
22use Digest::MD2           ();
23use Digest::MD4           ();
24use Digest::MD5           ();
25use Digest::MD6           ();
26use Digest::Perl::MD4     ();
27use Digest::Perl::MD5     ();
28use Digest::SHA           ();
29use Digest::SHA1          ();
30use Digest::SHA::PurePerl ();
31use Digest::SHAvite3      ();
32use Digest::SIMD          ();
33use Digest::Shabal        ();
34use Digest::Skein         ();
35use Digest::Whirlpool     ();
36
37my %opts = (
38    iterations => -1,
39    size       => 1,  # kB
40);
41GetOptions(\%opts, 'iterations|i=i', 'size|s=f',);
42
43my $data = '01234567' x (128 * $opts{size});
44
45my %digests = (
46    blake_224    => sub { Digest::BLAKE::blake_224($data) },
47    blake_256    => sub { Digest::BLAKE::blake_256($data) },
48    blake_384    => sub { Digest::BLAKE::blake_384($data) },
49    blake_512    => sub { Digest::BLAKE::blake_512($data) },
50    bmw_224      => sub { Digest::BMW::bmw_224($data) },
51    bmw_256      => sub { Digest::BMW::bmw_256($data) },
52    bmw_384      => sub { Digest::BMW::bmw_384($data) },
53    bmw_512      => sub { Digest::BMW::bmw_512($data) },
54    cubehash_224 => sub { Digest::CubeHash::XS::cubehash_224($data) },
55    cubehash_256 => sub { Digest::CubeHash::XS::cubehash_256($data) },
56    cubehash_384 => sub { Digest::CubeHash::XS::cubehash_384($data) },
57    cubehash_512 => sub { Digest::CubeHash::XS::cubehash_512($data) },
58    echo_224     => sub { Digest::ECHO::echo_224($data) },
59    echo_256     => sub { Digest::ECHO::echo_256($data) },
60    echo_384     => sub { Digest::ECHO::echo_384($data) },
61    echo_512     => sub { Digest::ECHO::echo_512($data) },
62    fugue_224    => sub { Digest::Fugue::fugue_224($data) },
63    fugue_256    => sub { Digest::Fugue::fugue_256($data) },
64    fugue_384    => sub { Digest::Fugue::fugue_384($data) },
65    fugue_512    => sub { Digest::Fugue::fugue_512($data) },
66    gost         => sub { Digest::GOST::gost($data) },
67    groestl_224  => sub { Digest::Groestl::groestl_224($data) },
68    groestl_256  => sub { Digest::Groestl::groestl_256($data) },
69    groestl_384  => sub { Digest::Groestl::groestl_384($data) },
70    groestl_512  => sub { Digest::Groestl::groestl_512($data) },
71    hamsi_224    => sub { Digest::Hamsi::hamsi_224($data) },
72    hamsi_256    => sub { Digest::Hamsi::hamsi_256($data) },
73    hamsi_384    => sub { Digest::Hamsi::hamsi_384($data) },
74    hamsi_512    => sub { Digest::Hamsi::hamsi_512($data) },
75    jh_224       => sub { Digest::JH::jh_224($data) },
76    jh_256       => sub { Digest::JH::jh_256($data) },
77    jh_384       => sub { Digest::JH::jh_384($data) },
78    jh_512       => sub { Digest::JH::jh_512($data) },
79    keccak_224   => sub { Digest::Keccak::keccak_224($data) },
80    keccak_256   => sub { Digest::Keccak::keccak_256($data) },
81    keccak_384   => sub { Digest::Keccak::keccak_384($data) },
82    keccak_512   => sub { Digest::Keccak::keccak_512($data) },
83    luffa_224    => sub { Digest::Luffa::luffa_224($data) },
84    luffa_256    => sub { Digest::Luffa::luffa_256($data) },
85    luffa_384    => sub { Digest::Luffa::luffa_384($data) },
86    luffa_512    => sub { Digest::Luffa::luffa_512($data) },
87    md2          => sub { Digest::MD2::md2($data) },
88    md4          => sub { Digest::MD4::md4($data) },
89    md5          => sub { Digest::MD5::md5($data) },
90    md6_224      => sub { Digest::MD6::md6_224($data) },
91    md6_256      => sub { Digest::MD6::md6_256($data) },
92    md6_384      => sub { Digest::MD6::md6_384($data) },
93    md6_512      => sub { Digest::MD6::md6_512($data) },
94    perl_md4     => sub { Digest::Perl::MD4::md4($data) },
95    perl_md5     => sub { Digest::Perl::MD4::md4($data) },
96    perl_sha_1   => sub { Digest::SHA::PurePerl::sha1($data) },
97    perl_sha_224 => sub { Digest::SHA::PurePerl::sha224($data) },
98    perl_sha_256 => sub { Digest::SHA::PurePerl::sha256($data) },
99    perl_sha_384 => sub { Digest::SHA::PurePerl::sha384($data) },
100    perl_sha_512 => sub { Digest::SHA::PurePerl::sha512($data) },
101    ripemd_160   => sub {
102        my $c = Crypt::RIPEMD160->new; $c->add($data); $c->digest;
103    },
104    sha1_sha_1   => sub { Digest::SHA1::sha1($data) },
105    sha_sha_1    => sub { Digest::SHA::sha1($data) },
106    sha_224      => sub { Digest::SHA::sha224($data) },
107    sha_256      => sub { Digest::SHA::sha384($data) },
108    sha_384      => sub { Digest::SHA::sha256($data) },
109    sha_512      => sub { Digest::SHA::sha512($data) },
110    shabal_224   => sub { Digest::Shabal::shabal_224($data) },
111    shabal_256   => sub { Digest::Shabal::shabal_256($data) },
112    shabal_384   => sub { Digest::Shabal::shabal_384($data) },
113    shabal_512   => sub { Digest::Shabal::shabal_512($data) },
114    shavite3_224 => sub { Digest::SHAvite3::shavite3_224($data) },
115    shavite3_256 => sub { Digest::SHAvite3::shavite3_256($data) },
116    shavite3_384 => sub { Digest::SHAvite3::shavite3_384($data) },
117    shavite3_512 => sub { Digest::SHAvite3::shavite3_512($data) },
118    simd_224     => sub { Digest::SIMD::simd_224($data) },
119    simd_256     => sub { Digest::SIMD::simd_256($data) },
120    simd_384     => sub { Digest::SIMD::simd_384($data) },
121    simd_512     => sub { Digest::SIMD::simd_512($data) },
122    skein_256    => sub { Digest::Skein::skein_256($data) },
123    skein_512    => sub { Digest::Skein::skein_512($data) },
124    skein_1024   => sub { Digest::Skein::skein_1024($data) },
125    whirlpool    => sub { Digest::Whirlpool->new->add($data)->digest },
126);
127
128my $times = timethese -1, \%digests, 'none';
129
130my @info;
131my ($max_name_len, $max_rate_len, $max_bw_len) = (0, 0, 0);
132
133while (my ($name, $info) = each %$times) {
134    my ($duration, $cycles) = @{$info}[ 1, 5 ];
135    my $rate = sprintf '%.0f', $cycles / $duration;
136    my $bw = $rate * $opts{size} / 1024;
137    $bw = sprintf int $bw ? '%.0f' : '%.2f', $bw;
138
139    push @info, [$name, $rate, $bw];
140
141    $max_name_len = max $max_name_len, length($name);
142    $max_rate_len = max $max_rate_len, length($rate);
143    $max_bw_len   = max $max_bw_len,   length($bw);
144}
145
146for my $rec (sort { $b->[1] <=> $a->[1] } @info) {
147    my ($name, $rate, $bw) = @$rec;
148
149    my $name_padding = $max_name_len - length($name);
150
151    printf "%s%s %${max_rate_len}s/s  %${max_bw_len}s MB/s\n",
152        $name, ' 'x$name_padding, $rate, $bw;
153}
154