private unsafe IntPtr DigestHmac(int digestLength, ProtectedMemory key, byte[] message)
        {
            Blake2bHashState blake2 = default;

            blake2.Init(digestLength, key);
            int length = message.Length;

            fixed(byte *input = message)
            {
                blake2.Update(input, length);
            }

            IntPtr hash = blake2.Finish();

            blake2.Free();
            return(hash);
        }
        private unsafe IntPtr Digest(int digestLength, ProtectedMemory protectedMemory)
        {
            Blake2bHashState blake2 = default;

            blake2.Init(digestLength, null);
            int    length = protectedMemory.ContentLength;
            IntPtr hInput = Marshal.AllocHGlobal(length);

            using (ProtectedMemoryAccess access = new ProtectedMemoryAccess(protectedMemory))
            {
                MarshalExtensions.Copy(access.Handle, 0, hInput, 0, length);
            }
            byte *input = (byte *)hInput;

            blake2.Update(input, length);
            MarshalExtensions.ZeroMemory(hInput, length);
            Marshal.FreeHGlobal(hInput);
            IntPtr hash = blake2.Finish();

            blake2.Free();
            return(hash);
        }