<PackageReference Include="SSH.NET" Version="2023.0.1" />

Mod

abstract class Mod
using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Utilities; using Renci.SshNet.Security.Org.BouncyCastle.Security; using System; namespace Renci.SshNet.Security.Org.BouncyCastle.Math.Raw { internal abstract class Mod { private static readonly SecureRandom RandomSource = new SecureRandom(); public static void Invert(uint[] p, uint[] x, uint[] z) { int num = p.Length; if (Nat.IsZero(num, x)) throw new ArgumentException("cannot be 0", "x"); if (Nat.IsOne(num, x)) Array.Copy(x, 0, z, 0, num); else { uint[] array = Nat.Copy(num, x); uint[] array2 = Nat.Create(num); array2[0] = 1; int xc = 0; if ((array[0] & 1) == 0) InversionStep(p, array, num, array2, ref xc); if (Nat.IsOne(num, array)) InversionResult(p, xc, array2, z); else { uint[] array3 = Nat.Copy(num, p); uint[] array4 = Nat.Create(num); int xc2 = 0; int num2 = num; while (true) { if (array[num2 - 1] == 0 && array3[num2 - 1] == 0) num2--; else if (Nat.Gte(num, array, array3)) { Nat.SubFrom(num, array3, array); xc += Nat.SubFrom(num, array4, array2) - xc2; InversionStep(p, array, num2, array2, ref xc); if (Nat.IsOne(num, array)) { InversionResult(p, xc, array2, z); return; } } else { Nat.SubFrom(num, array, array3); xc2 += Nat.SubFrom(num, array2, array4) - xc; InversionStep(p, array3, num2, array4, ref xc2); if (Nat.IsOne(num, array3)) break; } } InversionResult(p, xc2, array4, z); } } } public static uint[] Random(uint[] p) { int num = p.Length; uint[] array = Nat.Create(num); uint num2 = p[num - 1]; num2 |= num2 >> 1; num2 |= num2 >> 2; num2 |= num2 >> 4; num2 |= num2 >> 8; num2 |= num2 >> 16; do { byte[] array2 = new byte[num << 2]; RandomSource.NextBytes(array2); Pack.BE_To_UInt32(array2, 0, array); array[num - 1] &= num2; } while (Nat.Gte(num, array, p)); return array; } public static void Add(uint[] p, uint[] x, uint[] y, uint[] z) { int len = p.Length; if (Nat.Add(len, x, y, z) != 0) Nat.SubFrom(len, p, z); } public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z) { int len = p.Length; if (Nat.Sub(len, x, y, z) != 0) Nat.AddTo(len, p, z); } private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z) { if (ac < 0) Nat.Add(p.Length, a, p, z); else Array.Copy(a, 0, z, 0, p.Length); } private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc) { int len = p.Length; int num = 0; while (u[0] == 0) { Nat.ShiftDownWord(uLen, u, 0); num += 32; } int trailingZeroes = GetTrailingZeroes(u[0]); if (trailingZeroes > 0) { Nat.ShiftDownBits(uLen, u, trailingZeroes, 0); num += trailingZeroes; } for (int i = 0; i < num; i++) { if ((x[0] & 1) != 0) { if (xc < 0) xc += (int)Nat.AddTo(len, p, x); else xc += Nat.SubFrom(len, p, x); } Nat.ShiftDownBit(len, x, (uint)xc); } } private static int GetTrailingZeroes(uint x) { int num = 0; while ((x & 1) == 0) { x >>= 1; num++; } return num; } } }