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

Scalar25519

static class Scalar25519
using Org.BouncyCastle.Math.Raw; using System; namespace Org.BouncyCastle.Math.EC.Rfc8032 { internal static class Scalar25519 { internal const int Size = 8; private const int ScalarBytes = 32; private const long M28L = 268435455; private const int TargetLength = 254; private static readonly uint[] L = new uint[8] { 1559614445, 1477600026, 2734136534, 350157278, 0, 0, 0, 268435456 }; private static readonly uint[] LSq = new uint[16] { 2870118761, 3807245957, 580428573, 1745064566, 3524785598, 1036971123, 461123738, 2712901953, 1268693629, 3405925475, 3562992538, 43769659, 0, 0, 0, 16777216 }; private const int L0 = -50998291; private const int L1 = 19280294; private const int L2 = 127719000; private const int L3 = -6428113; private const int L4 = 5343; internal static bool CheckVar(byte[] s, uint[] n) { Decode(s, n); return !Nat256.Gte(n, L); } internal static void Decode(byte[] k, uint[] n) { Codec.Decode32(k, 0, n, 0, 8); } internal static void GetOrderWnafVar(int width, sbyte[] ws) { Wnaf.GetSignedVar(L, width, ws); } internal static void Multiply128Var(uint[] x, uint[] y128, uint[] z) { uint[] array = new uint[12]; Nat256.Mul128(x, y128, array); if ((int)y128[3] < 0) { Nat256.AddTo(L, 0, array, 4, 0); Nat256.SubFrom(x, 0, array, 4, 0); } byte[] array2 = new byte[48]; Codec.Encode32(array, 0, 12, array2, 0); Decode(Reduce384(array2), z); } internal static byte[] Reduce384(byte[] n) { byte[] array = new byte[32]; long num = Codec.Decode32(n, 0); long num2 = Codec.Decode24(n, 4) << 4; long num3 = Codec.Decode32(n, 7); long num4 = Codec.Decode24(n, 11) << 4; long num5 = Codec.Decode32(n, 14); long num6 = Codec.Decode24(n, 18) << 4; long num7 = Codec.Decode32(n, 21); long num8 = Codec.Decode24(n, 25) << 4; long num9 = Codec.Decode32(n, 28); long num10 = Codec.Decode24(n, 32) << 4; long num11 = Codec.Decode32(n, 35); long num12 = Codec.Decode24(n, 39) << 4; long num13 = Codec.Decode32(n, 42); long num14 = Codec.Decode16(n, 46) << 4; num14 += num13 >> 28; num13 &= 268435455; num5 -= num14 * -50998291; num6 -= num14 * 19280294; num7 -= num14 * 127719000; num8 -= num14 * -6428113; num9 -= num14 * 5343; num13 += num12 >> 28; num12 &= 268435455; num4 -= num13 * -50998291; num5 -= num13 * 19280294; num6 -= num13 * 127719000; num7 -= num13 * -6428113; num8 -= num13 * 5343; num12 += num11 >> 28; num11 &= 268435455; num3 -= num12 * -50998291; num4 -= num12 * 19280294; num5 -= num12 * 127719000; num6 -= num12 * -6428113; num7 -= num12 * 5343; num11 += num10 >> 28; num10 &= 268435455; num2 -= num11 * -50998291; num3 -= num11 * 19280294; num4 -= num11 * 127719000; num5 -= num11 * -6428113; num6 -= num11 * 5343; num9 += num8 >> 28; num8 &= 268435455; num10 += num9 >> 28; num9 &= 268435455; long num15 = (num9 >> 27) & 1; num10 += num15; num -= num10 * -50998291; num2 -= num10 * 19280294; num3 -= num10 * 127719000; num4 -= num10 * -6428113; num5 -= num10 * 5343; num2 += num >> 28; num &= 268435455; num3 += num2 >> 28; num2 &= 268435455; num4 += num3 >> 28; num3 &= 268435455; num5 += num4 >> 28; num4 &= 268435455; num6 += num5 >> 28; num5 &= 268435455; num7 += num6 >> 28; num6 &= 268435455; num8 += num7 >> 28; num7 &= 268435455; num9 += num8 >> 28; num8 &= 268435455; num10 = num9 >> 28; num9 &= 268435455; num10 -= num15; num += (num10 & -50998291); num2 += (num10 & 19280294); num3 += (num10 & 127719000); num4 += (num10 & -6428113); num5 += (num10 & 5343); num2 += num >> 28; num &= 268435455; num3 += num2 >> 28; num2 &= 268435455; num4 += num3 >> 28; num3 &= 268435455; num5 += num4 >> 28; num4 &= 268435455; num6 += num5 >> 28; num5 &= 268435455; num7 += num6 >> 28; num6 &= 268435455; num8 += num7 >> 28; num7 &= 268435455; num9 += num8 >> 28; num8 &= 268435455; Codec.Encode56((ulong)(num | (num2 << 28)), array, 0); Codec.Encode56((ulong)(num3 | (num4 << 28)), array, 7); Codec.Encode56((ulong)(num5 | (num6 << 28)), array, 14); Codec.Encode56((ulong)(num7 | (num8 << 28)), array, 21); Codec.Encode32((uint)num9, array, 28); return array; } internal static byte[] Reduce512(byte[] n) { byte[] array = new byte[32]; long num = Codec.Decode32(n, 0); long num2 = Codec.Decode24(n, 4) << 4; long num3 = Codec.Decode32(n, 7); long num4 = Codec.Decode24(n, 11) << 4; long num5 = Codec.Decode32(n, 14); long num6 = Codec.Decode24(n, 18) << 4; long num7 = Codec.Decode32(n, 21); long num8 = Codec.Decode24(n, 25) << 4; long num9 = Codec.Decode32(n, 28); long num10 = Codec.Decode24(n, 32) << 4; long num11 = Codec.Decode32(n, 35); long num12 = Codec.Decode24(n, 39) << 4; long num13 = Codec.Decode32(n, 42); long num14 = Codec.Decode24(n, 46) << 4; long num15 = Codec.Decode32(n, 49); long num16 = Codec.Decode24(n, 53) << 4; long num17 = Codec.Decode32(n, 56); long num18 = Codec.Decode24(n, 60) << 4; long num19 = n[63]; num10 -= num19 * -50998291; num11 -= num19 * 19280294; num12 -= num19 * 127719000; num13 -= num19 * -6428113; num14 -= num19 * 5343; num18 += num17 >> 28; num17 &= 268435455; num9 -= num18 * -50998291; num10 -= num18 * 19280294; num11 -= num18 * 127719000; num12 -= num18 * -6428113; num13 -= num18 * 5343; num8 -= num17 * -50998291; num9 -= num17 * 19280294; num10 -= num17 * 127719000; num11 -= num17 * -6428113; num12 -= num17 * 5343; num16 += num15 >> 28; num15 &= 268435455; num7 -= num16 * -50998291; num8 -= num16 * 19280294; num9 -= num16 * 127719000; num10 -= num16 * -6428113; num11 -= num16 * 5343; num6 -= num15 * -50998291; num7 -= num15 * 19280294; num8 -= num15 * 127719000; num9 -= num15 * -6428113; num10 -= num15 * 5343; num14 += num13 >> 28; num13 &= 268435455; num5 -= num14 * -50998291; num6 -= num14 * 19280294; num7 -= num14 * 127719000; num8 -= num14 * -6428113; num9 -= num14 * 5343; num13 += num12 >> 28; num12 &= 268435455; num4 -= num13 * -50998291; num5 -= num13 * 19280294; num6 -= num13 * 127719000; num7 -= num13 * -6428113; num8 -= num13 * 5343; num12 += num11 >> 28; num11 &= 268435455; num3 -= num12 * -50998291; num4 -= num12 * 19280294; num5 -= num12 * 127719000; num6 -= num12 * -6428113; num7 -= num12 * 5343; num11 += num10 >> 28; num10 &= 268435455; num2 -= num11 * -50998291; num3 -= num11 * 19280294; num4 -= num11 * 127719000; num5 -= num11 * -6428113; num6 -= num11 * 5343; num9 += num8 >> 28; num8 &= 268435455; num10 += num9 >> 28; num9 &= 268435455; long num20 = (num9 >> 27) & 1; num10 += num20; num -= num10 * -50998291; num2 -= num10 * 19280294; num3 -= num10 * 127719000; num4 -= num10 * -6428113; num5 -= num10 * 5343; num2 += num >> 28; num &= 268435455; num3 += num2 >> 28; num2 &= 268435455; num4 += num3 >> 28; num3 &= 268435455; num5 += num4 >> 28; num4 &= 268435455; num6 += num5 >> 28; num5 &= 268435455; num7 += num6 >> 28; num6 &= 268435455; num8 += num7 >> 28; num7 &= 268435455; num9 += num8 >> 28; num8 &= 268435455; num10 = num9 >> 28; num9 &= 268435455; num10 -= num20; num += (num10 & -50998291); num2 += (num10 & 19280294); num3 += (num10 & 127719000); num4 += (num10 & -6428113); num5 += (num10 & 5343); num2 += num >> 28; num &= 268435455; num3 += num2 >> 28; num2 &= 268435455; num4 += num3 >> 28; num3 &= 268435455; num5 += num4 >> 28; num4 &= 268435455; num6 += num5 >> 28; num5 &= 268435455; num7 += num6 >> 28; num6 &= 268435455; num8 += num7 >> 28; num7 &= 268435455; num9 += num8 >> 28; num8 &= 268435455; Codec.Encode56((ulong)(num | (num2 << 28)), array, 0); Codec.Encode56((ulong)(num3 | (num4 << 28)), array, 7); Codec.Encode56((ulong)(num5 | (num6 << 28)), array, 14); Codec.Encode56((ulong)(num7 | (num8 << 28)), array, 21); Codec.Encode32((uint)num9, array, 28); return array; } internal static bool ReduceBasisVar(uint[] k, uint[] z0, uint[] z1) { uint[] x = new uint[16]; Array.Copy(LSq, x, 16); uint[] y = new uint[16]; Nat256.Square(k, y); y[0]++; uint[] array = new uint[16]; Nat256.Mul(L, k, array); uint[] t = new uint[16]; uint[] x2 = new uint[4]; Array.Copy(L, x2, 4); uint[] x3 = new uint[4]; uint[] y2 = new uint[4]; Array.Copy(k, y2, 4); uint[] y3 = new uint[4] { 1, 0, 0, 0 }; int num = 1016; int num2 = 15; int bitLengthPositive = ScalarUtilities.GetBitLengthPositive(num2, y); while (bitLengthPositive > 254) { if (--num < 0) return false; int num3 = ScalarUtilities.GetBitLength(num2, array) - bitLengthPositive; num3 &= ~(num3 >> 31); if ((int)array[num2] < 0) { ScalarUtilities.AddShifted_NP(num2, num3, x, y, array, t); ScalarUtilities.AddShifted_UV(3, num3, x2, x3, y2, y3); } else { ScalarUtilities.SubShifted_NP(num2, num3, x, y, array, t); ScalarUtilities.SubShifted_UV(3, num3, x2, x3, y2, y3); } if (ScalarUtilities.LessThan(num2, x, y)) { ScalarUtilities.Swap(ref x2, ref y2); ScalarUtilities.Swap(ref x3, ref y3); ScalarUtilities.Swap(ref x, ref y); num2 = bitLengthPositive >> 5; bitLengthPositive = ScalarUtilities.GetBitLengthPositive(num2, y); } } Array.Copy(y2, z0, 4); Array.Copy(y3, z1, 4); return true; } internal static void ToSignedDigits(int bits, uint[] z) { Nat.CAddTo(8, (int)(~z[0] & 1), L, z); Nat.ShiftDownBit(8, z, 1); } } }