1#!/usr/bin/env perl 2 3## 4## Author......: See docs/credits.txt 5## License.....: MIT 6## 7 8use strict; 9use warnings; 10 11use Digest::SHA qw (sha1); 12use Digest::HMAC qw (hmac_hex); 13 14sub module_constraints { [[0, 256], [8, 12], [-1, -1], [-1, -1], [-1, -1]] } 15 16sub module_generate_hash 17{ 18 my $word = shift; 19 my $salt = shift; 20 21 my $padded_time = sprintf ("%016x", int (int ($salt) / 30)); 22 my $data = pack ('H*', $padded_time); 23 my $key = $word; 24 25 my $digest = hmac_hex ($data, $key, \&sha1, 64); 26 27 my $offset = hex (substr ($digest, -8)) & 0xf; 28 $offset *= 2; 29 30 my $token = hex (substr ($digest, $offset, 8)); 31 $token &= 0x7fffffff; 32 $token %= 1000000; 33 34 # token must be leading zero padded, and salt leading zero stripped 35 my $hash = sprintf ("%06d:%d", $token, int ($salt)); 36 37 return $hash; 38} 39 40sub module_verify_hash 41{ 42 my $line = shift; 43 44 my ($hash, $salt, $word) = split (':', $line); 45 46 return unless defined $hash; 47 return unless defined $salt; 48 return unless defined $word; 49 50 my $word_packed = pack_if_HEX_notation ($word); 51 52 my $new_hash = module_generate_hash ($word_packed, $salt); 53 54 return ($new_hash, $word); 55} 56 571; 58