#!/usr/bin/env perl

##
## Author......: See docs/credits.txt
## License.....: MIT
##

use strict;
use warnings;

use Digest::SHA  qw (sha1);
use Digest::HMAC qw (hmac);
use MIME::Base64 qw (encode_base64url);
use JSON         qw (encode_json);

sub module_constraints { [[0, 64], [-1, -1], [-1, -1], [-1, -1], [-1, -1]] }

sub module_generate_hash
{
  my $word = shift;
  my $salt = shift || get_random_flask_salt ();

  # https://github.com/hashcat/hashcat/issues/3239
  #first = HMACSHA1(key=secret, message="cookie-session").digest() // "cookie-session" is a constant; digest is raw digest bytes
  #second = HMACSHA1(key=first, message=message).digest()

  my $digest1 = hmac ("cookie-session", $word, \&sha1);

  my $digest2 = hmac ($salt, $digest1, \&sha1);

  my $hash = sprintf ("%s.%s", $salt, encode_base64url ($digest2, ""));

  return $hash;
}

sub module_verify_hash
{
  my $line = shift;

  my ($hash, $word) = split (':', $line);

  return unless defined $hash;
  return unless defined $word;

  my @data = split (/\./, $hash);

  return unless scalar @data == 3;

  my ($header, $payload, $signature) = @data;

  my $salt = $header . "." . $payload;

  my $word_packed = pack_if_HEX_notation ($word);

  my $new_hash = module_generate_hash ($word_packed, $salt);

  return ($new_hash, $word);
}

sub get_random_flask_salt
{
  my $username = random_number (10000, 99999);

  my $header =
  {
    "username" => $username
  };

  my $header_json = encode_json ($header);

  my $header_base64  = encode_base64url ($header_json, "");

  return $header_base64 . "." . "YjdgRQ";
}

1;