1#! /usr/local/bin/perl -w 2# 3# DES_PP benchmarking. 4# Copyright 2000, Guido Flohr <guido@imperia.net> 5 6use strict; 7use IO::File; 8use POSIX; 9use Crypt::DES_PP; 10use Benchmark; 11 12use constant SECONDS_PER_TEST => 10; 13use constant KEY => 'PurePerl'; 14use constant PLAINTEXT => 'PerlPunk'; 15use constant CIPHERTEXT => 'PunkPerl'; 16 17sub alarm_handler ($); 18 19my $clocks; 20my $elapsed = 0; 21 22STDOUT->autoflush (1); 23 24print <<EOF; 251..1 26=== Benchmarking DES_PP module. === 27To pace directly against XS (embedded C code) version run \`\`perl test-xs'' 28in this directory. 29EOF 30 31print "checking prerequisites... "; 32eval { 33 eval 'use POSIX qw (_SC_CLK_TCK); 34 $clocks = sysconf (&POSIX::_SC_CLK_TCK)'; 35 if ($@) { 36 eval 'use POSIX qw (CLK_TCK); 37 $clocks = sysconf (&POSIX::CLK_TCK)'; 38 if ($@) { 39 eval 'use POSIX qw (TICKS_PER_SEC); 40 $clocks = POSIX::TICKS_PER_SEC'; 41 } 42 die "can't find out your kernel's heartbeat\n" if $@; 43 } 44 45 if (exists $SIG{ALRM}) { 46 # Check if the POSIX version of times(2) is available. 47 die "POSIX::times not available\n" 48 unless exists $POSIX::{times}; 49 50 } else { 51 die "no SIGALRM available\n"; 52 } 53}; 54 55if ($@) { 56 print <<EOF; 57tsk, tsk 58Please reformat your harddisk and install an operating system before you 59proceed. 60ok # Skipped: $@ 61EOF 62 63 exit 0; 64} 65 66print "looks fine\n"; 67 68$SIG{ALRM} = \&alarm_handler; 69 70my $starttime; 71my $count = 0; 72 73my $des; 74 75print "Initializing 8-byte keys for ", SECONDS_PER_TEST, " seconds... "; 76eval { 77 (undef, $starttime) = POSIX::times; 78 79 alarm SECONDS_PER_TEST; 80 while (1) { $des = Crypt::DES_PP->new (KEY); ++$count }; 81}; 82die if $@ and $@ ne "alarm\n"; 83 84my $keys_per_sec = ($clocks * $count) / $elapsed; 85print "$keys_per_sec keys per second\n"; 86 87# Benchmark encryption. 88print "Encrypting 8-byte blocks for ", SECONDS_PER_TEST, " seconds... "; 89$des = Crypt::DES_PP->new (KEY); 90$count = 0; 91 92eval { 93 (undef, $starttime) = POSIX::times; 94 95 alarm SECONDS_PER_TEST; 96 while (1) { $des->encrypt (PLAINTEXT); ++$count }; 97}; 98die if $@ and $@ ne "alarm\n"; 99 100my $encrypts_per_sec = ($clocks * $count) / $elapsed; 101print "$encrypts_per_sec encryptions per second\n"; 102 103# Benchmark encryption. 104print "Decrypting 8-byte blocks for ", SECONDS_PER_TEST, " seconds... "; 105$des = Crypt::DES_PP->new (KEY); 106$count = 0; 107 108eval { 109 (undef, $starttime) = POSIX::times; 110 111 alarm SECONDS_PER_TEST; 112 while (1) { $des->decrypt (CIPHERTEXT); ++$count }; 113}; 114die if $@ and $@ ne "alarm\n"; 115 116my $decrypts_per_sec = ($clocks * $count) / $elapsed; 117print "$decrypts_per_sec decryptions per second\n"; 118 119# Run in Cipher Block Chaining Mode. 120use constant EIGHT_BYTE_BLOCKS => 20_000; 121my $plaintext = PLAINTEXT x EIGHT_BYTE_BLOCKS; 122my ($start, $end); 123my $timediff = ''; 124my $des_driver = 'DES'; 125my $des_pp_driver = 'DES_PP'; 126 127# First pure Perl version. 128print "Encrypting ", EIGHT_BYTE_BLOCKS << 3, " bytes in CBC mode..."; 129eval ' 130 use Crypt::CBC; 131 132 my $cipher = Crypt::CBC->new (KEY, $des_pp_driver); 133 my $start = Benchmark->new; 134 $cipher->encrypt ($plaintext); 135 my $end = Benchmark->new; 136 $timediff = timestr timediff $end, $start; 137'; 138print $@ ? " skipped (Crypt::CBC not loadable)\n" : 139 " done\n$timediff\n"; 140 141# Now the XS version. 142print "XS-Version: Encrypting ", EIGHT_BYTE_BLOCKS << 3, 143 " bytes bytes in CBC mode..."; 144eval ' 145 use Crypt::CBC; 146 147 my $cipher = Crypt::CBC->new (KEY, $des_driver); 148 my $start = Benchmark->new; 149 $cipher->encrypt ($plaintext); 150 my $end = Benchmark->new; 151 $timediff = timestr timediff $end, $start; 152'; 153print $@ ? " skipped (Crypt::CBC or Crypt::DES not loadable)\n" : 154 " done\n$timediff\n"; 155$timediff = 0; 156 157# Now with a non-cached key and 128 bytes of plaintext. 158$plaintext = PLAINTEXT x 16; 159print "Encrypting ", EIGHT_BYTE_BLOCKS, 160 " 128-byte-blocks in non-cached CBC mode..."; 161eval ' 162 use Crypt::CBC; 163 164 my $start = Benchmark->new; 165 166 for (1 .. EIGHT_BYTE_BLOCKS >> 3) { 167 my $cipher = Crypt::CBC->new (KEY, $des_pp_driver); 168 $cipher->encrypt ($plaintext); 169 } 170 my $end = Benchmark->new; 171 $timediff = timestr timediff $end, $start; 172'; 173print $@ ? " skipped (Crypt::CBC not loadable)\n" : 174 " done\n$timediff\n"; 175$timediff = 0; 176 177$plaintext = PLAINTEXT x 16; 178print "XS-Version: Encrypting ", EIGHT_BYTE_BLOCKS, 179 " 128-byte-blocks in non-cached CBC mode..."; 180eval ' 181 use Crypt::CBC; 182 183 my $start = Benchmark->new; 184 185 for (1 .. EIGHT_BYTE_BLOCKS >> 3) { 186 my $cipher = Crypt::CBC->new (KEY, $des_driver); 187 $cipher->encrypt ($plaintext); 188 } 189 my $end = Benchmark->new; 190 $timediff = timestr timediff $end, $start; 191'; 192print $@ ? " skipped (Crypt::CBC not loadable)\n" : 193 " done\n$timediff\n"; 194print "ok 1\n"; 195 196sub alarm_handler ($) { 197 my (undef, $endtime) = POSIX::times; 198 199 $elapsed = $endtime - $starttime; 200 201 die "alarm\n"; 202} 203 204 205 206 207