#!/usr/bin/perl use strict; use warnings; my $nvidia_cache = "~/.nv"; my $amd_cache = "~/.AMD"; my $hashcat_path = "."; my $kernels_cache = "$hashcat_path/kernels"; my $hashcat_bin = "$hashcat_path/hashcat"; my $device = 1; my $workload_profile = 3; my $runtime = 24; my $sleep_sec = 12; my $default_mask = "?b?b?b?b?b?b?b"; my $result = "result.txt"; my $old_hashcat = 0; # requires to have ran with new hashcat before to create the hashfiles my $repeats = 1; my $cpu_benchmark = 0; print "\nHardware preparations... You may need to adjust some settings and probably can ignore some of the error\n\n"; system ("echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor"); if ($cpu_benchmark == 1) { system ("echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo"); ## for CPU benchmark Intel system ("echo 0 > /sys/devices/system/cpu/cpufreq/boost"); ## for CPU benchmark AMD } else { system ("rocm-smi --resetprofile --resetclocks --resetfans"); system ("rocm-smi --setfan 100% --setperflevel high"); system ("nvidia-smi -rac"); system ("nvidia-smi -pm ENABLED"); system ("nvidia-smi -acp UNRESTRICTED"); system ("nvidia-smi -pl 1"); ## needs per-gpu adjust system ("nvidia-settings -a GPUPowerMizerMode=1 -a GPUFanControlState=1 -a GPUTargetFanSpeed=100"); } print "\n\nStarting...\n\n"; system ("rm -rf $nvidia_cache"); system ("rm -rf $amd_cache"); system ("rm -rf $kernels_cache"); my @hash_types_selection = ( 0, 100, 1400, 1700, 16800, 1000, 3000, 5500, 5600, 1500, 500, 3200, 1800, 7500, 13100, 15300, 15900, 7100, 11600, 12500, 13000, 6241, 13400, 6800, 11300, ); my @hash_types = ( 0, 20, 50, 60, 100, 120, 150, 160, 200, 300, 400, 500, 600, 900, 1000, 1100, 1300, 1400, 1420, 1450, 1460, 1500, 1600, 1700, 1720, 1750, 1760, 1800, 2100, 2400, 2410, 2500, 2501, 2611, 2711, 2811, 3000, 3100, 3200, 3710, 3800, 3910, 4010, 4110, 4300, 4400, 4500, 4520, 4700, 4800, 4900, 5100, 5200, 5300, 5400, 5500, 5600, 5800, 6000, 6100, 6211, 6221, 6231, 6241, 6300, 6400, 6500, 6600, 6700, 6800, 6900, 7000, 7100, 7300, 7400, 7500, 7700, 7701, 7800, 7801, 7900, 8000, 8100, 8200, 8300, 8400, 8500, 8600, 8700, 8800, 8900, 9000, 9100, 9400, 9500, 9600, 9700, 9710, 9720, 9800, 9810, 9820, 9900, 10100, 10300, 10400, 10410, 10420, 10500, 10700, 10800, 10900, 11000, 11100, 11200, 11300, 11400, 11500, 11600, 11700, 11750, 11760, 11800, 11850, 11860, 11900, 12000, 12200, 12300, 12400, 12500, 12600, 12700, 12800, 12900, 13000, 13100, 13200, 13300, 13400, 13500, 13600, 13711, 13721, 13731, 13741, 13751, 13761, 13771, 13800, 13900, 14000, 14100, 14400, 14700, 14800, 14900, 15000, 15100, 15300, 15400, 15500, 15600, 15900, 16000, 16100, 16200, 16300, 16400, 16600, 16800, 16801, 16900, 17300, 17400, 17500, 17600, 17700, 17800, 17900, 18000, 18100, 18200, 18300, 18400, 18500, 18600, 18700, 18800, 18900, 19000, 19100, 19200, 19300, 19500, 19600, 19700, 19800, 19900, 20011, 20012, 20013, 20500, 20510, ); if (scalar @ARGV) { @hash_types = @ARGV; } unlink ($result); chdir ($hashcat_path); for my $hash_type (@hash_types) { # banchmark always in optimized mode with single hash and mask! my $mask = $default_mask; if ($old_hashcat == 0) { my $module = get_module ($hash_type); my $st_hash = $module->{"st_hash"}; my $is_binary = $module->{"is_binary"}; open (OUT, ">", "tmp.hash.$hash_type") or die; if ($is_binary) { print OUT pack ("H*", $st_hash), "\n"; } else { print OUT "$st_hash\n"; } close (OUT); $mask = $module->{"mask"}; } my @command = ( $hashcat_bin, "--quiet", "tmp.hash.$hash_type", "--keep-guessing", "--self-test-disable", "--markov-disable", "--restore-disable", "--outfile-autohex-disable", "--wordlist-autohex-disable", "--potfile-disable", "--logfile-disable", "--hwmon-disable", "--status", "--status-timer", 1, "--runtime", $runtime, "--machine-readable", "--optimized-kernel-enable", "--workload-profile", $workload_profile, "--hash-type", $hash_type, "--attack-mode", 3, $mask ); if ($cpu_benchmark == 1) { push (@command, "--opencl-device-types", 1); } else { push (@command, "--backend-devices", $device); } print "Executing command: ", join (" ", @command), "\n"; my $final_speed = 0; for (my $i = 0; $i <= $repeats; $i++) { printf ("Run #%d\n", $i); open (IN, "-|", @command, "--runtime", 1); close (IN); my $was_slower = 0; my $speed = 0; my $sample = 0; open (IN, "-|", @command); while (my $line = ) { chomp $line; print "$line\n"; my @data = split "\t", $line; next unless defined $data[1]; next if ($data[1] != '3'); $sample++; if ($sample > 5) { if ($data[3] > $speed) { $speed = $data[3]; } else { $was_slower++; last if ($was_slower == 3); } } } close (IN); sleep ($sleep_sec); $final_speed = $speed if ($speed > $final_speed); } open (OUT, ">>", $result) or die; print OUT $final_speed, "\n"; close (OUT); } sub get_module { my $hash_type = shift; my $st_hash = undef; my $is_binary = 0; my $pw_min = -1; my $pw_max = -1; my $path = sprintf ("src/modules/module_%05d.c", $hash_type); open (IN, $path) or die; while (my $line = ) { chomp $line; if ($line =~ /OPTS_TYPE_BINARY_HASHFILE/) { $is_binary = 1; } if ($line =~ /ST_HASH *= \"(.*)\"/) { $st_hash = $1; } if ($line =~ /const u32 pw_min = (\d+);/) { $pw_min = $1; } if ($line =~ /const u32 pw_max = (\d+);/) { $pw_max = $1; } } close (IN); my $mask = $default_mask; if ($pw_min != -1) { if ($pw_min < 7) { $mask = substr ($mask, 0, $pw_min * 2); } else { my $left = $pw_min - 7; $mask .= "x" x $left; } } elsif ($pw_max != -1) { if ($pw_max < 7) { $mask = substr ($mask, 0, $pw_min * 2); } } my $module = { "is_binary" => $is_binary, "st_hash" => $st_hash, "mask" => $mask, }; return $module; }