#! /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";