<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

SecT283Field

static class SecT283Field
using Org.BouncyCastle.Math.Raw; using System; namespace Org.BouncyCastle.Math.EC.Custom.Sec { internal static class SecT283Field { private const ulong M27 = 134217727; private const ulong M57 = 144115188075855871; private static readonly ulong[] ROOT_Z = new ulong[5] { 878416384462358536, 3513665537849438403, 9369774767598502668, 585610922974906400, 34087042 }; public static void Add(ulong[] x, ulong[] y, ulong[] z) { z[0] = (x[0] ^ y[0]); z[1] = (x[1] ^ y[1]); z[2] = (x[2] ^ y[2]); z[3] = (x[3] ^ y[3]); z[4] = (x[4] ^ y[4]); } public static void AddBothTo(ulong[] x, ulong[] y, ulong[] z) { z[0] ^= (x[0] ^ y[0]); z[1] ^= (x[1] ^ y[1]); z[2] ^= (x[2] ^ y[2]); z[3] ^= (x[3] ^ y[3]); z[4] ^= (x[4] ^ y[4]); } public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz) { zz[0] = (xx[0] ^ yy[0]); zz[1] = (xx[1] ^ yy[1]); zz[2] = (xx[2] ^ yy[2]); zz[3] = (xx[3] ^ yy[3]); zz[4] = (xx[4] ^ yy[4]); zz[5] = (xx[5] ^ yy[5]); zz[6] = (xx[6] ^ yy[6]); zz[7] = (xx[7] ^ yy[7]); zz[8] = (xx[8] ^ yy[8]); } public static void AddOne(ulong[] x, ulong[] z) { z[0] = (x[0] ^ 1); z[1] = x[1]; z[2] = x[2]; z[3] = x[3]; z[4] = x[4]; } public static void AddTo(ulong[] x, ulong[] z) { z[0] ^= x[0]; z[1] ^= x[1]; z[2] ^= x[2]; z[3] ^= x[3]; z[4] ^= x[4]; } public static ulong[] FromBigInteger(BigInteger x) { return Nat.FromBigInteger64(283, x); } public static void HalfTrace(ulong[] x, ulong[] z) { ulong[] array = Nat.Create64(9); Nat320.Copy64(x, z); for (int i = 1; i < 283; i += 2) { ImplSquare(z, array); Reduce(array, z); ImplSquare(z, array); Reduce(array, z); AddTo(x, z); } } public static void Invert(ulong[] x, ulong[] z) { if (Nat320.IsZero64(x)) throw new InvalidOperationException(); ulong[] array = Nat320.Create64(); ulong[] array2 = Nat320.Create64(); Square(x, array); Multiply(array, x, array); SquareN(array, 2, array2); Multiply(array2, array, array2); SquareN(array2, 4, array); Multiply(array, array2, array); SquareN(array, 8, array2); Multiply(array2, array, array2); Square(array2, array2); Multiply(array2, x, array2); SquareN(array2, 17, array); Multiply(array, array2, array); Square(array, array); Multiply(array, x, array); SquareN(array, 35, array2); Multiply(array2, array, array2); SquareN(array2, 70, array); Multiply(array, array2, array); Square(array, array); Multiply(array, x, array); SquareN(array, 141, array2); Multiply(array2, array, array2); Square(array2, z); } public static void Multiply(ulong[] x, ulong[] y, ulong[] z) { ulong[] array = Nat320.CreateExt64(); ImplMultiply(x, y, array); Reduce(array, z); } public static void MultiplyAddToExt(ulong[] x, ulong[] y, ulong[] zz) { ulong[] array = Nat320.CreateExt64(); ImplMultiply(x, y, array); AddExt(zz, array, zz); } public static void MultiplyExt(ulong[] x, ulong[] y, ulong[] zz) { Array.Clear(zz, 0, 10); ImplMultiply(x, y, zz); } public static void Reduce(ulong[] xx, ulong[] z) { ulong num = xx[0]; ulong num2 = xx[1]; ulong num3 = xx[2]; ulong num4 = xx[3]; ulong num5 = xx[4]; ulong num6 = xx[5]; ulong num7 = xx[6]; ulong num8 = xx[7]; ulong num9 = xx[8]; num4 ^= ((num9 << 37) ^ (num9 << 42) ^ (num9 << 44) ^ (num9 << 49)); num5 ^= ((num9 >> 27) ^ (num9 >> 22) ^ (num9 >> 20) ^ (num9 >> 15)); num3 ^= ((num8 << 37) ^ (num8 << 42) ^ (num8 << 44) ^ (num8 << 49)); num4 ^= ((num8 >> 27) ^ (num8 >> 22) ^ (num8 >> 20) ^ (num8 >> 15)); num2 ^= ((num7 << 37) ^ (num7 << 42) ^ (num7 << 44) ^ (num7 << 49)); num3 ^= ((num7 >> 27) ^ (num7 >> 22) ^ (num7 >> 20) ^ (num7 >> 15)); num ^= ((num6 << 37) ^ (num6 << 42) ^ (num6 << 44) ^ (num6 << 49)); num2 ^= ((num6 >> 27) ^ (num6 >> 22) ^ (num6 >> 20) ^ (num6 >> 15)); ulong num10 = num5 >> 27; z[0] = (num ^ num10 ^ (num10 << 5) ^ (num10 << 7) ^ (num10 << 12)); z[1] = num2; z[2] = num3; z[3] = num4; z[4] = (num5 & 134217727); } public static void Reduce37(ulong[] z, int zOff) { ulong num = z[zOff + 4]; ulong num2 = num >> 27; z[zOff] ^= (num2 ^ (num2 << 5) ^ (num2 << 7) ^ (num2 << 12)); z[zOff + 4] = (num & 134217727); } public static void Sqrt(ulong[] x, ulong[] z) { ulong[] array = Nat320.Create64(); array[0] = Interleave.Unshuffle(x[0], x[1], out ulong even); array[1] = Interleave.Unshuffle(x[2], x[3], out ulong even2); array[2] = Interleave.Unshuffle(x[4], out ulong even3); Multiply(array, ROOT_Z, z); z[0] ^= even; z[1] ^= even2; z[2] ^= even3; } public static void Square(ulong[] x, ulong[] z) { ulong[] array = Nat.Create64(9); ImplSquare(x, array); Reduce(array, z); } public static void SquareAddToExt(ulong[] x, ulong[] zz) { ulong[] array = Nat.Create64(9); ImplSquare(x, array); AddExt(zz, array, zz); } public static void SquareExt(ulong[] x, ulong[] zz) { ImplSquare(x, zz); } public static void SquareN(ulong[] x, int n, ulong[] z) { ulong[] array = Nat.Create64(9); ImplSquare(x, array); Reduce(array, z); while (--n > 0) { ImplSquare(z, array); Reduce(array, z); } } public static uint Trace(ulong[] x) { return (uint)((int)(x[0] ^ (x[4] >> 15)) & 1); } private static void ImplCompactExt(ulong[] zz) { ulong num = zz[0]; ulong num2 = zz[1]; ulong num3 = zz[2]; ulong num4 = zz[3]; ulong num5 = zz[4]; ulong num6 = zz[5]; ulong num7 = zz[6]; ulong num8 = zz[7]; ulong num9 = zz[8]; ulong num10 = zz[9]; zz[0] = (num ^ (num2 << 57)); zz[1] = ((num2 >> 7) ^ (num3 << 50)); zz[2] = ((num3 >> 14) ^ (num4 << 43)); zz[3] = ((num4 >> 21) ^ (num5 << 36)); zz[4] = ((num5 >> 28) ^ (num6 << 29)); zz[5] = ((num6 >> 35) ^ (num7 << 22)); zz[6] = ((num7 >> 42) ^ (num8 << 15)); zz[7] = ((num8 >> 49) ^ (num9 << 8)); zz[8] = ((num9 >> 56) ^ (num10 << 1)); zz[9] = num10 >> 63; } private static void ImplExpand(ulong[] x, ulong[] z) { ulong num = x[0]; ulong num2 = x[1]; ulong num3 = x[2]; ulong num4 = x[3]; ulong num5 = x[4]; z[0] = (num & 144115188075855871); z[1] = (((num >> 57) ^ (num2 << 7)) & 144115188075855871); z[2] = (((num2 >> 50) ^ (num3 << 14)) & 144115188075855871); z[3] = (((num3 >> 43) ^ (num4 << 21)) & 144115188075855871); z[4] = ((num4 >> 36) ^ (num5 << 28)); } private static void ImplMultiply(ulong[] x, ulong[] y, ulong[] zz) { ulong[] array = new ulong[5]; ulong[] array2 = new ulong[5]; ImplExpand(x, array); ImplExpand(y, array2); ulong[] array3 = new ulong[26]; ImplMulw(zz, array[0], array2[0], array3, 0); ImplMulw(zz, array[1], array2[1], array3, 2); ImplMulw(zz, array[2], array2[2], array3, 4); ImplMulw(zz, array[3], array2[3], array3, 6); ImplMulw(zz, array[4], array2[4], array3, 8); ulong num = array[0] ^ array[1]; ulong num2 = array2[0] ^ array2[1]; ulong num3 = array[0] ^ array[2]; ulong num4 = array2[0] ^ array2[2]; ulong num5 = array[2] ^ array[4]; ulong num6 = array2[2] ^ array2[4]; ulong num7 = array[3] ^ array[4]; ulong num8 = array2[3] ^ array2[4]; ImplMulw(zz, num3 ^ array[3], num4 ^ array2[3], array3, 18); ImplMulw(zz, num5 ^ array[1], num6 ^ array2[1], array3, 20); ulong num9 = num ^ num7; ulong num10 = num2 ^ num8; ulong x2 = num9 ^ array[2]; ulong y2 = num10 ^ array2[2]; ImplMulw(zz, num9, num10, array3, 22); ImplMulw(zz, x2, y2, array3, 24); ImplMulw(zz, num, num2, array3, 10); ImplMulw(zz, num3, num4, array3, 12); ImplMulw(zz, num5, num6, array3, 14); ImplMulw(zz, num7, num8, array3, 16); zz[0] = array3[0]; zz[9] = array3[9]; ulong num11 = array3[0] ^ array3[1]; ulong num12 = num11 ^ array3[2]; ulong num13 = zz[1] = (num12 ^ array3[10]); ulong num14 = array3[3] ^ array3[4]; ulong num15 = array3[11] ^ array3[12]; ulong num16 = num14 ^ num15; ulong num17 = zz[2] = (num12 ^ num16); ulong num18 = num11 ^ num14; ulong num19 = array3[5] ^ array3[6]; ulong num20 = num18 ^ num19 ^ array3[8]; ulong num21 = array3[13] ^ array3[14]; ulong num22 = num20 ^ num21; ulong num23 = array3[18] ^ array3[22] ^ array3[24]; ulong num24 = zz[3] = (num22 ^ num23); ulong num25 = array3[7] ^ array3[8] ^ array3[9]; ulong num26 = zz[8] = (num25 ^ array3[17]); ulong num27 = num25 ^ num19; ulong num28 = array3[15] ^ array3[16]; ulong num29 = (zz[7] = (num27 ^ num28)) ^ num13; ulong num30 = array3[19] ^ array3[20]; ulong num31 = array3[25] ^ array3[24]; ulong num32 = array3[18] ^ array3[23]; ulong num33 = num30 ^ num31; ulong num34 = zz[4] = (num33 ^ num32 ^ num29); ulong num35 = num17 ^ num26; ulong num36 = num33 ^ num35; ulong num37 = array3[21] ^ array3[22]; ulong num38 = zz[5] = (num36 ^ num37); ulong num39 = zz[6] = (num20 ^ array3[0] ^ array3[9] ^ num21 ^ array3[21] ^ array3[23] ^ array3[25]); ImplCompactExt(zz); } private static void ImplMulw(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) { u[1] = y; u[2] = u[1] << 1; u[3] = (u[2] ^ y); u[4] = u[2] << 1; u[5] = (u[4] ^ y); u[6] = u[3] << 1; u[7] = (u[6] ^ y); uint num = (uint)x; ulong num2 = 0; ulong num3 = u[num & 7]; int num4 = 48; do { num = (uint)(x >> num4); ulong num5 = u[num & 7] ^ (u[(num >> 3) & 7] << 3) ^ (u[(num >> 6) & 7] << 6); num3 ^= num5 << num4; num2 ^= num5 >> -num4; } while ((num4 -= 9) > 0); num2 ^= (ulong)((long)(x & 72198606942111744) & ((long)(y << 7) >> 63)) >> 8; z[zOff] = (num3 & 144115188075855871); z[zOff + 1] = ((num3 >> 57) ^ (num2 << 7)); } private static void ImplSquare(ulong[] x, ulong[] zz) { zz[8] = Interleave.Expand32to64((uint)x[4]); Interleave.Expand64To128(x, 0, 4, zz, 0); } } }