#!/bin/sh [ -z "$BASH_VERSION" ] && (which bash > /dev/null 2>&1) && exec bash $0 $*; # ----------------------------------------------------------------------------- root=$(cd $(dirname $(which "$0"))/.. && pwd); . $root/scripts/tools.sh; # ----------------------------------------------------------------------------- reports="$root/reports-$HOSTNAME"; srcdir=$1 dstdir=.; [ -n "$srcdir" ] || srcdir=$root; vectors=unverified.test-vectors; cpu_speed=$(tail -n 1 "$reports/cpuinfo"); if [ -r "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" ]; then status 1 "warming up CPU"; i=0; while [ $i -lt 10000 ]; do ((i++)); curr_speed=$(awk '/^cpu MHz/ { print $4; exit; }' /proc/cpuinfo); [ $((${cpu_speed%.*} - ${curr_speed%.*})) -gt 10 ] \ || break; done status 1; fi # ----------------------------------------------------------------------------- run () { srcdir=$1; var=$2; conf=$3; ext=${var}_${conf}; make="make var=$var conf=$conf"; name=$($make name); [ "$var" = "1" ] || name="$name (variant $var)"; status 1 "compiling $name under $conf"; $make clean &> /dev/null; cat > info_current <&1) COMPILATION: ------------------------------------------------------------------------------- $make $($make 2>&1) EXECUTABLE: ------------------------------------------------------------------------------- EOF status 1; if $make -q &> /dev/null; then hash=$($make hash); else echo "none" >> info_current; mv info_current errors_$ext; error 0 "compilation failed (see errors_$ext)."; $make clean &> /dev/null; return; fi status 1 "checking for duplicates"; matches=$(grep -l "$hash" {info,speed}_*_* 2> /dev/null); status 1; echo "$hash" >> info_current; if [ -n "$matches" ]; then info 1 "executable has been checked before (see $(echo $matches))"; mv info_current info_$ext; $make clean &> /dev/null; return; fi run=$($make run); status 1 "generating test vectors"; error=$($run -v -q > vectors_$ext 2> /dev/null; echo "$?"); status 1; if [ "$error" -gt "1" ]; then mv vectors_$ext errors_$ext; mv info_current info_$ext; error 0 "execution failed."; $make clean &> /dev/null; return; fi status 1 "verifying test vectors"; if diff -waq vectors_$ext "$srcdir/$vectors" > /dev/null; then status 1; rm -f vectors_$ext; else if diff -wad vectors_$ext "$srcdir/$vectors" \ | grep '<' > /dev/null; then status 1; mv info_current info_$ext; error 0 "vectors do not match. check vectors_$ext."; $make clean &> /dev/null; return; else status 1; warning 1 "vectors are incomplete but match."; rm -f vectors_$ext; fi fi detailed=false; for flags in "-s -k -p" "-s"; do status 1 "running speed measurements on $cpu_speed MHz CPU"; $run -c $cpu_speed $flags 2> /dev/null > speed_$ext; error=$?; cat >> speed_$ext < /dev/null; return; fi [ -r fastest ] \ && [ $(echo "$cycles / $( 1.01" | bc -l) = 1 ] \ && break; [ "$detailed" = "true" ] && ([ ! -r fastest ] \ || [ $(echo "$cycles < $( fastest; detailed=true; done $make clean &> /dev/null; rm -f info_current info 1 "Current implementation of $name encrypts at $cycles cycles/byte." info 1 "Previous implementations reached $( Makefile; success=$(ls speed_${var}_${conf%%_*}_* 2> /dev/null | wc -l); failure=$(ls {errors,vectors}_${var}_${conf%%_*}_* 2> /dev/null | wc -l); if [ "$success" = "0" -a "$failure" -ge "5" ]; then error 0 "This implementation seems to be buggy. Please fix it first."; return; fi make variants &> /dev/null; for var in $( /dev/null || run $srcdir $var $conf; done } # ----------------------------------------------------------------------------- for conf in $(cd "$reports/configs"; ls *.mk); do tag=$(awk '/tag = / { print $3; exit; }' "$reports/configs/$conf"); score=$(awk '/ '$tag'$/ { print $1; exit; }' "$reports/shortlist"); echo $((score + 0)) ${conf%.mk}; done | sort -rn | while read score conf; do info 1 "Testing $conf configuration (score: $score)."; process_dir "$srcdir" "$dstdir" $conf < /dev/null; done # -----------------------------------------------------------------------------