#! /usr/sepp/bin/perl -w
############################################################
## Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
## http://www.iis.ee.ethz.ch/~sha3
############################################################
use strict;
# v0.2 - kgf@ee.ethz.ch - Thu Sep 22 08:21:54 CEST 2011
# - added a small hack to make the results uppercase, needed for postlayout
# v0.1 - kgf@ee.ethz.ch - Mon Aug 29 16:10:41 CEST 2011
# - This file will parse the list.lst file generated by modelsim
# and generate the
my $LIST_FILE="list.lst";
my @inputs;
my @outputs;
my @algs;
my $RESETTIME=25;
my $APPTIME=5;
my $PERIOD=20;
my $last_input_alg;
my @final_block;
my %names= ( "blake" => "Jean-Philippe Aumasson",
"groestl" => "Groestl Team",
"jh" => "Hongjun Wu",
"keccak" => "Keccak Team",
"sha2" => "NIST",
"skein" => "Bruce Schneier");
my %ALGORITHM = (
0 => "ethz_sha2",
1 => "ethz_blake",
2 => "ethz_groestl",
3 => "ethz_jh",
4 => "ethz_keccak",
5 => "ethz_skein",
8 => "gmu_sha2",
9 => "gmu_blake",
10=> "gmu_groestl",
11=> "gmu_jh",
12=> "gmu_keccak",
13=> "gmu_skein"
);
# we need to truncate part of the output if this is the final block
# in effect undo the padding
my %LAST_BLOCK = (
0 => 108,
1 => 108,
2 => 108,
3 => 0,
4 => 268,
5 => 128,
8 => 108,
9 => 108,
10=> 108,
11=> 0,
12=> 268,
13=> 128
);
print "\n\n";
print "Reading [$LIST_FILE] \n";
open (L, "< $LIST_FILE") or die "Can not open $LIST_FILE for reading\n";
my $icnt=0;
my $ocnt=0;
my $totaltime=0;
my %duration;
my $lasttime=$RESETTIME + 10; # delay for respacqtime
# the first line contains the time unit. If it is ps multiply the time
# constants by 1000
my $line =L; # read the first line
if ($line=~/^\s*ps\s+/){
$RESETTIME=$RESETTIME * 1000;
$APPTIME=$APPTIME *5;
$PERIOD=$PERIOD * 1000;
}
while (L){
next unless (m/^\s*\d/); # skip lines that don't start with anumber
$_=uc($_); # make sure results are uppercase
(my $time, my $alg, my $we, my $fin, my $oe, my $pen, my $i, my $o) = split;
if (($oe eq '1') and ($final_block[$ocnt] eq '1')){
$outputs[$ocnt]=$o;
if ($alg ne $last_input_alg){
print "Current algorithm [$alg] does not match algorithm when last block started [$last_input_alg]\n";
}
$algs[$ocnt]=$alg;
$ocnt=$ocnt+1; # increase the count
}
if ($we eq '1'){
# we are writing new block
# update the counters
my $cycles = ($time-$lasttime) / $PERIOD;
$lasttime= $time;
$duration{$cycles}++;
## truncate if not keccak
unless (($alg eq "4") or ($alg eq "12")){
$i=~s/^.{144}//;
}
if ($fin eq '1'){ # we are in the last block
$last_input_alg = $alg;
$final_block[$icnt] = 1;
# get rid of the padding for the last block
my $len= $LAST_BLOCK{$alg};
$i=~m/^(.{$len})/;
$i = $1;
}
my $old = (exists $inputs[$icnt]) ? $inputs[$icnt] : "";
my $new = $old.$i;
$inputs[$icnt] = $new;
if ($fin eq '1') { $icnt= $icnt + 1}; # increment counter we are finished
}
$totaltime=$time;
}
close(L);
$totaltime = ($totaltime - $RESETTIME - $APPTIME) / $PERIOD;
## this is an example stimuli generation
## assumes the that the algorithms stays constant
## modify later
my $alg = $ALGORITHM{$algs[0]};
my $STIMULI="stimuli.txt";
my $EXPRESP="expresp.txt";
print "Generating [$STIMULI] file for ETHZ_KAT\n";
open (S, "> $STIMULI") or die "Can not write to $STIMULI";
(my $short_alg = $alg) =~s/(ethz|gmu)_//;
print S <<"BUGU";
# stimuli.txt
# Algorithm Name: $short_alg
# Principal Submitter: $names{${short_alg}}
BUGU
## importnat, we skip the first output, it is a dummy.
## that is why the loop is from 1..$#outputs
for my $i (1.. $#outputs){
my $len = length($inputs[$i]) * 4;
print S "Len = $len\n";
print S "Msg = $inputs[$i]\n";
print S "MD = ??\n\n";
}
close(S);
## now run
my $exec = "../../$alg/simvectors/ETHZ_KAT";
print "Running [$exec]\n";
system("$exec");
## now we can read the expresp file and compare the results
print "Reading [$EXPRESP] file \n";
open (E, "< $EXPRESP") or die "Can not open $EXPRESP\n";
my $cnt=1; # we will skip the first output as it is a dummy
my $err=0;
while (E){
if (m/MD = (\S+)/){
my $res= $1;
if ($res ne $outputs[$cnt]){
$err++;
print "\n";
print "ERROR: output #",$cnt," does not match\n"; # we skipped the first guy
print " Expected: [$res]\n";
print " Received: [$outputs[$cnt]]\n\n";
}
$cnt ++;
}
}
$cnt--;
close (E);
## determine the most common block length
my $maxduration=0;
my $maxcount=0;
foreach my $d (keys %duration){
if ($duration{$d} > $maxduration){
$maxduration = $duration{$d};
$maxcount = $d;
}
}
print '-' x 78,"\n";
print "RESULT for $alg: checked $cnt vectors - ";
if ($err eq 0) {
print "ALL RESULTS MATCH - $maxcount cycles per block \n";
}
else{
print "Encountered $err errors\n";
}
print "\n\n";