1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-08-04 12:56:00 +00:00
hashcat/tools/test_modules/m34200.pm

157 lines
2.8 KiB
Perl
Executable File

#!/usr/bin/env perl
##
## Author......: See docs/credits.txt
## License.....: MIT
##
use strict;
use warnings;
use Math::BigInt;
sub module_constraints { [[0, 256], [16, 16], [0, 64], [16, 16], [-1, -1]] }
my $u64_width = Math::BigInt->new ("0x10000000000000000"); # 2**64
# Ensure that uint64 integer overflow is replicated correctly
sub wrapping_mul
{
my $a = shift;
my $b = shift;
return ($a * $b)->bmod ($u64_width);
}
my $m = Math::BigInt->new ("0xc6a4a7935bd1e995");
my $r = 47;
sub murmurhash64a
{
use integer;
my $word = shift;
my $seed = shift;
my @chars = unpack ("C*", $word);
my $len = length $word;
my $hash = $seed ^ wrapping_mul ($len, $m);
my $endpos = $len - ($len & 7);
my $i;
for ($i = 0; $i < $endpos; $i += 8)
{
my $c0 = $chars[$i + 0];
my $c1 = $chars[$i + 1];
my $c2 = $chars[$i + 2];
my $c3 = $chars[$i + 3];
my $c4 = $chars[$i + 4];
my $c5 = $chars[$i + 5];
my $c6 = $chars[$i + 6];
my $c7 = $chars[$i + 7];
my $k = ($c0 << 0)
| ($c1 << 8)
| ($c2 << 16)
| ($c3 << 24)
| ($c4 << 32)
| ($c5 << 40)
| ($c6 << 48)
| ($c7 << 56);
$k = wrapping_mul ($k, $m);
$k ^= $k >> $r;
$k = wrapping_mul ($k, $m);
$hash ^= $k;
$hash = wrapping_mul ($hash, $m);
}
my $overflow = $len & 7;
if ($overflow == 7)
{
$hash ^= $chars[$i + 6] << 48;
}
if ($overflow >= 6)
{
$hash ^= $chars[$i + 5] << 40;
}
if ($overflow >= 5)
{
$hash ^= $chars[$i + 4] << 32;
}
if ($overflow >= 4)
{
$hash ^= $chars[$i + 3] << 24;
}
if ($overflow >= 3)
{
$hash ^= $chars[$i + 2] << 16;
}
if ($overflow >= 2)
{
$hash ^= $chars[$i + 1] << 8;
}
if ($overflow >= 1)
{
$hash ^= $chars[$i + 0] << 0;
}
if ($overflow > 0)
{
$hash = wrapping_mul ($hash, $m);
}
$hash ^= $hash >> $r;
$hash = wrapping_mul ($hash, $m);
$hash ^= $hash >> $r;
return $hash;
}
sub module_generate_hash
{
my $word = shift;
my $salt = shift;
my $salt_bin = pack ("H*", $salt);
my $seed = unpack ("Q>", $salt_bin);
my $digest = murmurhash64a ($word, $seed);
$digest = unpack ("H*", pack ("Q>", $digest));
my $hash = sprintf ("%s:%016x", $digest, $seed);
return $hash;
}
sub module_verify_hash
{
my $line = shift;
my ($hash, $seed, $word) = split (':', $line, 3);
return unless defined $hash;
return unless defined $seed;
return unless defined $word;
return unless length $hash == 16;
return unless length $seed == 16;
return unless ($hash =~ m/^[0-9a-fA-F]{16}$/);
return unless ($seed =~ m/^[0-9a-fA-F]{16}$/);
my $word_packed = pack_if_HEX_notation ($word);
my $seed_packed = pack_if_HEX_notation ($seed);
my $new_hash = module_generate_hash ($word_packed, $seed_packed);
return ($new_hash, $word);
}
1;