Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NaCl Net v0.1.1300
BepInEx/core/NaCl.Net/netstandard2.1/NaCl.dll
Decompiled 2 years agousing 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); } } } }