Decompiled source of NaCl Net v0.1.1300

BepInEx/core/NaCl.Net/netstandard2.1/NaCl.dll

Decompiled 3 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using Microsoft.CodeAnalysis;
using NaCl.Internal;
using NetMQ.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("NaCl.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010067b1aa21413f594425a88383ca09bcc62c34092da0cde540f8929cc026e39cf5f862faa23d96616e7050b23fd431a1007a0866c9e08aa8b1d5fdc5021f09b5302bb8545f4db589c60622f5a31d718896af939388230dd3d407fffa623dd7e75f6fef38da5bcba0b1d109f7f5ad64344bd24b995c744ca704640f511aa3ee3ba7")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Doron Somech")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Port of Curve25519, XSalsa20 and Poly1305 from NaCl project")]
[assembly: AssemblyFileVersion("0.1.13.0")]
[assembly: AssemblyInformationalVersion("0.1.13")]
[assembly: AssemblyProduct("NaCl")]
[assembly: AssemblyTitle("NaCl")]
[assembly: AssemblyVersion("0.1.13.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace NaCl
{
	public static class Curve25519
	{
		public const int ScalarLength = 32;

		public static void ScalarMultiplication(Span<byte> q, ReadOnlySpan<byte> n, ReadOnlySpan<byte> p)
		{
			Span<byte> span = q;
			Span<int> span2 = stackalloc int[10];
			Span<int> span3 = stackalloc int[10];
			Span<int> span4 = stackalloc int[10];
			Span<int> span5 = stackalloc int[10];
			Span<int> span6 = stackalloc int[10];
			Span<int> span7 = stackalloc int[10];
			Span<int> span8 = stackalloc int[10];
			for (int i = 0; i < 32; i++)
			{
				span[i] = n[i];
			}
			span[0] &= 248;
			span[31] &= 127;
			span[31] |= 64;
			Fe25519.FromBytes(span2, p);
			Fe25519.One(span3);
			Fe25519.Zero(span4);
			Fe25519.Copy(span5, span2);
			Fe25519.One(span6);
			int num = 0;
			for (int num2 = 254; num2 >= 0; num2--)
			{
				int num3 = span[num2 / 8] >> (num2 & 7);
				num3 &= 1;
				num ^= num3;
				Fe25519.CSwap(span3, span5, num);
				Fe25519.CSwap(span4, span6, num);
				num = num3;
				Fe25519.Sub(span7, span5, span6);
				Fe25519.Sub(span8, span3, span4);
				Fe25519.Add(span3, span3, span4);
				Fe25519.Add(span4, span5, span6);
				Fe25519.Mul(span6, span7, span3);
				Fe25519.Mul(span4, span4, span8);
				Fe25519.Sq(span7, span8);
				Fe25519.Sq(span8, span3);
				Fe25519.Add(span5, span6, span4);
				Fe25519.Sub(span4, span6, span4);
				Fe25519.Mul(span3, span8, span7);
				Fe25519.Sub(span8, span8, span7);
				Fe25519.Sq(span4, span4);
				Fe25519.Mul121666(span6, span8);
				Fe25519.Sq(span5, span5);
				Fe25519.Add(span7, span7, span6);
				Fe25519.Mul(span6, span2, span4);
				Fe25519.Mul(span4, span8, span7);
			}
			Fe25519.CSwap(span3, span5, num);
			Fe25519.CSwap(span4, span6, num);
			Fe25519.Invert(span4, span4);
			Fe25519.Mul(span3, span3, span4);
			Fe25519.ToBytes(q, span3);
		}

		public static byte[] ScalarMultiplication(ReadOnlySpan<byte> n, ReadOnlySpan<byte> p)
		{
			byte[] array = new byte[32];
			ScalarMultiplication(array, n, p);
			return array;
		}

		public static byte[] ScalarMultiplication(byte[] n, byte[] p)
		{
			return ScalarMultiplication(new Span<byte>(n, 0, 32), new Span<byte>(p, 0, 32));
		}

		public static void ScalarMultiplication(byte[] q, byte[] n, byte[] p)
		{
			ScalarMultiplication(new Span<byte>(q, 0, 32), new Span<byte>(n, 0, 32), new Span<byte>(p, 0, 32));
		}

		public static void ScalarMultiplication(byte[] q, int qOffset, byte[] n, int nOffset, byte[] p, int pOffset)
		{
			ScalarMultiplication(new Span<byte>(q, qOffset, 32), new Span<byte>(n, nOffset, 32), new Span<byte>(p, pOffset, 32));
		}

		public static void ScalarMultiplicationBase(Span<byte> q, Span<byte> n)
		{
			Span<byte> span = stackalloc byte[32];
			span[0] = 9;
			ScalarMultiplication(q, n, span);
		}

		public static void ScalarMultiplicationBase(byte[] q, byte[] n)
		{
			ScalarMultiplicationBase(new Span<byte>(q, 0, 32), new Span<byte>(n, 0, 32));
		}

		public static void ScalarMultiplicationBase(byte[] q, int qOffset, byte[] n, int nOffset)
		{
			ScalarMultiplicationBase(new Span<byte>(q, qOffset, 32), new Span<byte>(n, nOffset, 32));
		}

		public static byte[] ScalarMultiplicationBase(Span<byte> n)
		{
			byte[] array = new byte[32];
			ScalarMultiplicationBase(array, n);
			return array;
		}

		public static byte[] ScalarMultiplicationBase(byte[] n)
		{
			byte[] array = new byte[32];
			ScalarMultiplicationBase(array, n);
			return array;
		}
	}
	public class Curve25519XSalsa20Poly1305 : XSalsa20Poly1305
	{
		public const int SecretKeyLength = 32;

		public const int PublicKeyLength = 32;

		public Curve25519XSalsa20Poly1305(ReadOnlySpan<byte> secretKey, ReadOnlySpan<byte> publicKey)
		{
			ReadOnlySpan<byte> input = stackalloc byte[16];
			Span<byte> span = stackalloc byte[32];
			Curve25519.ScalarMultiplication(span, secretKey, publicKey);
			HSalsa20.Transform(key, input, span, Span<byte>.Empty);
			span.Clear();
		}

		public static void KeyPair(Span<byte> secretKey, Span<byte> publicKey)
		{
			if (secretKey.Length != 32)
			{
				throw new ArgumentException("secretKey length must be 32 bytes");
			}
			if (publicKey.Length != 32)
			{
				throw new ArgumentException("publicKey length must be 32 bytes");
			}
			using RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
			randomNumberGenerator.GetBytes(secretKey);
			Curve25519.ScalarMultiplicationBase(publicKey, secretKey);
		}

		public static void KeyPair(byte[] secretKey, byte[] publicKey)
		{
			KeyPair(new Span<byte>(secretKey), new Span<byte>(publicKey));
		}

		public static void KeyPair(out byte[] secretKey, out byte[] publicKey)
		{
			secretKey = new byte[32];
			publicKey = new byte[32];
			KeyPair(secretKey, publicKey);
		}

		public static (byte[], byte[]) KeyPair()
		{
			byte[] array = new byte[32];
			byte[] array2 = new byte[32];
			KeyPair(array, array2);
			return (array, array2);
		}
	}
	public class Poly1305 : IDisposable
	{
		private const int BlockLength = 16;

		public const int KeyLength = 32;

		public const int TagLength = 16;

		private uint[] r = new uint[5];

		private uint[] h = new uint[5];

		private uint[] pad = new uint[4];

		private int leftover;

		private byte[] buffer = new byte[16];

		private bool final;

		public Poly1305(ReadOnlySpan<byte> key)
		{
			Initialize();
			SetKey(key);
		}

		public Poly1305()
		{
			Initialize();
		}

		public void Dispose()
		{
			Reset();
		}

		public void Reset()
		{
			Array.Clear(r, 0, 5);
			Array.Clear(h, 0, 5);
			Array.Clear(pad, 0, 4);
			Array.Clear(buffer, 0, 16);
			leftover = 0;
			final = false;
		}

		public void SetKey(ReadOnlySpan<byte> key)
		{
			r[0] = Common.Load32(key, 0) & 0x3FFFFFFu;
			r[1] = (Common.Load32(key, 3) >> 2) & 0x3FFFF03u;
			r[2] = (Common.Load32(key, 6) >> 4) & 0x3FFC0FFu;
			r[3] = (Common.Load32(key, 9) >> 6) & 0x3F03FFFu;
			r[4] = (Common.Load32(key, 12) >> 8) & 0xFFFFFu;
			pad[0] = Common.Load32(key, 16);
			pad[1] = Common.Load32(key, 20);
			pad[2] = Common.Load32(key, 24);
			pad[3] = Common.Load32(key, 28);
		}

		public void SetKey(byte[] key, int offset)
		{
			SetKey(new Span<byte>(key, offset, 32));
		}

		private void Initialize()
		{
			h[0] = 0u;
			h[1] = 0u;
			h[2] = 0u;
			h[3] = 0u;
			h[4] = 0u;
			Array.Clear(buffer, 0, 16);
			leftover = 0;
			final = false;
		}

		private void Blocks(ReadOnlySpan<byte> m, int count)
		{
			uint num = ((!final) ? 16777216u : 0u);
			uint num2 = r[0];
			uint num3 = r[1];
			uint num4 = r[2];
			uint num5 = r[3];
			uint num6 = r[4];
			uint num7 = num3 * 5;
			uint num8 = num4 * 5;
			uint num9 = num5 * 5;
			uint num10 = num6 * 5;
			uint num11 = h[0];
			uint num12 = h[1];
			uint num13 = h[2];
			uint num14 = h[3];
			uint num15 = h[4];
			while (count >= 16)
			{
				num11 += Common.Load32(m, 0) & 0x3FFFFFF;
				num12 += (Common.Load32(m, 3) >> 2) & 0x3FFFFFF;
				num13 += (Common.Load32(m, 6) >> 4) & 0x3FFFFFF;
				num14 += (Common.Load32(m, 9) >> 6) & 0x3FFFFFF;
				num15 += (Common.Load32(m, 12) >> 8) | num;
				ulong num16 = (ulong)((long)num11 * (long)num2 + (long)num12 * (long)num10 + (long)num13 * (long)num9 + (long)num14 * (long)num8 + (long)num15 * (long)num7);
				ulong num17 = (ulong)((long)num11 * (long)num3 + (long)num12 * (long)num2 + (long)num13 * (long)num10 + (long)num14 * (long)num9 + (long)num15 * (long)num8);
				ulong num18 = (ulong)((long)num11 * (long)num4 + (long)num12 * (long)num3 + (long)num13 * (long)num2 + (long)num14 * (long)num10 + (long)num15 * (long)num9);
				ulong num19 = (ulong)((long)num11 * (long)num5 + (long)num12 * (long)num4 + (long)num13 * (long)num3 + (long)num14 * (long)num2 + (long)num15 * (long)num10);
				long num20 = (long)num11 * (long)num6 + (long)num12 * (long)num5 + (long)num13 * (long)num4 + (long)num14 * (long)num3 + (long)num15 * (long)num2;
				uint num21 = (uint)(num16 >> 26);
				num11 = (uint)(int)num16 & 0x3FFFFFFu;
				num17 += num21;
				num21 = (uint)(num17 >> 26);
				num12 = (uint)(int)num17 & 0x3FFFFFFu;
				num18 += num21;
				num21 = (uint)(num18 >> 26);
				num13 = (uint)(int)num18 & 0x3FFFFFFu;
				num19 += num21;
				num21 = (uint)(num19 >> 26);
				num14 = (uint)(int)num19 & 0x3FFFFFFu;
				long num22 = num20 + num21;
				num21 = (uint)((ulong)num22 >> 26);
				num15 = (uint)(int)num22 & 0x3FFFFFFu;
				num11 += num21 * 5;
				num21 = num11 >> 26;
				num11 &= 0x3FFFFFFu;
				num12 += num21;
				m = m.Slice(16);
				count -= 16;
			}
			h[0] = num11;
			h[1] = num12;
			h[2] = num13;
			h[3] = num14;
			h[4] = num15;
		}

		public void Final(Span<byte> tag)
		{
			if (leftover > 0)
			{
				int i = leftover;
				buffer[i++] = 1;
				for (; i < 16; i++)
				{
					buffer[i] = 0;
				}
				final = true;
				Blocks(buffer, 16);
			}
			uint num = h[0];
			uint num2 = h[1];
			uint num3 = h[2];
			uint num4 = h[3];
			uint num5 = h[4];
			uint num6 = num2 >> 26;
			num2 &= 0x3FFFFFFu;
			num3 += num6;
			num6 = num3 >> 26;
			num3 &= 0x3FFFFFFu;
			num4 += num6;
			num6 = num4 >> 26;
			num4 &= 0x3FFFFFFu;
			num5 += num6;
			num6 = num5 >> 26;
			num5 &= 0x3FFFFFFu;
			num += num6 * 5;
			num6 = num >> 26;
			num &= 0x3FFFFFFu;
			num2 += num6;
			uint num7 = num + 5;
			num6 = num7 >> 26;
			num7 &= 0x3FFFFFFu;
			uint num8 = num2 + num6;
			num6 = num8 >> 26;
			num8 &= 0x3FFFFFFu;
			uint num9 = num3 + num6;
			num6 = num9 >> 26;
			num9 &= 0x3FFFFFFu;
			uint num10 = num4 + num6;
			num6 = num10 >> 26;
			num10 &= 0x3FFFFFFu;
			uint num11 = num5 + num6 - 67108864;
			uint num12 = (num11 >> 31) - 1;
			num7 &= num12;
			num8 &= num12;
			num9 &= num12;
			num10 &= num12;
			num11 &= num12;
			num12 = ~num12;
			num = (num & num12) | num7;
			num2 = (num2 & num12) | num8;
			num3 = (num3 & num12) | num9;
			num4 = (num4 & num12) | num10;
			num5 = (num5 & num12) | num11;
			num = (num | (num2 << 26)) & 0xFFFFFFFFu;
			num2 = ((num2 >> 6) | (num3 << 20)) & 0xFFFFFFFFu;
			num3 = ((num3 >> 12) | (num4 << 14)) & 0xFFFFFFFFu;
			num4 = ((num4 >> 18) | (num5 << 8)) & 0xFFFFFFFFu;
			ulong num13 = (ulong)num + (ulong)pad[0];
			num = (uint)num13;
			num13 = (ulong)((long)num2 + (long)pad[1]) + (num13 >> 32);
			num2 = (uint)num13;
			num13 = (ulong)((long)num3 + (long)pad[2]) + (num13 >> 32);
			num3 = (uint)num13;
			num13 = (ulong)((long)num4 + (long)pad[3]) + (num13 >> 32);
			num4 = (uint)num13;
			Common.Store(tag, 0, num);
			Common.Store(tag, 4, num2);
			Common.Store(tag, 8, num3);
			Common.Store(tag, 12, num4);
			Initialize();
		}

		public void Update(ReadOnlySpan<byte> bytes)
		{
			int num = bytes.Length;
			if (leftover != 0)
			{
				int num2 = 16 - leftover;
				if (num2 > num)
				{
					num2 = num;
				}
				for (int i = 0; i < num2; i++)
				{
					buffer[leftover + i] = bytes[i];
				}
				num -= num2;
				bytes = bytes.Slice(num2);
				leftover += num2;
				if (leftover < 16)
				{
					return;
				}
				Blocks(buffer, 16);
				leftover = 0;
			}
			if (num >= 16)
			{
				int num3 = num & -16;
				Blocks(bytes, num3);
				bytes = bytes.Slice(num3);
				num -= num3;
			}
			if (num > 0)
			{
				for (int j = 0; j < num; j++)
				{
					buffer[leftover + j] = bytes[j];
				}
				leftover += num;
			}
		}

		public void Update(byte[] bytes, int offset, int count)
		{
			Span<byte> span = new Span<byte>(bytes, offset, count);
			Update(span);
		}

		public byte[] Final()
		{
			byte[] array = new byte[16];
			Final(array);
			return array;
		}

		public bool Verify(ReadOnlySpan<byte> tag, ReadOnlySpan<byte> input)
		{
			Update(input);
			byte[] array = Final();
			return SafeComparison.Verify16(tag, array);
		}

		public bool Verify(byte[] tag, int tagOffset, byte[] input, int inputOffset, int inputCount)
		{
			Span<byte> span = new Span<byte>(tag, tagOffset, 16);
			return Verify(input: new Span<byte>(input, inputOffset, inputCount), tag: span);
		}
	}
	public class XSalsa20 : IDisposable
	{
		public const int KeyLength = 32;

		public const int NonceLength = 24;

		private byte[] key;

		public XSalsa20(ReadOnlySpan<byte> key)
		{
			if (key.Length != 32)
			{
				throw new ArgumentException("key length must be 32 bytes");
			}
			this.key = key.ToArray();
		}

		public XSalsa20(byte[] key)
		{
			if (key.Length != 32)
			{
				throw new ArgumentException("key length must be 32 bytes");
			}
			this.key = (byte[])key.Clone();
		}

		public void Dispose()
		{
			Array.Clear(key, 0, 32);
		}

		public void Transform(Span<byte> output, ReadOnlySpan<byte> input, ReadOnlySpan<byte> nonce)
		{
			Span<byte> span = stackalloc byte[32];
			HSalsa20.Transform(span, nonce, key, Span<byte>.Empty);
			StreamSalsa20Xor.Transform(output, input, nonce.Slice(16), span, 0uL);
		}

		public void Transform(byte[] output, int outputOffset, byte[] input, int inputOffset, int inputCount, byte[] nonce, int nonceOffset)
		{
			Transform(new Span<byte>(output, outputOffset, inputCount), new ReadOnlySpan<byte>(input, inputOffset, inputCount), new ReadOnlySpan<byte>(nonce, nonceOffset, 24));
		}
	}
	public class XSalsa20Poly1305 : IDisposable
	{
		private const int ZeroBytesLength = 32;

		public const int KeyLength = 32;

		public const int TagLength = 16;

		public const int NonceLength = 24;

		private Poly1305 poly1305;

		internal byte[] key;

		public XSalsa20Poly1305(ReadOnlySpan<byte> key)
		{
			if (key.Length != 32)
			{
				throw new ArgumentException("key length must be 32 bytes");
			}
			this.key = key.ToArray();
			poly1305 = new Poly1305();
		}

		public XSalsa20Poly1305(byte[] key)
		{
			if (key.Length != 32)
			{
				throw new ArgumentException("key length must be 32 bytes");
			}
			this.key = (byte[])key.Clone();
			poly1305 = new Poly1305();
		}

		internal XSalsa20Poly1305()
		{
			poly1305 = new Poly1305();
			key = new byte[32];
		}

		public void Encrypt(Span<byte> cipher, Span<byte> mac, ReadOnlySpan<byte> message, ReadOnlySpan<byte> nonce)
		{
			Span<byte> c = stackalloc byte[64];
			Span<byte> span = stackalloc byte[32];
			HSalsa20.Transform(span, nonce, key, ReadOnlySpan<byte>.Empty);
			int num = message.Length;
			if (num > 32)
			{
				num = 32;
			}
			for (int i = 0; i < num; i++)
			{
				c[i + 32] = message[i];
			}
			StreamSalsa20Xor.Transform(c, c.Slice(0, num + 32), nonce.Slice(16), span, 0uL);
			poly1305.SetKey(c.Slice(0, 32));
			for (int j = 0; j < num; j++)
			{
				cipher[j] = c[32 + j];
			}
			c.Clear();
			if (message.Length > num)
			{
				StreamSalsa20Xor.Transform(cipher.Slice(num), message.Slice(num), nonce.Slice(16), span, 1uL);
			}
			span.Clear();
			poly1305.Update(cipher.Slice(0, message.Length));
			poly1305.Final(mac);
			poly1305.Reset();
		}

		public void Encrypt(byte[] cipher, int cipherOffset, byte[] mac, int macOffset, byte[] message, int messageOffset, int messageCount, byte[] nonce, int nonceOffset)
		{
			Encrypt(new Span<byte>(cipher, cipherOffset, messageCount), new Span<byte>(mac, macOffset, 16), new ReadOnlySpan<byte>(message, messageOffset, messageCount), new ReadOnlySpan<byte>(nonce, nonceOffset, 24));
		}

		public void Encrypt(Span<byte> cipher, ReadOnlySpan<byte> message, ReadOnlySpan<byte> nonce)
		{
			Encrypt(cipher.Slice(16), cipher.Slice(0, 16), message, nonce);
		}

		public void Encrypt(byte[] cipher, int cipherOffset, byte[] message, int messageOffset, int messageCount, byte[] nonce, int nonceOffset)
		{
			Encrypt(new Span<byte>(cipher, cipherOffset + 16, messageCount), new Span<byte>(cipher, cipherOffset, 16), new ReadOnlySpan<byte>(message, messageOffset, messageCount), new ReadOnlySpan<byte>(nonce, nonceOffset, 24));
		}

		public bool TryDecrypt(Span<byte> message, ReadOnlySpan<byte> cipher, ReadOnlySpan<byte> mac, ReadOnlySpan<byte> nonce)
		{
			Span<byte> c = stackalloc byte[64];
			Span<byte> span = stackalloc byte[32];
			HSalsa20.Transform(span, nonce, key, ReadOnlySpan<byte>.Empty);
			StreamSalsa20.Transform(c.Slice(0, 32), nonce.Slice(16), span);
			poly1305.SetKey(c.Slice(0, 32));
			if (!poly1305.Verify(mac, cipher))
			{
				poly1305.Reset();
				span.Clear();
				return false;
			}
			int num = cipher.Length;
			if (num > 32)
			{
				num = 32;
			}
			for (int i = 0; i < num; i++)
			{
				c[32 + i] = cipher[i];
			}
			StreamSalsa20Xor.Transform(c, c.Slice(0, 32 + num), nonce.Slice(16), span, 0uL);
			for (int j = 0; j < num; j++)
			{
				message[j] = c[j + 32];
			}
			if (cipher.Length > num)
			{
				StreamSalsa20Xor.Transform(message.Slice(num), cipher.Slice(num), nonce.Slice(16), span, 1uL);
			}
			span.Clear();
			poly1305.Reset();
			return true;
		}

		public bool TryDecrypt(byte[] message, int messageOffset, byte[] cipher, int cipherOffset, int cipherCount, byte[] mac, int macOffset, byte[] nonce, int nonceOffset)
		{
			return TryDecrypt(new Span<byte>(message, messageOffset, cipherCount), new ReadOnlySpan<byte>(cipher, cipherOffset, cipherCount), new ReadOnlySpan<byte>(mac, macOffset, 16), new ReadOnlySpan<byte>(nonce, nonceOffset, 24));
		}

		public bool TryDecrypt(Span<byte> message, ReadOnlySpan<byte> cipher, ReadOnlySpan<byte> nonce)
		{
			return TryDecrypt(message, cipher.Slice(16), cipher.Slice(0, 16), nonce);
		}

		public bool TryDecrypt(byte[] message, int messageOffset, byte[] cipher, int cipherOffset, int cipherCount, byte[] nonce, int nonceOffset)
		{
			return TryDecrypt(new Span<byte>(message, messageOffset, cipherCount - 16), new ReadOnlySpan<byte>(cipher, cipherOffset, cipherCount), new ReadOnlySpan<byte>(nonce, nonceOffset, 24));
		}

		public void Dispose()
		{
			Array.Clear(key, 0, key.Length);
			poly1305.Dispose();
		}
	}
}
namespace NaCl.Internal
{
	internal static class Common
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint Load32(byte[] src, int offset)
		{
			return (uint)(src[offset] | (src[offset + 1] << 8) | (src[offset + 2] << 16) | (src[offset + 3] << 24));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint Load32(ReadOnlySpan<byte> src, int offset)
		{
			return (uint)(src[offset] | (src[offset + 1] << 8) | (src[offset + 2] << 16) | (src[offset + 3] << 24));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Store(byte[] dst, int offset, uint w)
		{
			dst[offset] = (byte)w;
			w >>= 8;
			dst[offset + 1] = (byte)w;
			w >>= 8;
			dst[offset + 2] = (byte)w;
			w >>= 8;
			dst[offset + 3] = (byte)w;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Store(Span<byte> dst, int offset, uint w)
		{
			dst[offset] = (byte)w;
			w >>= 8;
			dst[offset + 1] = (byte)w;
			w >>= 8;
			dst[offset + 2] = (byte)w;
			w >>= 8;
			dst[offset + 3] = (byte)w;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint RotateLeft(in uint x, in int b)
		{
			return (x << b) | (x >> 32 - b);
		}
	}
	internal static class Constants
	{
		public static readonly byte[] Sigma = new byte[16]
		{
			101, 120, 112, 97, 110, 100, 32, 51, 50, 45,
			98, 121, 116, 101, 32, 107
		};

		public static readonly byte[] N = new byte[32];

		public static readonly uint[] MinUsp;

		static Constants()
		{
			uint[] array = new uint[32];
			array[0] = 19u;
			array[31] = 128u;
			MinUsp = array;
		}
	}
	internal static class Fe25519
	{
		public const int ArraySize = 10;

		public static void Zero(Span<int> h)
		{
			h.Slice(0, 10).Fill(0);
		}

		public static void One(Span<int> h)
		{
			h[0] = 1;
			h.Slice(1, 9).Fill(0);
		}

		public static void Copy(Span<int> h, Span<int> f)
		{
			int num = f[0];
			int num2 = f[1];
			int num3 = f[2];
			int num4 = f[3];
			int num5 = f[4];
			int num6 = f[5];
			int num7 = f[6];
			int num8 = f[7];
			int num9 = f[8];
			int num10 = f[9];
			h[0] = num;
			h[1] = num2;
			h[2] = num3;
			h[3] = num4;
			h[4] = num5;
			h[5] = num6;
			h[6] = num7;
			h[7] = num8;
			h[8] = num9;
			h[9] = num10;
		}

		private static long Load3(ReadOnlySpan<byte> input)
		{
			return (long)(input[0] | ((ulong)input[1] << 8) | ((ulong)input[2] << 16));
		}

		private static long Load4(ReadOnlySpan<byte> input)
		{
			return (long)(input[0] | ((ulong)input[1] << 8) | ((ulong)input[2] << 16) | ((ulong)input[3] << 24));
		}

		public static void FromBytes(Span<int> h, ReadOnlySpan<byte> s)
		{
			long num = Load4(s);
			long num2 = Load3(s.Slice(4)) << 6;
			long num3 = Load3(s.Slice(7)) << 5;
			long num4 = Load3(s.Slice(10)) << 3;
			long num5 = Load3(s.Slice(13)) << 2;
			long num6 = Load4(s.Slice(16));
			long num7 = Load3(s.Slice(20)) << 7;
			long num8 = Load3(s.Slice(23)) << 5;
			long num9 = Load3(s.Slice(26)) << 4;
			long num10 = (Load3(s.Slice(29)) & 0x7FFFFF) << 2;
			long num11 = num10 + 16777216 >> 25;
			num += num11 * 19;
			num10 -= num11 << 25;
			long num12 = num2 + 16777216 >> 25;
			num3 += num12;
			num2 -= num12 << 25;
			long num13 = num4 + 16777216 >> 25;
			num5 += num13;
			num4 -= num13 << 25;
			long num14 = num6 + 16777216 >> 25;
			num7 += num14;
			num6 -= num14 << 25;
			long num15 = num8 + 16777216 >> 25;
			num9 += num15;
			num8 -= num15 << 25;
			long num16 = num + 33554432 >> 26;
			num2 += num16;
			num -= num16 << 26;
			long num17 = num3 + 33554432 >> 26;
			num4 += num17;
			num3 -= num17 << 26;
			long num18 = num5 + 33554432 >> 26;
			num6 += num18;
			num5 -= num18 << 26;
			long num19 = num7 + 33554432 >> 26;
			num8 += num19;
			num7 -= num19 << 26;
			long num20 = num9 + 33554432 >> 26;
			num10 += num20;
			num9 -= num20 << 26;
			h[0] = (int)num;
			h[1] = (int)num2;
			h[2] = (int)num3;
			h[3] = (int)num4;
			h[4] = (int)num5;
			h[5] = (int)num6;
			h[6] = (int)num7;
			h[7] = (int)num8;
			h[8] = (int)num9;
			h[9] = (int)num10;
		}

		public static void CSwap(Span<int> f, Span<int> g, int b)
		{
			int num = -b;
			int num2 = f[0];
			int num3 = f[1];
			int num4 = f[2];
			int num5 = f[3];
			int num6 = f[4];
			int num7 = f[5];
			int num8 = f[6];
			int num9 = f[7];
			int num10 = f[8];
			int num11 = f[9];
			int num12 = g[0];
			int num13 = g[1];
			int num14 = g[2];
			int num15 = g[3];
			int num16 = g[4];
			int num17 = g[5];
			int num18 = g[6];
			int num19 = g[7];
			int num20 = g[8];
			int num21 = g[9];
			int num22 = num2 ^ num12;
			int num23 = num3 ^ num13;
			int num24 = num4 ^ num14;
			int num25 = num5 ^ num15;
			int num26 = num6 ^ num16;
			int num27 = num7 ^ num17;
			int num28 = num8 ^ num18;
			int num29 = num9 ^ num19;
			int num30 = num10 ^ num20;
			int num31 = num11 ^ num21;
			num22 &= num;
			num23 &= num;
			num24 &= num;
			num25 &= num;
			num26 &= num;
			num27 &= num;
			num28 &= num;
			num29 &= num;
			num30 &= num;
			num31 &= num;
			f[0] = num2 ^ num22;
			f[1] = num3 ^ num23;
			f[2] = num4 ^ num24;
			f[3] = num5 ^ num25;
			f[4] = num6 ^ num26;
			f[5] = num7 ^ num27;
			f[6] = num8 ^ num28;
			f[7] = num9 ^ num29;
			f[8] = num10 ^ num30;
			f[9] = num11 ^ num31;
			g[0] = num12 ^ num22;
			g[1] = num13 ^ num23;
			g[2] = num14 ^ num24;
			g[3] = num15 ^ num25;
			g[4] = num16 ^ num26;
			g[5] = num17 ^ num27;
			g[6] = num18 ^ num28;
			g[7] = num19 ^ num29;
			g[8] = num20 ^ num30;
			g[9] = num21 ^ num31;
		}

		public static void Sub(Span<int> h, Span<int> f, Span<int> g)
		{
			int num = f[0] - g[0];
			int num2 = f[1] - g[1];
			int num3 = f[2] - g[2];
			int num4 = f[3] - g[3];
			int num5 = f[4] - g[4];
			int num6 = f[5] - g[5];
			int num7 = f[6] - g[6];
			int num8 = f[7] - g[7];
			int num9 = f[8] - g[8];
			int num10 = f[9] - g[9];
			h[0] = num;
			h[1] = num2;
			h[2] = num3;
			h[3] = num4;
			h[4] = num5;
			h[5] = num6;
			h[6] = num7;
			h[7] = num8;
			h[8] = num9;
			h[9] = num10;
		}

		public static void Add(Span<int> h, Span<int> f, Span<int> g)
		{
			int num = f[0] + g[0];
			int num2 = f[1] + g[1];
			int num3 = f[2] + g[2];
			int num4 = f[3] + g[3];
			int num5 = f[4] + g[4];
			int num6 = f[5] + g[5];
			int num7 = f[6] + g[6];
			int num8 = f[7] + g[7];
			int num9 = f[8] + g[8];
			int num10 = f[9] + g[9];
			h[0] = num;
			h[1] = num2;
			h[2] = num3;
			h[3] = num4;
			h[4] = num5;
			h[5] = num6;
			h[6] = num7;
			h[7] = num8;
			h[8] = num9;
			h[9] = num10;
		}

		public static void Mul(Span<int> h, Span<int> f, Span<int> g)
		{
			int num = f[0];
			int num2 = f[1];
			int num3 = f[2];
			int num4 = f[3];
			int num5 = f[4];
			int num6 = f[5];
			int num7 = f[6];
			int num8 = f[7];
			int num9 = f[8];
			int num10 = f[9];
			int num11 = g[0];
			int num12 = g[1];
			int num13 = g[2];
			int num14 = g[3];
			int num15 = g[4];
			int num16 = g[5];
			int num17 = g[6];
			int num18 = g[7];
			int num19 = g[8];
			int num20 = g[9];
			int num21 = 19 * num12;
			int num22 = 19 * num13;
			int num23 = 19 * num14;
			int num24 = 19 * num15;
			int num25 = 19 * num16;
			int num26 = 19 * num17;
			int num27 = 19 * num18;
			int num28 = 19 * num19;
			int num29 = 19 * num20;
			int num30 = 2 * num2;
			int num31 = 2 * num4;
			int num32 = 2 * num6;
			int num33 = 2 * num8;
			int num34 = 2 * num10;
			long num35 = (long)num * (long)num11;
			long num36 = (long)num * (long)num12;
			long num37 = (long)num * (long)num13;
			long num38 = (long)num * (long)num14;
			long num39 = (long)num * (long)num15;
			long num40 = (long)num * (long)num16;
			long num41 = (long)num * (long)num17;
			long num42 = (long)num * (long)num18;
			long num43 = (long)num * (long)num19;
			long num44 = (long)num * (long)num20;
			long num45 = (long)num2 * (long)num11;
			long num46 = (long)num30 * (long)num12;
			long num47 = (long)num2 * (long)num13;
			long num48 = (long)num30 * (long)num14;
			long num49 = (long)num2 * (long)num15;
			long num50 = (long)num30 * (long)num16;
			long num51 = (long)num2 * (long)num17;
			long num52 = (long)num30 * (long)num18;
			long num53 = (long)num2 * (long)num19;
			long num54 = (long)num30 * (long)num29;
			long num55 = (long)num3 * (long)num11;
			long num56 = (long)num3 * (long)num12;
			long num57 = (long)num3 * (long)num13;
			long num58 = (long)num3 * (long)num14;
			long num59 = (long)num3 * (long)num15;
			long num60 = (long)num3 * (long)num16;
			long num61 = (long)num3 * (long)num17;
			long num62 = (long)num3 * (long)num18;
			long num63 = (long)num3 * (long)num28;
			long num64 = (long)num3 * (long)num29;
			long num65 = (long)num4 * (long)num11;
			long num66 = (long)num31 * (long)num12;
			long num67 = (long)num4 * (long)num13;
			long num68 = (long)num31 * (long)num14;
			long num69 = (long)num4 * (long)num15;
			long num70 = (long)num31 * (long)num16;
			long num71 = (long)num4 * (long)num17;
			long num72 = (long)num31 * (long)num27;
			long num73 = (long)num4 * (long)num28;
			long num74 = (long)num31 * (long)num29;
			long num75 = (long)num5 * (long)num11;
			long num76 = (long)num5 * (long)num12;
			long num77 = (long)num5 * (long)num13;
			long num78 = (long)num5 * (long)num14;
			long num79 = (long)num5 * (long)num15;
			long num80 = (long)num5 * (long)num16;
			long num81 = (long)num5 * (long)num26;
			long num82 = (long)num5 * (long)num27;
			long num83 = (long)num5 * (long)num28;
			long num84 = (long)num5 * (long)num29;
			long num85 = (long)num6 * (long)num11;
			long num86 = (long)num32 * (long)num12;
			long num87 = (long)num6 * (long)num13;
			long num88 = (long)num32 * (long)num14;
			long num89 = (long)num6 * (long)num15;
			long num90 = (long)num32 * (long)num25;
			long num91 = (long)num6 * (long)num26;
			long num92 = (long)num32 * (long)num27;
			long num93 = (long)num6 * (long)num28;
			long num94 = (long)num32 * (long)num29;
			long num95 = (long)num7 * (long)num11;
			long num96 = (long)num7 * (long)num12;
			long num97 = (long)num7 * (long)num13;
			long num98 = (long)num7 * (long)num14;
			long num99 = (long)num7 * (long)num24;
			long num100 = (long)num7 * (long)num25;
			long num101 = (long)num7 * (long)num26;
			long num102 = (long)num7 * (long)num27;
			long num103 = (long)num7 * (long)num28;
			long num104 = (long)num7 * (long)num29;
			long num105 = (long)num8 * (long)num11;
			long num106 = (long)num33 * (long)num12;
			long num107 = (long)num8 * (long)num13;
			long num108 = (long)num33 * (long)num23;
			long num109 = (long)num8 * (long)num24;
			long num110 = (long)num33 * (long)num25;
			long num111 = (long)num8 * (long)num26;
			long num112 = (long)num33 * (long)num27;
			long num113 = (long)num8 * (long)num28;
			long num114 = (long)num33 * (long)num29;
			long num115 = (long)num9 * (long)num11;
			long num116 = (long)num9 * (long)num12;
			long num117 = (long)num9 * (long)num22;
			long num118 = (long)num9 * (long)num23;
			long num119 = (long)num9 * (long)num24;
			long num120 = (long)num9 * (long)num25;
			long num121 = (long)num9 * (long)num26;
			long num122 = (long)num9 * (long)num27;
			long num123 = (long)num9 * (long)num28;
			long num124 = (long)num9 * (long)num29;
			long num125 = (long)num10 * (long)num11;
			long num126 = (long)num34 * (long)num21;
			long num127 = (long)num10 * (long)num22;
			long num128 = (long)num34 * (long)num23;
			long num129 = (long)num10 * (long)num24;
			long num130 = (long)num34 * (long)num25;
			long num131 = (long)num10 * (long)num26;
			long num132 = (long)num34 * (long)num27;
			long num133 = (long)num10 * (long)num28;
			long num134 = (long)num34 * (long)num29;
			long num135 = num35 + num54 + num63 + num72 + num81 + num90 + num99 + num108 + num117 + num126;
			long num136 = num36 + num45 + num64 + num73 + num82 + num91 + num100 + num109 + num118 + num127;
			long num137 = num37 + num46 + num55 + num74 + num83 + num92 + num101 + num110 + num119 + num128;
			long num138 = num38 + num47 + num56 + num65 + num84 + num93 + num102 + num111 + num120 + num129;
			long num139 = num39 + num48 + num57 + num66 + num75 + num94 + num103 + num112 + num121 + num130;
			long num140 = num40 + num49 + num58 + num67 + num76 + num85 + num104 + num113 + num122 + num131;
			long num141 = num41 + num50 + num59 + num68 + num77 + num86 + num95 + num114 + num123 + num132;
			long num142 = num42 + num51 + num60 + num69 + num78 + num87 + num96 + num105 + num124 + num133;
			long num143 = num43 + num52 + num61 + num70 + num79 + num88 + num97 + num106 + num115 + num134;
			long num144 = num44 + num53 + num62 + num71 + num80 + num89 + num98 + num107 + num116 + num125;
			long num145 = num135 + 33554432 >> 26;
			num136 += num145;
			num135 -= num145 * 67108864;
			long num146 = num139 + 33554432 >> 26;
			num140 += num146;
			num139 -= num146 * 67108864;
			long num147 = num136 + 16777216 >> 25;
			num137 += num147;
			num136 -= num147 * 33554432;
			long num148 = num140 + 16777216 >> 25;
			num141 += num148;
			num140 -= num148 * 33554432;
			long num149 = num137 + 33554432 >> 26;
			num138 += num149;
			num137 -= num149 * 67108864;
			long num150 = num141 + 33554432 >> 26;
			num142 += num150;
			num141 -= num150 * 67108864;
			long num151 = num138 + 16777216 >> 25;
			num139 += num151;
			num138 -= num151 * 33554432;
			long num152 = num142 + 16777216 >> 25;
			num143 += num152;
			num142 -= num152 * 33554432;
			num146 = num139 + 33554432 >> 26;
			num140 += num146;
			num139 -= num146 * 67108864;
			long num153 = num143 + 33554432 >> 26;
			num144 += num153;
			num143 -= num153 * 67108864;
			long num154 = num144 + 16777216 >> 25;
			num135 += num154 * 19;
			num144 -= num154 * 33554432;
			num145 = num135 + 33554432 >> 26;
			num136 += num145;
			num135 -= num145 * 67108864;
			h[0] = (int)num135;
			h[1] = (int)num136;
			h[2] = (int)num137;
			h[3] = (int)num138;
			h[4] = (int)num139;
			h[5] = (int)num140;
			h[6] = (int)num141;
			h[7] = (int)num142;
			h[8] = (int)num143;
			h[9] = (int)num144;
		}

		public static void Sq(Span<int> h, Span<int> f)
		{
			int num = f[0];
			int num2 = f[1];
			int num3 = f[2];
			int num4 = f[3];
			int num5 = f[4];
			int num6 = f[5];
			int num7 = f[6];
			int num8 = f[7];
			int num9 = f[8];
			int num10 = f[9];
			int num11 = 2 * num;
			int num12 = 2 * num2;
			int num13 = 2 * num3;
			int num14 = 2 * num4;
			int num15 = 2 * num5;
			int num16 = 2 * num6;
			int num17 = 2 * num7;
			int num18 = 2 * num8;
			int num19 = 38 * num6;
			int num20 = 19 * num7;
			int num21 = 38 * num8;
			int num22 = 19 * num9;
			int num23 = 38 * num10;
			long num24 = (long)num * (long)num;
			long num25 = (long)num11 * (long)num2;
			long num26 = (long)num11 * (long)num3;
			long num27 = (long)num11 * (long)num4;
			long num28 = (long)num11 * (long)num5;
			long num29 = (long)num11 * (long)num6;
			long num30 = (long)num11 * (long)num7;
			long num31 = (long)num11 * (long)num8;
			long num32 = (long)num11 * (long)num9;
			long num33 = (long)num11 * (long)num10;
			long num34 = (long)num12 * (long)num2;
			long num35 = (long)num12 * (long)num3;
			long num36 = (long)num12 * (long)num14;
			long num37 = (long)num12 * (long)num5;
			long num38 = (long)num12 * (long)num16;
			long num39 = (long)num12 * (long)num7;
			long num40 = (long)num12 * (long)num18;
			long num41 = (long)num12 * (long)num9;
			long num42 = (long)num12 * (long)num23;
			long num43 = (long)num3 * (long)num3;
			long num44 = (long)num13 * (long)num4;
			long num45 = (long)num13 * (long)num5;
			long num46 = (long)num13 * (long)num6;
			long num47 = (long)num13 * (long)num7;
			long num48 = (long)num13 * (long)num8;
			long num49 = (long)num13 * (long)num22;
			long num50 = (long)num3 * (long)num23;
			long num51 = (long)num14 * (long)num4;
			long num52 = (long)num14 * (long)num5;
			long num53 = (long)num14 * (long)num16;
			long num54 = (long)num14 * (long)num7;
			long num55 = (long)num14 * (long)num21;
			long num56 = (long)num14 * (long)num22;
			long num57 = (long)num14 * (long)num23;
			long num58 = (long)num5 * (long)num5;
			long num59 = (long)num15 * (long)num6;
			long num60 = (long)num15 * (long)num20;
			long num61 = (long)num5 * (long)num21;
			long num62 = (long)num15 * (long)num22;
			long num63 = (long)num5 * (long)num23;
			long num64 = (long)num6 * (long)num19;
			long num65 = (long)num16 * (long)num20;
			long num66 = (long)num16 * (long)num21;
			long num67 = (long)num16 * (long)num22;
			long num68 = (long)num16 * (long)num23;
			long num69 = (long)num7 * (long)num20;
			long num70 = (long)num7 * (long)num21;
			long num71 = (long)num17 * (long)num22;
			long num72 = (long)num7 * (long)num23;
			long num73 = (long)num8 * (long)num21;
			long num74 = (long)num18 * (long)num22;
			long num75 = (long)num18 * (long)num23;
			long num76 = (long)num9 * (long)num22;
			long num77 = (long)num9 * (long)num23;
			long num78 = (long)num10 * (long)num23;
			long num79 = num24 + num42 + num49 + num55 + num60 + num64;
			long num80 = num25 + num50 + num56 + num61 + num65;
			long num81 = num26 + num34 + num57 + num62 + num66 + num69;
			long num82 = num27 + num35 + num63 + num67 + num70;
			long num83 = num28 + num36 + num43 + num68 + num71 + num73;
			long num84 = num29 + num37 + num44 + num72 + num74;
			long num85 = num30 + num38 + num45 + num51 + num75 + num76;
			long num86 = num31 + num39 + num46 + num52 + num77;
			long num87 = num32 + num40 + num47 + num53 + num58 + num78;
			long num88 = num33 + num41 + num48 + num54 + num59;
			long num89 = num79 + 33554432 >> 26;
			num80 += num89;
			num79 -= num89 * 67108864;
			long num90 = num83 + 33554432 >> 26;
			num84 += num90;
			num83 -= num90 * 67108864;
			long num91 = num80 + 16777216 >> 25;
			num81 += num91;
			num80 -= num91 * 33554432;
			long num92 = num84 + 16777216 >> 25;
			num85 += num92;
			num84 -= num92 * 33554432;
			long num93 = num81 + 33554432 >> 26;
			num82 += num93;
			num81 -= num93 * 67108864;
			long num94 = num85 + 33554432 >> 26;
			num86 += num94;
			num85 -= num94 * 67108864;
			long num95 = num82 + 16777216 >> 25;
			num83 += num95;
			num82 -= num95 * 33554432;
			long num96 = num86 + 16777216 >> 25;
			num87 += num96;
			num86 -= num96 * 33554432;
			num90 = num83 + 33554432 >> 26;
			num84 += num90;
			num83 -= num90 * 67108864;
			long num97 = num87 + 33554432 >> 26;
			num88 += num97;
			num87 -= num97 * 67108864;
			long num98 = num88 + 16777216 >> 25;
			num79 += num98 * 19;
			num88 -= num98 * 33554432;
			num89 = num79 + 33554432 >> 26;
			num80 += num89;
			num79 -= num89 * 67108864;
			h[0] = (int)num79;
			h[1] = (int)num80;
			h[2] = (int)num81;
			h[3] = (int)num82;
			h[4] = (int)num83;
			h[5] = (int)num84;
			h[6] = (int)num85;
			h[7] = (int)num86;
			h[8] = (int)num87;
			h[9] = (int)num88;
		}

		public static void Mul121666(Span<int> h, Span<int> f)
		{
			int num = f[0];
			int num2 = f[1];
			int num3 = f[2];
			int num4 = f[3];
			int num5 = f[4];
			int num6 = f[5];
			int num7 = f[6];
			int num8 = f[7];
			int num9 = f[8];
			int num10 = f[9];
			long num11 = (long)num * 121666L;
			long num12 = (long)num2 * 121666L;
			long num13 = (long)num3 * 121666L;
			long num14 = (long)num4 * 121666L;
			long num15 = (long)num5 * 121666L;
			long num16 = (long)num6 * 121666L;
			long num17 = (long)num7 * 121666L;
			long num18 = (long)num8 * 121666L;
			long num19 = (long)num9 * 121666L;
			long num20 = (long)num10 * 121666L;
			long num21 = num20 + 16777216 >> 25;
			num11 += num21 * 19;
			num20 -= num21 << 25;
			long num22 = num12 + 16777216 >> 25;
			num13 += num22;
			num12 -= num22 << 25;
			long num23 = num14 + 16777216 >> 25;
			num15 += num23;
			num14 -= num23 << 25;
			long num24 = num16 + 16777216 >> 25;
			num17 += num24;
			num16 -= num24 << 25;
			long num25 = num18 + 16777216 >> 25;
			num19 += num25;
			num18 -= num25 << 25;
			long num26 = num11 + 33554432 >> 26;
			num12 += num26;
			num11 -= num26 << 26;
			long num27 = num13 + 33554432 >> 26;
			num14 += num27;
			num13 -= num27 << 26;
			long num28 = num15 + 33554432 >> 26;
			num16 += num28;
			num15 -= num28 << 26;
			long num29 = num17 + 33554432 >> 26;
			num18 += num29;
			num17 -= num29 << 26;
			long num30 = num19 + 33554432 >> 26;
			num20 += num30;
			num19 -= num30 << 26;
			h[0] = (int)num11;
			h[1] = (int)num12;
			h[2] = (int)num13;
			h[3] = (int)num14;
			h[4] = (int)num15;
			h[5] = (int)num16;
			h[6] = (int)num17;
			h[7] = (int)num18;
			h[8] = (int)num19;
			h[9] = (int)num20;
		}

		public static void Invert(Span<int> output, Span<int> z)
		{
			Span<int> span = stackalloc int[10];
			Span<int> span2 = stackalloc int[10];
			Span<int> span3 = stackalloc int[10];
			Span<int> span4 = stackalloc int[10];
			Sq(span, z);
			Sq(span2, span);
			Sq(span2, span2);
			Mul(span2, z, span2);
			Mul(span, span, span2);
			Sq(span3, span);
			Mul(span2, span2, span3);
			Sq(span3, span2);
			for (int i = 1; i < 5; i++)
			{
				Sq(span3, span3);
			}
			Mul(span2, span3, span2);
			Sq(span3, span2);
			for (int i = 1; i < 10; i++)
			{
				Sq(span3, span3);
			}
			Mul(span3, span3, span2);
			Sq(span4, span3);
			for (int i = 1; i < 20; i++)
			{
				Sq(span4, span4);
			}
			Mul(span3, span4, span3);
			Sq(span3, span3);
			for (int i = 1; i < 10; i++)
			{
				Sq(span3, span3);
			}
			Mul(span2, span3, span2);
			Sq(span3, span2);
			for (int i = 1; i < 50; i++)
			{
				Sq(span3, span3);
			}
			Mul(span3, span3, span2);
			Sq(span4, span3);
			for (int i = 1; i < 100; i++)
			{
				Sq(span4, span4);
			}
			Mul(span3, span4, span3);
			Sq(span3, span3);
			for (int i = 1; i < 50; i++)
			{
				Sq(span3, span3);
			}
			Mul(span2, span3, span2);
			Sq(span2, span2);
			for (int i = 1; i < 5; i++)
			{
				Sq(span2, span2);
			}
			Mul(output, span2, span);
		}

		private static void Reduce(Span<int> h, Span<int> f)
		{
			int num = f[0];
			int num2 = f[1];
			int num3 = f[2];
			int num4 = f[3];
			int num5 = f[4];
			int num6 = f[5];
			int num7 = f[6];
			int num8 = f[7];
			int num9 = f[8];
			int num10 = f[9];
			int num11 = 19 * num10 + 16777216 >> 25;
			num11 = num + num11 >> 26;
			num11 = num2 + num11 >> 25;
			num11 = num3 + num11 >> 26;
			num11 = num4 + num11 >> 25;
			num11 = num5 + num11 >> 26;
			num11 = num6 + num11 >> 25;
			num11 = num7 + num11 >> 26;
			num11 = num8 + num11 >> 25;
			num11 = num9 + num11 >> 26;
			num11 = num10 + num11 >> 25;
			num += 19 * num11;
			int num12 = num >> 26;
			num2 += num12;
			num -= num12 * 67108864;
			int num13 = num2 >> 25;
			num3 += num13;
			num2 -= num13 * 33554432;
			int num14 = num3 >> 26;
			num4 += num14;
			num3 -= num14 * 67108864;
			int num15 = num4 >> 25;
			num5 += num15;
			num4 -= num15 * 33554432;
			int num16 = num5 >> 26;
			num6 += num16;
			num5 -= num16 * 67108864;
			int num17 = num6 >> 25;
			num7 += num17;
			num6 -= num17 * 33554432;
			int num18 = num7 >> 26;
			num8 += num18;
			num7 -= num18 * 67108864;
			int num19 = num8 >> 25;
			num9 += num19;
			num8 -= num19 * 33554432;
			int num20 = num9 >> 26;
			num10 += num20;
			num9 -= num20 * 67108864;
			int num21 = num10 >> 25;
			num10 -= num21 * 33554432;
			h[0] = num;
			h[1] = num2;
			h[2] = num3;
			h[3] = num4;
			h[4] = num5;
			h[5] = num6;
			h[6] = num7;
			h[7] = num8;
			h[8] = num9;
			h[9] = num10;
		}

		public static void ToBytes(Span<byte> s, Span<int> h)
		{
			Span<int> h2 = stackalloc int[10];
			Reduce(h2, h);
			s[0] = (byte)h2[0];
			s[1] = (byte)(h2[0] >> 8);
			s[2] = (byte)(h2[0] >> 16);
			s[3] = (byte)((h2[0] >> 24) | (h2[1] * 4));
			s[4] = (byte)(h2[1] >> 6);
			s[5] = (byte)(h2[1] >> 14);
			s[6] = (byte)((h2[1] >> 22) | (h2[2] * 8));
			s[7] = (byte)(h2[2] >> 5);
			s[8] = (byte)(h2[2] >> 13);
			s[9] = (byte)((h2[2] >> 21) | (h2[3] * 32));
			s[10] = (byte)(h2[3] >> 3);
			s[11] = (byte)(h2[3] >> 11);
			s[12] = (byte)((h2[3] >> 19) | (h2[4] * 64));
			s[13] = (byte)(h2[4] >> 2);
			s[14] = (byte)(h2[4] >> 10);
			s[15] = (byte)(h2[4] >> 18);
			s[16] = (byte)h2[5];
			s[17] = (byte)(h2[5] >> 8);
			s[18] = (byte)(h2[5] >> 16);
			s[19] = (byte)((h2[5] >> 24) | (h2[6] * 2));
			s[20] = (byte)(h2[6] >> 7);
			s[21] = (byte)(h2[6] >> 15);
			s[22] = (byte)((h2[6] >> 23) | (h2[7] * 8));
			s[23] = (byte)(h2[7] >> 5);
			s[24] = (byte)(h2[7] >> 13);
			s[25] = (byte)((h2[7] >> 21) | (h2[8] * 16));
			s[26] = (byte)(h2[8] >> 4);
			s[27] = (byte)(h2[8] >> 12);
			s[28] = (byte)((h2[8] >> 20) | (h2[9] * 64));
			s[29] = (byte)(h2[9] >> 2);
			s[30] = (byte)(h2[9] >> 10);
			s[31] = (byte)(h2[9] >> 18);
		}
	}
	internal class HSalsa20
	{
		private const int Rounds = 20;

		public const int BlockLength = 32;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Transform(Span<byte> output, ReadOnlySpan<byte> input, ReadOnlySpan<byte> k, ReadOnlySpan<byte> c)
		{
			uint num;
			uint num2;
			uint num3;
			uint num4;
			if (c.IsEmpty)
			{
				num = 1634760805u;
				num2 = 857760878u;
				num3 = 2036477234u;
				num4 = 1797285236u;
			}
			else
			{
				num = Common.Load32(c, 0);
				num2 = Common.Load32(c, 4);
				num3 = Common.Load32(c, 8);
				num4 = Common.Load32(c, 12);
			}
			uint num5 = Common.Load32(k, 0);
			uint num6 = Common.Load32(k, 4);
			uint num7 = Common.Load32(k, 8);
			uint num8 = Common.Load32(k, 12);
			uint num9 = Common.Load32(k, 16);
			uint num10 = Common.Load32(k, 20);
			uint num11 = Common.Load32(k, 24);
			uint num12 = Common.Load32(k, 28);
			uint num13 = Common.Load32(input, 0);
			uint num14 = Common.Load32(input, 4);
			uint num15 = Common.Load32(input, 8);
			uint num16 = Common.Load32(input, 12);
			for (int num17 = 20; num17 > 0; num17 -= 2)
			{
				uint num18 = num8;
				uint x = num + num10;
				int b = 7;
				num8 = num18 ^ Common.RotateLeft(in x, in b);
				uint num19 = num15;
				x = num8 + num;
				b = 9;
				num15 = num19 ^ Common.RotateLeft(in x, in b);
				uint num20 = num10;
				x = num15 + num8;
				b = 13;
				num10 = num20 ^ Common.RotateLeft(in x, in b);
				uint num21 = num;
				x = num10 + num15;
				b = 18;
				num = num21 ^ Common.RotateLeft(in x, in b);
				uint num22 = num16;
				x = num2 + num5;
				b = 7;
				num16 = num22 ^ Common.RotateLeft(in x, in b);
				uint num23 = num11;
				x = num16 + num2;
				b = 9;
				num11 = num23 ^ Common.RotateLeft(in x, in b);
				uint num24 = num5;
				x = num11 + num16;
				b = 13;
				num5 = num24 ^ Common.RotateLeft(in x, in b);
				uint num25 = num2;
				x = num5 + num11;
				b = 18;
				num2 = num25 ^ Common.RotateLeft(in x, in b);
				uint num26 = num12;
				x = num3 + num13;
				b = 7;
				num12 = num26 ^ Common.RotateLeft(in x, in b);
				uint num27 = num6;
				x = num12 + num3;
				b = 9;
				num6 = num27 ^ Common.RotateLeft(in x, in b);
				uint num28 = num13;
				x = num6 + num12;
				b = 13;
				num13 = num28 ^ Common.RotateLeft(in x, in b);
				uint num29 = num3;
				x = num13 + num6;
				b = 18;
				num3 = num29 ^ Common.RotateLeft(in x, in b);
				uint num30 = num7;
				x = num4 + num9;
				b = 7;
				num7 = num30 ^ Common.RotateLeft(in x, in b);
				uint num31 = num14;
				x = num7 + num4;
				b = 9;
				num14 = num31 ^ Common.RotateLeft(in x, in b);
				uint num32 = num9;
				x = num14 + num7;
				b = 13;
				num9 = num32 ^ Common.RotateLeft(in x, in b);
				uint num33 = num4;
				x = num9 + num14;
				b = 18;
				num4 = num33 ^ Common.RotateLeft(in x, in b);
				uint num34 = num5;
				x = num + num7;
				b = 7;
				num5 = num34 ^ Common.RotateLeft(in x, in b);
				uint num35 = num6;
				x = num5 + num;
				b = 9;
				num6 = num35 ^ Common.RotateLeft(in x, in b);
				uint num36 = num7;
				x = num6 + num5;
				b = 13;
				num7 = num36 ^ Common.RotateLeft(in x, in b);
				uint num37 = num;
				x = num7 + num6;
				b = 18;
				num = num37 ^ Common.RotateLeft(in x, in b);
				uint num38 = num13;
				x = num2 + num8;
				b = 7;
				num13 = num38 ^ Common.RotateLeft(in x, in b);
				uint num39 = num14;
				x = num13 + num2;
				b = 9;
				num14 = num39 ^ Common.RotateLeft(in x, in b);
				uint num40 = num8;
				x = num14 + num13;
				b = 13;
				num8 = num40 ^ Common.RotateLeft(in x, in b);
				uint num41 = num2;
				x = num8 + num14;
				b = 18;
				num2 = num41 ^ Common.RotateLeft(in x, in b);
				uint num42 = num9;
				x = num3 + num16;
				b = 7;
				num9 = num42 ^ Common.RotateLeft(in x, in b);
				uint num43 = num15;
				x = num9 + num3;
				b = 9;
				num15 = num43 ^ Common.RotateLeft(in x, in b);
				uint num44 = num16;
				x = num15 + num9;
				b = 13;
				num16 = num44 ^ Common.RotateLeft(in x, in b);
				uint num45 = num3;
				x = num16 + num15;
				b = 18;
				num3 = num45 ^ Common.RotateLeft(in x, in b);
				uint num46 = num10;
				x = num4 + num12;
				b = 7;
				num10 = num46 ^ Common.RotateLeft(in x, in b);
				uint num47 = num11;
				x = num10 + num4;
				b = 9;
				num11 = num47 ^ Common.RotateLeft(in x, in b);
				uint num48 = num12;
				x = num11 + num10;
				b = 13;
				num12 = num48 ^ Common.RotateLeft(in x, in b);
				uint num49 = num4;
				x = num12 + num11;
				b = 18;
				num4 = num49 ^ Common.RotateLeft(in x, in b);
			}
			Common.Store(output, 0, num);
			Common.Store(output, 4, num2);
			Common.Store(output, 8, num3);
			Common.Store(output, 12, num4);
			Common.Store(output, 16, num13);
			Common.Store(output, 20, num14);
			Common.Store(output, 24, num15);
			Common.Store(output, 28, num16);
		}
	}
	internal static class SafeComparison
	{
		public static bool Verify16(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y)
		{
			uint num = 0u;
			num |= (uint)(x[0] ^ y[0]);
			num |= (uint)(x[1] ^ y[1]);
			num |= (uint)(x[2] ^ y[2]);
			num |= (uint)(x[3] ^ y[3]);
			num |= (uint)(x[4] ^ y[4]);
			num |= (uint)(x[5] ^ y[5]);
			num |= (uint)(x[6] ^ y[6]);
			num |= (uint)(x[7] ^ y[7]);
			num |= (uint)(x[8] ^ y[8]);
			num |= (uint)(x[9] ^ y[9]);
			num |= (uint)(x[10] ^ y[10]);
			num |= (uint)(x[11] ^ y[11]);
			num |= (uint)(x[12] ^ y[12]);
			num |= (uint)(x[13] ^ y[13]);
			num |= (uint)(x[14] ^ y[14]);
			num |= (uint)(x[15] ^ y[15]);
			return (1 & (num - 1 >> 8)) == 1;
		}

		public static bool Verify32(Span<byte> x, Span<byte> y)
		{
			uint num = 0u;
			num |= (uint)(x[0] ^ y[0]);
			num |= (uint)(x[1] ^ y[1]);
			num |= (uint)(x[2] ^ y[2]);
			num |= (uint)(x[3] ^ y[3]);
			num |= (uint)(x[4] ^ y[4]);
			num |= (uint)(x[5] ^ y[5]);
			num |= (uint)(x[6] ^ y[6]);
			num |= (uint)(x[7] ^ y[7]);
			num |= (uint)(x[8] ^ y[8]);
			num |= (uint)(x[9] ^ y[9]);
			num |= (uint)(x[10] ^ y[10]);
			num |= (uint)(x[11] ^ y[11]);
			num |= (uint)(x[12] ^ y[12]);
			num |= (uint)(x[13] ^ y[13]);
			num |= (uint)(x[14] ^ y[14]);
			num |= (uint)(x[15] ^ y[15]);
			num |= (uint)(x[16] ^ y[16]);
			num |= (uint)(x[17] ^ y[17]);
			num |= (uint)(x[18] ^ y[18]);
			num |= (uint)(x[19] ^ y[19]);
			num |= (uint)(x[20] ^ y[20]);
			num |= (uint)(x[21] ^ y[21]);
			num |= (uint)(x[22] ^ y[22]);
			num |= (uint)(x[23] ^ y[23]);
			num |= (uint)(x[24] ^ y[24]);
			num |= (uint)(x[25] ^ y[25]);
			num |= (uint)(x[26] ^ y[26]);
			num |= (uint)(x[27] ^ y[27]);
			num |= (uint)(x[28] ^ y[28]);
			num |= (uint)(x[29] ^ y[29]);
			num |= (uint)(x[30] ^ y[30]);
			num |= (uint)(x[31] ^ y[31]);
			return (1 & (num - 1 >> 8)) == 1;
		}
	}
	internal static class Salsa20
	{
		private const int Rounds = 20;

		public const int KeyLength = 32;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Transform(byte[] output, byte[] input, byte[] k, byte[] c)
		{
			uint num;
			uint num2 = (num = 1634760805u);
			uint num3;
			uint num4 = (num3 = 857760878u);
			uint num5;
			uint num6 = (num5 = 2036477234u);
			uint num7;
			uint num8 = (num7 = 1797285236u);
			if (c != null)
			{
				num2 = (num = Common.Load32(c, 0));
				num4 = (num3 = Common.Load32(c, 4));
				num6 = (num5 = Common.Load32(c, 8));
				num8 = (num7 = Common.Load32(c, 12));
			}
			uint num9;
			uint num10 = (num9 = Common.Load32(k, 0));
			uint num11;
			uint num12 = (num11 = Common.Load32(k, 4));
			uint num13;
			uint num14 = (num13 = Common.Load32(k, 8));
			uint num15;
			uint num16 = (num15 = Common.Load32(k, 12));
			uint num17;
			uint num18 = (num17 = Common.Load32(k, 16));
			uint num19;
			uint num20 = (num19 = Common.Load32(k, 20));
			uint num21;
			uint num22 = (num21 = Common.Load32(k, 24));
			uint num23;
			uint num24 = (num23 = Common.Load32(k, 28));
			uint num25;
			uint num26 = (num25 = Common.Load32(input, 0));
			uint num27;
			uint num28 = (num27 = Common.Load32(input, 4));
			uint num29;
			uint num30 = (num29 = Common.Load32(input, 8));
			uint num31;
			uint num32 = (num31 = Common.Load32(input, 12));
			for (int i = 0; i < 20; i += 2)
			{
				uint num33 = num15;
				uint x = num + num19;
				int b = 7;
				num15 = num33 ^ Common.RotateLeft(in x, in b);
				uint num34 = num29;
				x = num15 + num;
				b = 9;
				num29 = num34 ^ Common.RotateLeft(in x, in b);
				uint num35 = num19;
				x = num29 + num15;
				b = 13;
				num19 = num35 ^ Common.RotateLeft(in x, in b);
				uint num36 = num;
				x = num19 + num29;
				b = 18;
				num = num36 ^ Common.RotateLeft(in x, in b);
				uint num37 = num31;
				x = num3 + num9;
				b = 7;
				num31 = num37 ^ Common.RotateLeft(in x, in b);
				uint num38 = num21;
				x = num31 + num3;
				b = 9;
				num21 = num38 ^ Common.RotateLeft(in x, in b);
				uint num39 = num9;
				x = num21 + num31;
				b = 13;
				num9 = num39 ^ Common.RotateLeft(in x, in b);
				uint num40 = num3;
				x = num9 + num21;
				b = 18;
				num3 = num40 ^ Common.RotateLeft(in x, in b);
				uint num41 = num23;
				x = num5 + num25;
				b = 7;
				num23 = num41 ^ Common.RotateLeft(in x, in b);
				uint num42 = num11;
				x = num23 + num5;
				b = 9;
				num11 = num42 ^ Common.RotateLeft(in x, in b);
				uint num43 = num25;
				x = num11 + num23;
				b = 13;
				num25 = num43 ^ Common.RotateLeft(in x, in b);
				uint num44 = num5;
				x = num25 + num11;
				b = 18;
				num5 = num44 ^ Common.RotateLeft(in x, in b);
				uint num45 = num13;
				x = num7 + num17;
				b = 7;
				num13 = num45 ^ Common.RotateLeft(in x, in b);
				uint num46 = num27;
				x = num13 + num7;
				b = 9;
				num27 = num46 ^ Common.RotateLeft(in x, in b);
				uint num47 = num17;
				x = num27 + num13;
				b = 13;
				num17 = num47 ^ Common.RotateLeft(in x, in b);
				uint num48 = num7;
				x = num17 + num27;
				b = 18;
				num7 = num48 ^ Common.RotateLeft(in x, in b);
				uint num49 = num9;
				x = num + num13;
				b = 7;
				num9 = num49 ^ Common.RotateLeft(in x, in b);
				uint num50 = num11;
				x = num9 + num;
				b = 9;
				num11 = num50 ^ Common.RotateLeft(in x, in b);
				uint num51 = num13;
				x = num11 + num9;
				b = 13;
				num13 = num51 ^ Common.RotateLeft(in x, in b);
				uint num52 = num;
				x = num13 + num11;
				b = 18;
				num = num52 ^ Common.RotateLeft(in x, in b);
				uint num53 = num25;
				x = num3 + num15;
				b = 7;
				num25 = num53 ^ Common.RotateLeft(in x, in b);
				uint num54 = num27;
				x = num25 + num3;
				b = 9;
				num27 = num54 ^ Common.RotateLeft(in x, in b);
				uint num55 = num15;
				x = num27 + num25;
				b = 13;
				num15 = num55 ^ Common.RotateLeft(in x, in b);
				uint num56 = num3;
				x = num15 + num27;
				b = 18;
				num3 = num56 ^ Common.RotateLeft(in x, in b);
				uint num57 = num17;
				x = num5 + num31;
				b = 7;
				num17 = num57 ^ Common.RotateLeft(in x, in b);
				uint num58 = num29;
				x = num17 + num5;
				b = 9;
				num29 = num58 ^ Common.RotateLeft(in x, in b);
				uint num59 = num31;
				x = num29 + num17;
				b = 13;
				num31 = num59 ^ Common.RotateLeft(in x, in b);
				uint num60 = num5;
				x = num31 + num29;
				b = 18;
				num5 = num60 ^ Common.RotateLeft(in x, in b);
				uint num61 = num19;
				x = num7 + num23;
				b = 7;
				num19 = num61 ^ Common.RotateLeft(in x, in b);
				uint num62 = num21;
				x = num19 + num7;
				b = 9;
				num21 = num62 ^ Common.RotateLeft(in x, in b);
				uint num63 = num23;
				x = num21 + num19;
				b = 13;
				num23 = num63 ^ Common.RotateLeft(in x, in b);
				uint num64 = num7;
				x = num23 + num21;
				b = 18;
				num7 = num64 ^ Common.RotateLeft(in x, in b);
			}
			Common.Store(output, 0, num + num2);
			Common.Store(output, 4, num9 + num10);
			Common.Store(output, 8, num11 + num12);
			Common.Store(output, 12, num13 + num14);
			Common.Store(output, 16, num15 + num16);
			Common.Store(output, 20, num3 + num4);
			Common.Store(output, 24, num25 + num26);
			Common.Store(output, 28, num27 + num28);
			Common.Store(output, 32, num29 + num30);
			Common.Store(output, 36, num31 + num32);
			Common.Store(output, 40, num5 + num6);
			Common.Store(output, 44, num17 + num18);
			Common.Store(output, 48, num19 + num20);
			Common.Store(output, 52, num21 + num22);
			Common.Store(output, 56, num23 + num24);
			Common.Store(output, 60, num7 + num8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Transform(Span<byte> output, ReadOnlySpan<byte> input, ReadOnlySpan<byte> k, ReadOnlySpan<byte> c)
		{
			uint num;
			uint num2 = (num = 1634760805u);
			uint num3;
			uint num4 = (num3 = 857760878u);
			uint num5;
			uint num6 = (num5 = 2036477234u);
			uint num7;
			uint num8 = (num7 = 1797285236u);
			if (!c.IsEmpty)
			{
				num2 = (num = Common.Load32(c, 0));
				num4 = (num3 = Common.Load32(c, 4));
				num6 = (num5 = Common.Load32(c, 8));
				num8 = (num7 = Common.Load32(c, 12));
			}
			uint num9;
			uint num10 = (num9 = Common.Load32(k, 0));
			uint num11;
			uint num12 = (num11 = Common.Load32(k, 4));
			uint num13;
			uint num14 = (num13 = Common.Load32(k, 8));
			uint num15;
			uint num16 = (num15 = Common.Load32(k, 12));
			uint num17;
			uint num18 = (num17 = Common.Load32(k, 16));
			uint num19;
			uint num20 = (num19 = Common.Load32(k, 20));
			uint num21;
			uint num22 = (num21 = Common.Load32(k, 24));
			uint num23;
			uint num24 = (num23 = Common.Load32(k, 28));
			uint num25;
			uint num26 = (num25 = Common.Load32(input, 0));
			uint num27;
			uint num28 = (num27 = Common.Load32(input, 4));
			uint num29;
			uint num30 = (num29 = Common.Load32(input, 8));
			uint num31;
			uint num32 = (num31 = Common.Load32(input, 12));
			for (int i = 0; i < 20; i += 2)
			{
				uint num33 = num15;
				uint x = num + num19;
				int b = 7;
				num15 = num33 ^ Common.RotateLeft(in x, in b);
				uint num34 = num29;
				x = num15 + num;
				b = 9;
				num29 = num34 ^ Common.RotateLeft(in x, in b);
				uint num35 = num19;
				x = num29 + num15;
				b = 13;
				num19 = num35 ^ Common.RotateLeft(in x, in b);
				uint num36 = num;
				x = num19 + num29;
				b = 18;
				num = num36 ^ Common.RotateLeft(in x, in b);
				uint num37 = num31;
				x = num3 + num9;
				b = 7;
				num31 = num37 ^ Common.RotateLeft(in x, in b);
				uint num38 = num21;
				x = num31 + num3;
				b = 9;
				num21 = num38 ^ Common.RotateLeft(in x, in b);
				uint num39 = num9;
				x = num21 + num31;
				b = 13;
				num9 = num39 ^ Common.RotateLeft(in x, in b);
				uint num40 = num3;
				x = num9 + num21;
				b = 18;
				num3 = num40 ^ Common.RotateLeft(in x, in b);
				uint num41 = num23;
				x = num5 + num25;
				b = 7;
				num23 = num41 ^ Common.RotateLeft(in x, in b);
				uint num42 = num11;
				x = num23 + num5;
				b = 9;
				num11 = num42 ^ Common.RotateLeft(in x, in b);
				uint num43 = num25;
				x = num11 + num23;
				b = 13;
				num25 = num43 ^ Common.RotateLeft(in x, in b);
				uint num44 = num5;
				x = num25 + num11;
				b = 18;
				num5 = num44 ^ Common.RotateLeft(in x, in b);
				uint num45 = num13;
				x = num7 + num17;
				b = 7;
				num13 = num45 ^ Common.RotateLeft(in x, in b);
				uint num46 = num27;
				x = num13 + num7;
				b = 9;
				num27 = num46 ^ Common.RotateLeft(in x, in b);
				uint num47 = num17;
				x = num27 + num13;
				b = 13;
				num17 = num47 ^ Common.RotateLeft(in x, in b);
				uint num48 = num7;
				x = num17 + num27;
				b = 18;
				num7 = num48 ^ Common.RotateLeft(in x, in b);
				uint num49 = num9;
				x = num + num13;
				b = 7;
				num9 = num49 ^ Common.RotateLeft(in x, in b);
				uint num50 = num11;
				x = num9 + num;
				b = 9;
				num11 = num50 ^ Common.RotateLeft(in x, in b);
				uint num51 = num13;
				x = num11 + num9;
				b = 13;
				num13 = num51 ^ Common.RotateLeft(in x, in b);
				uint num52 = num;
				x = num13 + num11;
				b = 18;
				num = num52 ^ Common.RotateLeft(in x, in b);
				uint num53 = num25;
				x = num3 + num15;
				b = 7;
				num25 = num53 ^ Common.RotateLeft(in x, in b);
				uint num54 = num27;
				x = num25 + num3;
				b = 9;
				num27 = num54 ^ Common.RotateLeft(in x, in b);
				uint num55 = num15;
				x = num27 + num25;
				b = 13;
				num15 = num55 ^ Common.RotateLeft(in x, in b);
				uint num56 = num3;
				x = num15 + num27;
				b = 18;
				num3 = num56 ^ Common.RotateLeft(in x, in b);
				uint num57 = num17;
				x = num5 + num31;
				b = 7;
				num17 = num57 ^ Common.RotateLeft(in x, in b);
				uint num58 = num29;
				x = num17 + num5;
				b = 9;
				num29 = num58 ^ Common.RotateLeft(in x, in b);
				uint num59 = num31;
				x = num29 + num17;
				b = 13;
				num31 = num59 ^ Common.RotateLeft(in x, in b);
				uint num60 = num5;
				x = num31 + num29;
				b = 18;
				num5 = num60 ^ Common.RotateLeft(in x, in b);
				uint num61 = num19;
				x = num7 + num23;
				b = 7;
				num19 = num61 ^ Common.RotateLeft(in x, in b);
				uint num62 = num21;
				x = num19 + num7;
				b = 9;
				num21 = num62 ^ Common.RotateLeft(in x, in b);
				uint num63 = num23;
				x = num21 + num19;
				b = 13;
				num23 = num63 ^ Common.RotateLeft(in x, in b);
				uint num64 = num7;
				x = num23 + num21;
				b = 18;
				num7 = num64 ^ Common.RotateLeft(in x, in b);
			}
			Common.Store(output, 0, num + num2);
			Common.Store(output, 4, num9 + num10);
			Common.Store(output, 8, num11 + num12);
			Common.Store(output, 12, num13 + num14);
			Common.Store(output, 16, num15 + num16);
			Common.Store(output, 20, num3 + num4);
			Common.Store(output, 24, num25 + num26);
			Common.Store(output, 28, num27 + num28);
			Common.Store(output, 32, num29 + num30);
			Common.Store(output, 36, num31 + num32);
			Common.Store(output, 40, num5 + num6);
			Common.Store(output, 44, num17 + num18);
			Common.Store(output, 48, num19 + num20);
			Common.Store(output, 52, num21 + num22);
			Common.Store(output, 56, num23 + num24);
			Common.Store(output, 60, num7 + num8);
		}
	}
	internal static class StreamSalsa20
	{
		public const int KeyLength = 32;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Transform(Span<byte> c, ReadOnlySpan<byte> n, ReadOnlySpan<byte> k)
		{
			if (c.IsEmpty)
			{
				return;
			}
			byte[] array = new byte[16];
			byte[] array2 = new byte[64];
			byte[] array3 = k.ToArray();
			try
			{
				for (int i = 0; i < 8; i++)
				{
					array[i] = n[i];
				}
				while (c.Length >= 64)
				{
					Salsa20.Transform(array2, array, array3, null);
					array2.CopyTo(c);
					uint num = 1u;
					for (int j = 8; j < 16; j++)
					{
						num += array[j];
						array[j] = (byte)num;
						num >>= 8;
					}
					c = c.Slice(64);
				}
				if (c.Length != 0)
				{
					Salsa20.Transform(array2, array, array3, null);
					for (int l = 0; l < c.Length; l++)
					{
						c[l] = array2[l];
					}
				}
			}
			finally
			{
				array.Clear();
				array2.Clear();
				array3.Clear();
			}
		}
	}
	internal static class StreamSalsa20Xor
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Transform(Span<byte> c, ReadOnlySpan<byte> m, ReadOnlySpan<byte> n, ReadOnlySpan<byte> k, ulong ic = 0uL)
		{
			if (m.Length == 0)
			{
				return;
			}
			byte[] array = new byte[16];
			byte[] array2 = new byte[64];
			byte[] array3 = k.Slice(0, 32).ToArray();
			try
			{
				n.Slice(0, 8).CopyTo(array);
				for (int i = 8; i < 16; i++)
				{
					array[i] = (byte)(ic & 0xFF);
					ic >>= 8;
				}
				int num = m.Length;
				while (num >= 64)
				{
					Salsa20.Transform(array2, array, array3, null);
					for (int j = 0; j < 64; j++)
					{
						c[j] = (byte)(m[j] ^ array2[j]);
					}
					uint num2 = 1u;
					for (int l = 8; l < 16; l++)
					{
						num2 += array[l];
						array[l] = (byte)num2;
						num2 >>= 8;
					}
					num -= 64;
					c = c.Slice(64);
					m = m.Slice(64);
				}
				if (num != 0)
				{
					Salsa20.Transform(array2, array, array3, null);
					for (int num3 = 0; num3 < num; num3++)
					{
						c[num3] = (byte)(m[num3] ^ array2[num3]);
					}
				}
			}
			finally
			{
				array.Clear();
				array2.Clear();
				array3.Clear();
			}
		}
	}
}
namespace NetMQ.Utils
{
	internal static class ArrayExtensions
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void Clear<T>(this T[] array)
		{
			if (array != null)
			{
				Array.Clear(array, 0, array.Length);
			}
		}
	}
}