using System;
using SecurityDriven.Inferno;
using SecurityDriven.Inferno.Extensions;

namespace HMAC_final {
    class Program {
        static void Main(string[] args) {
            // Generate key
            var rng = new CryptoRandom();
            var key = rng.NextBytes(32);
            Console.WriteLine($"Signing key: {key.ToBase16()}");
            Console.WriteLine();

            // Get message to sign
            Console.Write("Enter message to sign: ");
            var messageString = Console.ReadLine();
            var message = messageString.ToBytes();

            // Sign the message
            using (var hmac = SuiteB.HmacFactory()) {
                hmac.Key = key;
                var sig = hmac.ComputeHash(message);
                Console.WriteLine($"Signature: {sig.ToBase16()}");
            }
            Console.WriteLine();

            // Get message to verify
            Console.Write("Enter message to verify (or just ENTER for original one): ");
            var verifyMessageString = Console.ReadLine();
            if (string.IsNullOrEmpty(verifyMessageString)) verifyMessageString = messageString;
            var verifyMessage = verifyMessageString.ToBytes();

            // Get received signature
            Console.Write("Enter received signature: ");
            var recSigString = Console.ReadLine();
            var recSig = recSigString.FromBase16();

            // Get correct signature
            using (var hmac = SuiteB.HmacFactory()) {
                hmac.Key = key;
                var sig = hmac.ComputeHash(verifyMessage);
                Console.WriteLine($"Computed signature: {sig.ToBase16()}");

                // Verify signature
                var sigValid = Utils.ConstantTimeEqual(sig, recSig);
                if (sigValid) {
                    Console.WriteLine("Signature is valid.");
                } else {
                    Console.WriteLine("Signature is invalid.");
                }
            }

        }
    }
}
