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);
}
}
}
}