From 4172bd983f6fbc1e010977266442432fa96aa5a2 Mon Sep 17 00:00:00 2001 From: Robert Hague Date: Mon, 9 Sep 2024 18:29:15 +0200 Subject: [PATCH] Reference System.Memory and use it in math/raw --- crypto/src/BouncyCastle.Crypto.csproj | 12 + crypto/src/math/raw/Bits.cs | 6 - crypto/src/math/raw/Interleave.cs | 30 +- crypto/src/math/raw/Mod.cs | 124 -- crypto/src/math/raw/Nat.cs | 2060 ++----------------------- crypto/src/math/raw/Nat128.cs | 275 +--- crypto/src/math/raw/Nat160.cs | 281 +--- crypto/src/math/raw/Nat192.cs | 399 +---- crypto/src/math/raw/Nat224.cs | 758 +-------- crypto/src/math/raw/Nat256.cs | 1001 +----------- crypto/src/math/raw/Nat320.cs | 21 +- crypto/src/math/raw/Nat384.cs | 28 +- crypto/src/math/raw/Nat448.cs | 68 +- crypto/src/math/raw/Nat512.cs | 331 +--- crypto/src/math/raw/Nat576.cs | 29 +- 15 files changed, 317 insertions(+), 5106 deletions(-) diff --git a/crypto/src/BouncyCastle.Crypto.csproj b/crypto/src/BouncyCastle.Crypto.csproj index e45a736fb6..22e97639f9 100644 --- a/crypto/src/BouncyCastle.Crypto.csproj +++ b/crypto/src/BouncyCastle.Crypto.csproj @@ -6,6 +6,7 @@ ..\..\BouncyCastle.NET.snk true 1591 + 10.0 BouncyCastle.Cryptography BouncyCastle.NET Cryptography ($(TargetFramework)) @@ -87,6 +88,13 @@ + + + + + + + @@ -101,6 +109,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/crypto/src/math/raw/Bits.cs b/crypto/src/math/raw/Bits.cs index 3efc890d6d..8ee30a4a0f 100644 --- a/crypto/src/math/raw/Bits.cs +++ b/crypto/src/math/raw/Bits.cs @@ -1,7 +1,5 @@ using System.Diagnostics; -#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER using System.Runtime.CompilerServices; -#endif namespace Org.BouncyCastle.Math.Raw { @@ -36,9 +34,7 @@ internal static ulong BitPermuteStep(ulong x, ulong m, int s) #endif internal static void BitPermuteStep2(ref uint hi, ref uint lo, uint m, int s) { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP1_1_OR_GREATER Debug.Assert(!Unsafe.AreSame(ref hi, ref lo) || (m & (m << s)) == 0U); -#endif Debug.Assert((m << s) >> s == m); uint t = ((lo >> s) ^ hi) & m; @@ -51,9 +47,7 @@ internal static void BitPermuteStep2(ref uint hi, ref uint lo, uint m, int s) #endif internal static void BitPermuteStep2(ref ulong hi, ref ulong lo, ulong m, int s) { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP1_1_OR_GREATER Debug.Assert(!Unsafe.AreSame(ref hi, ref lo) || (m & (m << s)) == 0UL); -#endif Debug.Assert((m << s) >> s == m); ulong t = ((lo >> s) ^ hi) & m; diff --git a/crypto/src/math/raw/Interleave.cs b/crypto/src/math/raw/Interleave.cs index e71f8e394a..7b7feb2112 100644 --- a/crypto/src/math/raw/Interleave.cs +++ b/crypto/src/math/raw/Interleave.cs @@ -66,27 +66,9 @@ internal static ulong Expand32to64(uint x) internal static void Expand64To128(ulong x, ulong[] z, int zOff) { -#if NETCOREAPP3_0_OR_GREATER - if (Org.BouncyCastle.Runtime.Intrinsics.X86.Bmi2.X64.IsEnabled) - { - z[zOff ] = Bmi2.X64.ParallelBitDeposit(x , 0x5555555555555555UL); - z[zOff + 1] = Bmi2.X64.ParallelBitDeposit(x >> 32, 0x5555555555555555UL); - return; - } -#endif - - // "shuffle" low half to even bits and high half to odd bits - x = Bits.BitPermuteStep(x, 0x00000000FFFF0000UL, 16); - x = Bits.BitPermuteStep(x, 0x0000FF000000FF00UL, 8); - x = Bits.BitPermuteStep(x, 0x00F000F000F000F0UL, 4); - x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); - x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); - - z[zOff ] = (x ) & M64; - z[zOff + 1] = (x >> 1) & M64; + Expand64To128(x, z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER internal static void Expand64To128(ulong x, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -108,19 +90,12 @@ internal static void Expand64To128(ulong x, Span z) z[0] = (x ) & M64; z[1] = (x >> 1) & M64; } -#endif internal static void Expand64To128(ulong[] xs, int xsOff, int xsLen, ulong[] zs, int zsOff) { - int xsPos = xsLen, zsPos = zsOff + (xsLen << 1); - while (--xsPos >= 0) - { - zsPos -= 2; - Expand64To128(xs[xsOff + xsPos], zs, zsPos); - } + Expand64To128(xs.AsSpan(xsOff, xsLen), zs.AsSpan(zsOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER internal static void Expand64To128(ReadOnlySpan xs, Span zs) { int xsPos = xs.Length, zsPos = xs.Length << 1; @@ -131,7 +106,6 @@ internal static void Expand64To128(ReadOnlySpan xs, Span zs) Expand64To128(xs[xsPos], zs[zsPos..]); } } -#endif internal static ulong Expand64To128Rev(ulong x, out ulong low) { diff --git a/crypto/src/math/raw/Mod.cs b/crypto/src/math/raw/Mod.cs index 9059e479cd..f49c20fc42 100644 --- a/crypto/src/math/raw/Mod.cs +++ b/crypto/src/math/raw/Mod.cs @@ -22,21 +22,13 @@ internal static class Mod private static readonly int MaxStackAlloc = Platform.Is64BitProcess ? 4096 : 1024; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void CheckedModOddInverse(ReadOnlySpan m, ReadOnlySpan x, Span z) -#else - public static void CheckedModOddInverse(uint[] m, uint[] x, uint[] z) -#endif { if (0 == ModOddInverse(m, x, z)) throw new ArithmeticException("Inverse does not exist."); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void CheckedModOddInverseVar(ReadOnlySpan m, ReadOnlySpan x, Span z) -#else - public static void CheckedModOddInverseVar(uint[] m, uint[] x, uint[] z) -#endif { if (!ModOddInverseVar(m, x, z)) throw new ArithmeticException("Inverse does not exist."); @@ -71,11 +63,7 @@ public static ulong Inverse64(ulong d) return x; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ModOddInverse(ReadOnlySpan m, ReadOnlySpan x, Span z) -#else - public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) -#endif { int len32 = m.Length; Debug.Assert(len32 > 0); @@ -85,7 +73,6 @@ public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) int bits = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]); int len30 = (bits + 29) / 30; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int allocSize = len30 * 5; Span alloc = (allocSize * Integers.NumBytes <= MaxStackAlloc) ? stackalloc int[allocSize] @@ -97,24 +84,12 @@ public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) Span F = alloc[..len30]; alloc = alloc[len30..]; Span G = alloc[..len30]; alloc = alloc[len30..]; Span M = alloc[..len30]; -#else - int[] t = new int[4]; - int[] D = new int[len30]; - int[] E = new int[len30]; - int[] F = new int[len30]; - int[] G = new int[len30]; - int[] M = new int[len30]; -#endif E[0] = 1; Encode30(bits, x, G); Encode30(bits, m, M); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER M.CopyTo(F); -#else - Array.Copy(M, 0, F, 0, len30); -#endif // We use the "half delta" variant here, with theta == delta - 1/2 int theta = 0; @@ -139,11 +114,7 @@ public static uint ModOddInverse(uint[] m, uint[] x, uint[] z) return (uint)(EqualTo(len30, F, 1) & EqualTo(len30, G, 0)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool ModOddInverseVar(ReadOnlySpan m, ReadOnlySpan x, Span z) -#else - public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z) -#endif { int len32 = m.Length; Debug.Assert(len32 > 0); @@ -156,7 +127,6 @@ public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z) int clz = bits - Nat.GetBitLength(len32, x); Debug.Assert(clz >= 0); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int allocSize = len30 * 5; Span alloc = (allocSize * Integers.NumBytes <= MaxStackAlloc) ? stackalloc int[allocSize] @@ -168,24 +138,12 @@ public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z) Span F = alloc[..len30]; alloc = alloc[len30..]; Span G = alloc[..len30]; alloc = alloc[len30..]; Span M = alloc[..len30]; -#else - int[] t = new int[4]; - int[] D = new int[len30]; - int[] E = new int[len30]; - int[] F = new int[len30]; - int[] G = new int[len30]; - int[] M = new int[len30]; -#endif E[0] = 1; Encode30(bits, x, G); Encode30(bits, m, M); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER M.CopyTo(F); -#else - Array.Copy(M, 0, F, 0, len30); -#endif // We use the original safegcd here, with eta == 1 - delta // For shorter x, configure as if low zeros of x had been shifted away by divsteps @@ -242,11 +200,7 @@ public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ModOddIsCoprime(ReadOnlySpan m, ReadOnlySpan x) -#else - public static uint ModOddIsCoprime(uint[] m, uint[] x) -#endif { int len32 = m.Length; Debug.Assert(len32 > 0); @@ -256,7 +210,6 @@ public static uint ModOddIsCoprime(uint[] m, uint[] x) int bits = (len32 << 5) - Integers.NumberOfLeadingZeros((int)m[len32 - 1]); int len30 = (bits + 29) / 30; -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int allocSize = len30 * 3; Span alloc = (allocSize * Integers.NumBytes <= MaxStackAlloc) ? stackalloc int[allocSize] @@ -266,21 +219,11 @@ public static uint ModOddIsCoprime(uint[] m, uint[] x) Span F = alloc[..len30]; alloc = alloc[len30..]; Span G = alloc[..len30]; alloc = alloc[len30..]; Span M = alloc[..len30]; -#else - int[] t = new int[4]; - int[] F = new int[len30]; - int[] G = new int[len30]; - int[] M = new int[len30]; -#endif Encode30(bits, x, G); Encode30(bits, m, M); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER M.CopyTo(F); -#else - Array.Copy(M, 0, F, 0, len30); -#endif // We use the "half delta" variant here, with theta == delta - 1/2 int theta = 0; @@ -298,11 +241,7 @@ public static uint ModOddIsCoprime(uint[] m, uint[] x) return (uint)(EqualTo(len30, F, 1) & EqualTo(len30, G, 0)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool ModOddIsCoprimeVar(ReadOnlySpan m, ReadOnlySpan x) -#else - public static bool ModOddIsCoprimeVar(uint[] m, uint[] x) -#endif { int len32 = m.Length; Debug.Assert(len32 > 0); @@ -315,7 +254,6 @@ public static bool ModOddIsCoprimeVar(uint[] m, uint[] x) int clz = bits - Nat.GetBitLength(len32, x); Debug.Assert(clz >= 0); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER int allocSize = len30 * 3; Span alloc = (allocSize * Integers.NumBytes <= MaxStackAlloc) ? stackalloc int[allocSize] @@ -325,21 +263,11 @@ public static bool ModOddIsCoprimeVar(uint[] m, uint[] x) Span F = alloc[..len30]; alloc = alloc[len30..]; Span G = alloc[..len30]; alloc = alloc[len30..]; Span M = alloc[..len30]; -#else - int[] t = new int[4]; - int[] F = new int[len30]; - int[] G = new int[len30]; - int[] M = new int[len30]; -#endif Encode30(bits, x, G); Encode30(bits, m, M); -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER M.CopyTo(F); -#else - Array.Copy(M, 0, F, 0, len30); -#endif // We use the original safegcd here, with eta == 1 - delta // For shorter x, configure as if low zeros of x had been shifted away by divsteps @@ -425,11 +353,7 @@ public static void Random(SecureRandom random, ReadOnlySpan p, Span } #endif -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int Add30(int len30, Span D, ReadOnlySpan M) -#else - private static int Add30(int len30, int[] D, int[] M) -#endif { Debug.Assert(len30 > 0); Debug.Assert(D.Length >= len30); @@ -446,11 +370,7 @@ private static int Add30(int len30, int[] D, int[] M) return c; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void CNegate30(int len30, int cond, Span D) -#else - private static void CNegate30(int len30, int cond, int[] D) -#endif { Debug.Assert(len30 > 0); Debug.Assert(D.Length >= len30); @@ -465,11 +385,7 @@ private static void CNegate30(int len30, int cond, int[] D) D[last] = c; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void CNormalize30(int len30, int condNegate, Span D, ReadOnlySpan M) -#else - private static void CNormalize30(int len30, int condNegate, int[] D, int[] M) -#endif { Debug.Assert(len30 > 0); Debug.Assert(D.Length >= len30); @@ -513,11 +429,7 @@ private static void CNormalize30(int len30, int condNegate, int[] D, int[] M) } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void Decode30(int bits, ReadOnlySpan x, Span z) -#else - private static void Decode30(int bits, int[] x, uint[] z) -#endif { Debug.Assert(bits > 0); @@ -539,11 +451,7 @@ private static void Decode30(int bits, int[] x, uint[] z) } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int Divsteps30Var(int eta, int f0, int g0, Span t) -#else - private static int Divsteps30Var(int eta, int f0, int g0, int[] t) -#endif { int u = 1, v = 0, q = 0, r = 1; int f = f0, g = g0, m, w, x, y, z; @@ -606,11 +514,7 @@ private static int Divsteps30Var(int eta, int f0, int g0, int[] t) return eta; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void Encode30(int bits, ReadOnlySpan x, Span z) -#else - private static void Encode30(int bits, uint[] x, int[] z) -#endif { Debug.Assert(bits > 0); @@ -632,11 +536,7 @@ private static void Encode30(int bits, uint[] x, int[] z) } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int EqualTo(int len, ReadOnlySpan x, int y) -#else - private static int EqualTo(int len, int[] x, int y) -#endif { int d = x[0] ^ y; for (int i = 1; i < len; ++i) @@ -647,11 +547,7 @@ private static int EqualTo(int len, int[] x, int y) return (d - 1) >> 31; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static bool EqualToVar(int len, ReadOnlySpan x, int y) -#else - private static bool EqualToVar(int len, int[] x, int y) -#endif { int d = x[0] ^ y; if (d != 0) @@ -676,11 +572,7 @@ private static int GetMaximumHDDivsteps(int bits) return (int)((150964L * bits + 99243) >> 16); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int HDDivsteps30(int theta, int f0, int g0, Span t) -#else - private static int HDDivsteps30(int theta, int f0, int g0, int[] t) -#endif { int u = 1 << 30, v = 0, q = 0, r = 1 << 30; int f = f0, g = g0; @@ -722,11 +614,7 @@ private static int HDDivsteps30(int theta, int f0, int g0, int[] t) return theta; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int Negate30(int len30, Span D) -#else - private static int Negate30(int len30, int[] D) -#endif { Debug.Assert(len30 > 0); Debug.Assert(D.Length >= len30); @@ -742,11 +630,7 @@ private static int Negate30(int len30, int[] D) return c; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static int TrimFG30Var(int len30, Span F, Span G) -#else - private static int TrimFG30Var(int len30, int[] F, int[] G) -#endif { Debug.Assert(len30 > 0); Debug.Assert(F.Length >= len30); @@ -769,12 +653,8 @@ private static int TrimFG30Var(int len30, int[] F, int[] G) return len30; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void UpdateDE30(int len30, Span D, Span E, ReadOnlySpan t, int m0Inv32, ReadOnlySpan M) -#else - private static void UpdateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32, int[] M) -#endif { Debug.Assert(len30 > 0); Debug.Assert(D.Length >= len30); @@ -838,11 +718,7 @@ private static void UpdateDE30(int len30, int[] D, int[] E, int[] t, int m0Inv32 E[len30 - 1] = (int)ce; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static void UpdateFG30(int len30, Span F, Span G, ReadOnlySpan t) -#else - private static void UpdateFG30(int len30, int[] F, int[] G, int[] t) -#endif { Debug.Assert(len30 > 0); Debug.Assert(F.Length >= len30); diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs index 48bf3b2e14..09a4b3be16 100644 --- a/crypto/src/math/raw/Nat.cs +++ b/crypto/src/math/raw/Nat.cs @@ -14,19 +14,6 @@ internal static class Nat { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(int len, uint[] x, uint[] y, uint[] z) - { - ulong c = 0UL; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[i] + y[i]; - z[i] = (uint)c; - c >>= 32; - } - return (uint)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Add(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0UL; @@ -38,33 +25,7 @@ public static uint Add(int len, ReadOnlySpan x, ReadOnlySpan y, Span } return (uint)c; } -#endif - - public static uint Add33At(int len, uint x, uint[] z, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - ulong c = (ulong)z[zPos + 0] + x; - z[zPos + 0] = (uint)c; - c >>= 32; - c += (ulong)z[zPos + 1] + 1; - z[zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zPos + 2); - } - public static uint Add33At(int len, uint x, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - ulong c = (ulong)z[zOff + zPos] + x; - z[zOff + zPos] = (uint)c; - c >>= 32; - c += (ulong)z[zOff + zPos + 1] + 1; - z[zOff + zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Add33At(int len, uint x, Span z, int zPos) { Debug.Assert(zPos <= (len - 2)); @@ -76,31 +37,7 @@ public static uint Add33At(int len, uint x, Span z, int zPos) c >>= 32; return c == 0 ? 0 : IncAt(len, z, zPos + 2); } -#endif - - public static uint Add33To(int len, uint x, uint[] z) - { - ulong c = (ulong)z[0] + x; - z[0] = (uint)c; - c >>= 32; - c += (ulong)z[1] + 1; - z[1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, 2); - } - - public static uint Add33To(int len, uint x, uint[] z, int zOff) - { - ulong c = (ulong)z[zOff + 0] + x; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)z[zOff + 1] + 1; - z[zOff + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, 2); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Add33To(int len, uint x, Span z) { ulong c = (ulong)z[0] + x; @@ -111,33 +48,7 @@ public static uint Add33To(int len, uint x, Span z) c >>= 32; return c == 0 ? 0 : IncAt(len, z, 2); } -#endif - - public static uint AddBothTo(int len, uint[] x, uint[] y, uint[] z) - { - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[i] + y[i] + z[i]; - z[i] = (uint)c; - c >>= 32; - } - return (uint)c; - } - - public static uint AddBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[xOff + i] + y[yOff + i] + z[zOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddBothTo(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; @@ -149,33 +60,7 @@ public static uint AddBothTo(int len, ReadOnlySpan x, ReadOnlySpan y } return (uint)c; } -#endif - - public static uint AddDWordAt(int len, ulong x, uint[] z, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - ulong c = z[zPos + 0] + (x & M); - z[zPos + 0] = (uint)c; - c >>= 32; - c += z[zPos + 1] + (x >> 32); - z[zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zPos + 2); - } - - public static uint AddDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - ulong c = z[zOff + zPos] + (x & M); - z[zOff + zPos] = (uint)c; - c >>= 32; - c += z[zOff + zPos + 1] + (x >> 32); - z[zOff + zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 2); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddDWordAt(int len, ulong x, Span z, int zPos) { Debug.Assert(zPos <= (len - 2)); @@ -187,31 +72,7 @@ public static uint AddDWordAt(int len, ulong x, Span z, int zPos) c >>= 32; return c == 0 ? 0 : IncAt(len, z, zPos + 2); } -#endif - - public static uint AddDWordTo(int len, ulong x, uint[] z) - { - ulong c = (ulong)z[0] + (x & M); - z[0] = (uint)c; - c >>= 32; - c += (ulong)z[1] + (x >> 32); - z[1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, 2); - } - - public static uint AddDWordTo(int len, ulong x, uint[] z, int zOff) - { - ulong c = (ulong)z[zOff + 0] + (x & M); - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)z[zOff + 1] + (x >> 32); - z[zOff + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, 2); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddDWordTo(int len, ulong x, Span z) { ulong c = z[0] + (x & M); @@ -222,33 +83,12 @@ public static uint AddDWordTo(int len, ulong x, Span z) c >>= 32; return c == 0 ? 0 : IncAt(len, z, 2); } -#endif - - public static uint AddTo(int len, uint[] x, uint[] z) - { - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[i] + z[i]; - z[i] = (uint)c; - c >>= 32; - } - return (uint)c; - } public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff) { - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[xOff + i] + z[zOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (uint)c; + return AddTo(len, x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddTo(int len, ReadOnlySpan x, Span z) { ulong c = 0; @@ -260,21 +100,7 @@ public static uint AddTo(int len, ReadOnlySpan x, Span z) } return (uint)c; } -#endif - - public static uint AddTo(int len, uint[] x, int xOff, uint[] z, int zOff, uint cIn) - { - ulong c = cIn; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[xOff + i] + z[zOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddTo(int len, ReadOnlySpan x, Span z, uint cIn) { ulong c = cIn; @@ -286,22 +112,6 @@ public static uint AddTo(int len, ReadOnlySpan x, Span z, uint cIn) } return (uint)c; } -#endif - - public static uint AddToEachOther(int len, uint[] u, int uOff, uint[] v, int vOff) - { - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)u[uOff + i] + v[vOff + i]; - u[uOff + i] = (uint)c; - v[vOff + i] = (uint)c; - c >>= 32; - } - return (uint)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddToEachOther(int len, Span u, Span v) { ulong c = 0; @@ -314,27 +124,7 @@ public static uint AddToEachOther(int len, Span u, Span v) } return (uint)c; } -#endif - - public static uint AddWordAt(int len, uint x, uint[] z, int zPos) - { - Debug.Assert(zPos <= (len - 1)); - ulong c = (ulong)x + z[zPos]; - z[zPos] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zPos + 1); - } - - public static uint AddWordAt(int len, uint x, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= (len - 1)); - ulong c = (ulong)x + z[zOff + zPos]; - z[zOff + zPos] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, zPos + 1); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddWordAt(int len, uint x, Span z, int zPos) { Debug.Assert(zPos <= (len - 1)); @@ -343,25 +133,7 @@ public static uint AddWordAt(int len, uint x, Span z, int zPos) c >>= 32; return c == 0 ? 0 : IncAt(len, z, zPos + 1); } -#endif - - public static uint AddWordTo(int len, uint x, uint[] z) - { - ulong c = (ulong)x + z[0]; - z[0] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, 1); - } - - public static uint AddWordTo(int len, uint x, uint[] z, int zOff) - { - ulong c = (ulong)x + z[zOff]; - z[zOff] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zOff, 1); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddWordTo(int len, uint x, Span z) { ulong c = (ulong)x + z[0]; @@ -369,23 +141,7 @@ public static uint AddWordTo(int len, uint x, Span z) c >>= 32; return c == 0 ? 0 : IncAt(len, z, 1); } -#endif - - public static uint CAdd(int len, int mask, uint[] x, uint[] y, uint[] z) - { - uint MASK = (uint)-(mask & 1); - - ulong c = 0; - for (int i = 0; i < len; ++i) - { - c += (ulong)x[i] + (y[i] & MASK); - z[i] = (uint)c; - c >>= 32; - } - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint CAdd(int len, int mask, ReadOnlySpan x, ReadOnlySpan y, Span z) { uint MASK = (uint)-(mask & 1); @@ -399,23 +155,7 @@ public static uint CAdd(int len, int mask, ReadOnlySpan x, ReadOnlySpan>= 32; - } - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint CAddTo(int len, int mask, ReadOnlySpan x, Span z) { uint MASK = (uint)-(mask & 1); @@ -429,31 +169,7 @@ public static uint CAddTo(int len, int mask, ReadOnlySpan x, Span z) } return (uint)c; } -#endif - - public static void CMov(int len, int mask, uint[] x, int xOff, uint[] z, int zOff) - { - uint MASK = (uint)-(mask & 1); - - for (int i = 0; i < len; ++i) - { - uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; - z_i ^= diff & MASK; - z[zOff + i] = z_i; - } - - //uint half = 0x55555555U, rest = half << (-(int)MASK); - - //for (int i = 0; i < len; ++i) - //{ - // uint z_i = z[zOff + i], diff = z_i ^ x[xOff + i]; - // z_i ^= (diff & half); - // z_i ^= (diff & rest); - // z[zOff + i] = z_i; - //} - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void CMov(int len, int mask, ReadOnlySpan x, Span z) { uint MASK = (uint)-(mask & 1); @@ -475,9 +191,8 @@ public static void CMov(int len, int mask, ReadOnlySpan x, Span z) // z[i] = z_i; //} } -#endif - public static int Compare(int len, uint[] x, uint[] y) + public static int Compare(int len, ReadOnlySpan x, ReadOnlySpan y) { for (int i = len - 1; i >= 0; --i) { @@ -491,87 +206,24 @@ public static int Compare(int len, uint[] x, uint[] y) return 0; } - public static int Compare(int len, uint[] x, int xOff, uint[] y, int yOff) + public static void Copy(int len, uint[] x, int xOff, uint[] z, int zOff) { - for (int i = len - 1; i >= 0; --i) - { - uint x_i = x[xOff + i]; - uint y_i = y[yOff + i]; - if (x_i < y_i) - return -1; - if (x_i > y_i) - return 1; - } - return 0; + Array.Copy(x, xOff, z, zOff, len); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int Compare(int len, ReadOnlySpan x, ReadOnlySpan y) + public static void Copy(int len, ReadOnlySpan x, Span z) { - for (int i = len - 1; i >= 0; --i) - { - uint x_i = x[i]; - uint y_i = y[i]; - if (x_i < y_i) - return -1; - if (x_i > y_i) - return 1; - } - return 0; + x[..len].CopyTo(z); } -#endif - public static uint[] Copy(int len, uint[] x) + public static void Copy64(int len, ReadOnlySpan x, Span z) { - uint[] z = new uint[len]; - Array.Copy(x, 0, z, 0, len); - return z; + x[..len].CopyTo(z); } - public static void Copy(int len, uint[] x, uint[] z) + public static uint[] Create(int len) { - Array.Copy(x, 0, z, 0, len); - } - - public static void Copy(int len, uint[] x, int xOff, uint[] z, int zOff) - { - Array.Copy(x, xOff, z, zOff, len); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Copy(int len, ReadOnlySpan x, Span z) - { - x[..len].CopyTo(z); - } -#endif - - public static ulong[] Copy64(int len, ulong[] x) - { - ulong[] z = new ulong[len]; - Array.Copy(x, 0, z, 0, len); - return z; - } - - public static void Copy64(int len, ulong[] x, ulong[] z) - { - Array.Copy(x, 0, z, 0, len); - } - - public static void Copy64(int len, ulong[] x, int xOff, ulong[] z, int zOff) - { - Array.Copy(x, xOff, z, zOff, len); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Copy64(int len, ReadOnlySpan x, Span z) - { - x[..len].CopyTo(z); - } -#endif - - public static uint[] Create(int len) - { - return new uint[len]; + return new uint[len]; } public static ulong[] Create64(int len) @@ -579,33 +231,6 @@ public static ulong[] Create64(int len) return new ulong[len]; } - public static int CSub(int len, int mask, uint[] x, uint[] y, uint[] z) - { - long MASK = (uint)-(mask & 1); - long c = 0; - for (int i = 0; i < len; ++i) - { - c += x[i] - (y[i] & MASK); - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } - - public static int CSub(int len, int mask, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long MASK = (uint)-(mask & 1); - long c = 0; - for (int i = 0; i < len; ++i) - { - c += x[xOff + i] - (y[yOff + i] & MASK); - z[zOff + i] = (uint)c; - c >>= 32; - } - return (int)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int CSub(int len, int mask, ReadOnlySpan x, ReadOnlySpan y, Span z) { long MASK = (uint)-(mask & 1); @@ -618,19 +243,7 @@ public static int CSub(int len, int mask, ReadOnlySpan x, ReadOnlySpan z) { for (int i = 0; i < len; ++i) @@ -640,30 +253,7 @@ public static int Dec(int len, Span z) } return -1; } -#endif - - public static int Dec(int len, uint[] x, uint[] z) - { - int i = 0; - while (i < len) - { - uint c = x[i] - 1; - z[i] = c; - ++i; - if (c != uint.MaxValue) - { - while (i < len) - { - z[i] = x[i]; - ++i; - } - return 0; - } - } - return -1; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int Dec(int len, ReadOnlySpan x, Span z) { int i = 0; @@ -684,31 +274,7 @@ public static int Dec(int len, ReadOnlySpan x, Span z) } return -1; } -#endif - - public static int DecAt(int len, uint[] z, int zPos) - { - Debug.Assert(zPos <= len); - for (int i = zPos; i < len; ++i) - { - if (--z[i] != uint.MaxValue) - return 0; - } - return -1; - } - - public static int DecAt(int len, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= len); - for (int i = zPos; i < len; ++i) - { - if (--z[zOff + i] != uint.MaxValue) - return 0; - } - return -1; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int DecAt(int len, Span z, int zPos) { Debug.Assert(zPos <= len); @@ -719,19 +285,7 @@ public static int DecAt(int len, Span z, int zPos) } return -1; } -#endif - - public static bool Eq(int len, uint[] x, uint[] y) - { - for (int i = len - 1; i >= 0; --i) - { - if (x[i] != y[i]) - return false; - } - return true; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool Eq(int len, ReadOnlySpan x, ReadOnlySpan y) { for (int i = len - 1; i >= 0; --i) @@ -741,13 +295,8 @@ public static bool Eq(int len, ReadOnlySpan x, ReadOnlySpan y) } return true; } -#endif -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint EqualTo(int len, ReadOnlySpan x, uint y) -#else - public static uint EqualTo(int len, uint[] x, uint y) -#endif { uint d = x[0] ^ y; for (int i = 1; i < len; ++i) @@ -758,22 +307,7 @@ public static uint EqualTo(int len, uint[] x, uint y) return (uint)(((int)d - 1) >> 31); } - public static uint EqualTo(int len, uint[] x, int xOff, uint y) - { - uint d = x[xOff] ^ y; - for (int i = 1; i < len; ++i) - { - d |= x[xOff + i]; - } - d = (d >> 1) | (d & 1); - return (uint)(((int)d - 1) >> 31); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint EqualTo(int len, ReadOnlySpan x, ReadOnlySpan y) -#else - public static uint EqualTo(int len, uint[] x, uint[] y) -#endif { uint d = 0; for (int i = 0; i < len; ++i) @@ -784,23 +318,7 @@ public static uint EqualTo(int len, uint[] x, uint[] y) return (uint)(((int)d - 1) >> 31); } - public static uint EqualTo(int len, uint[] x, int xOff, uint[] y, int yOff) - { - uint d = 0; - for (int i = 0; i < len; ++i) - { - d |= x[xOff + i] ^ y[yOff + i]; - } - d = (d >> 1) | (d & 1); - return (uint)(((int)d - 1) >> 31); - } - - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint EqualToZero(int len, ReadOnlySpan x) -#else - public static uint EqualToZero(int len, uint[] x) -#endif { uint d = 0; for (int i = 0; i < len; ++i) @@ -811,17 +329,6 @@ public static uint EqualToZero(int len, uint[] x) return (uint)(((int)d - 1) >> 31); } - public static uint EqualToZero(int len, uint[] x, int xOff) - { - uint d = 0; - for (int i = 0; i < len; ++i) - { - d |= x[xOff + i]; - } - d = (d >> 1) | (d & 1); - return (uint)(((int)d - 1) >> 31); - } - public static uint[] FromBigInteger(int bits, BigInteger x) { if (x.SignValue < 0 || x.BitLength > bits) @@ -901,20 +408,6 @@ public static void FromBigInteger64(int bits, BigInteger x, Span z) } #endif - public static uint GetBit(uint[] x, int bit) - { - if (bit == 0) - return x[0] & 1; - - int w = bit >> 5; - if (w < 0 || w >= x.Length) - return 0; - - int b = bit & 31; - return (x[w] >> b) & 1; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint GetBit(ReadOnlySpan x, int bit) { if (bit == 0) @@ -927,13 +420,8 @@ public static uint GetBit(ReadOnlySpan x, int bit) int b = bit & 31; return (x[w] >> b) & 1; } -#endif -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int GetBitLength(int len, ReadOnlySpan x) -#else - public static int GetBitLength(int len, uint[] x) -#endif { for (int i = len - 1; i >= 0; --i) { @@ -944,17 +432,6 @@ public static int GetBitLength(int len, uint[] x) return 0; } - public static int GetBitLength(int len, uint[] x, int xOff) - { - for (int i = len - 1; i >= 0; --i) - { - uint x_i = x[xOff + i]; - if (x_i != 0) - return i * 32 + 32 - Integers.NumberOfLeadingZeros((int)x_i); - } - return 0; - } - public static int GetLengthForBits(int bits) { if (bits < 1) @@ -971,20 +448,6 @@ public static int GetLengthForBits64(int bits) return (int)(((uint)bits + 63) >> 6); } - public static bool Gte(int len, uint[] x, uint[] y) - { - for (int i = len - 1; i >= 0; --i) - { - uint x_i = x[i], y_i = y[i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool Gte(int len, ReadOnlySpan x, ReadOnlySpan y) { for (int i = len - 1; i >= 0; --i) @@ -997,19 +460,7 @@ public static bool Gte(int len, ReadOnlySpan x, ReadOnlySpan y) } return true; } -#endif - - public static uint Inc(int len, uint[] z) - { - for (int i = 0; i < len; ++i) - { - if (++z[i] != uint.MinValue) - return 0; - } - return 1; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Inc(int len, Span z) { for (int i = 0; i < len; ++i) @@ -1019,30 +470,6 @@ public static uint Inc(int len, Span z) } return 1; } -#endif - - public static uint Inc(int len, uint[] x, uint[] z) - { - int i = 0; - while (i < len) - { - uint c = x[i] + 1; - z[i] = c; - ++i; - if (c != 0) - { - while (i < len) - { - z[i] = x[i]; - ++i; - } - return 0; - } - } - return 1; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Inc(int len, ReadOnlySpan x, Span z) { int i = 0; @@ -1063,31 +490,7 @@ public static uint Inc(int len, ReadOnlySpan x, Span z) } return 1; } -#endif - - public static uint IncAt(int len, uint[] z, int zPos) - { - Debug.Assert(zPos <= len); - for (int i = zPos; i < len; ++i) - { - if (++z[i] != uint.MinValue) - return 0; - } - return 1; - } - - public static uint IncAt(int len, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= len); - for (int i = zPos; i < len; ++i) - { - if (++z[zOff + i] != uint.MinValue) - return 0; - } - return 1; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint IncAt(int len, Span z, int zPos) { Debug.Assert(zPos <= len); @@ -1098,9 +501,8 @@ public static uint IncAt(int len, Span z, int zPos) } return 1; } -#endif - public static bool IsOne(int len, uint[] x) + public static bool IsOne(int len, ReadOnlySpan x) { if (x[0] != 1) return false; @@ -1113,35 +515,6 @@ public static bool IsOne(int len, uint[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static bool IsOne(int len, ReadOnlySpan x) - { - if (x[0] != 1) - return false; - - for (int i = 1; i < len; ++i) - { - if (x[i] != 0) - return false; - } - return true; - } -#endif - - public static bool IsZero(int len, uint[] x) - { - if (x[0] != 0) - return false; - - for (int i = 1; i < len; ++i) - { - if (x[i] != 0) - return false; - } - return true; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero(int len, ReadOnlySpan x) { if (x[0] != 0) @@ -1154,33 +527,7 @@ public static bool IsZero(int len, ReadOnlySpan x) } return true; } -#endif - - public static int LessThan(int len, uint[] x, uint[] y) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)x[i] - y[i]; - c >>= 32; - } - Debug.Assert(c == 0L || c == -1L); - return (int)c; - } - - public static int LessThan(int len, uint[] x, int xOff, uint[] y, int yOff) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)x[xOff + i] - y[yOff + i]; - c >>= 32; - } - Debug.Assert(c == 0L || c == -1L); - return (int)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int LessThan(int len, ReadOnlySpan x, ReadOnlySpan y) { long c = 0; @@ -1192,29 +539,7 @@ public static int LessThan(int len, ReadOnlySpan x, ReadOnlySpan y) Debug.Assert(c == 0L || c == -1L); return (int)c; } -#endif - - public static void Mul(int len, uint[] x, uint[] y, uint[] zz) - { - zz[len] = MulWord(len, x[0], y, zz); - - for (int i = 1; i < len; ++i) - { - zz[i + len] = MulWordAddTo(len, x[i], y, 0, zz, i); - } - } - - public static void Mul(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - zz[zzOff + len] = MulWord(len, x[xOff], y, yOff, zz, zzOff); - - for (int i = 1; i < len; ++i) - { - zz[zzOff + i + len] = MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i); - } - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Mul(int len, ReadOnlySpan x, ReadOnlySpan y, Span zz) { zz[len] = MulWord(len, x[0], y, zz); @@ -1224,19 +549,12 @@ public static void Mul(int len, ReadOnlySpan x, ReadOnlySpan y, Span zz[i + len] = MulWordAddTo(len, x[i], y, zz[i..]); } } -#endif public static void Mul(uint[] x, int xOff, int xLen, uint[] y, int yOff, int yLen, uint[] zz, int zzOff) { - zz[zzOff + yLen] = MulWord(yLen, x[xOff], y, yOff, zz, zzOff); - - for (int i = 1; i < xLen; ++i) - { - zz[zzOff + i + yLen] = MulWordAddTo(yLen, x[xOff + i], y, yOff, zz, zzOff + i); - } + Mul(x.AsSpan(xOff, xLen), y.AsSpan(yOff, yLen), zz.AsSpan(zzOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { int xLen = x.Length, yLen = y.Length; @@ -1247,36 +565,7 @@ public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz zz[i + yLen] = MulWordAddTo(yLen, x[i], y, zz[i..]); } } -#endif - - public static uint MulAddTo(int len, uint[] x, uint[] y, uint[] zz) - { - ulong zc = 0; - for (int i = 0; i < len; ++i) - { - zc += MulWordAddTo(len, x[i], y, 0, zz, i) & M; - zc += zz[i + len] & M; - zz[i + len] = (uint)zc; - zc >>= 32; - } - return (uint)zc; - } - - public static uint MulAddTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong zc = 0; - for (int i = 0; i < len; ++i) - { - zc += MulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff) & M; - zc += zz[zzOff + len] & M; - zz[zzOff + len] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint MulAddTo(int len, ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong zc = 0; @@ -1289,23 +578,12 @@ public static uint MulAddTo(int len, ReadOnlySpan x, ReadOnlySpan y, } return (uint)zc; } -#endif public static uint Mul31BothAdd(int len, uint a, uint[] x, uint b, uint[] y, uint[] z, int zOff) { - ulong c = 0, aVal = a, bVal = b; - int i = 0; - do - { - c += aVal * x[i] + bVal * y[i] + z[zOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - while (++i < len); - return (uint)c; + return Mul31BothAdd(len, a, x, b, y, z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint Mul31BothAdd(int len, uint a, ReadOnlySpan x, uint b, ReadOnlySpan y, Span z) { @@ -1320,37 +598,7 @@ public static uint Mul31BothAdd(int len, uint a, ReadOnlySpan x, uint b, R while (++i < len); return (uint)c; } -#endif - - public static uint MulWord(int len, uint x, uint[] y, uint[] z) - { - ulong c = 0, xVal = x; - int i = 0; - do - { - c += xVal * y[i]; - z[i] = (uint)c; - c >>= 32; - } - while (++i < len); - return (uint)c; - } - - public static uint MulWord(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0, xVal = x; - int i = 0; - do - { - c += xVal * y[yOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - while (++i < len); - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint MulWord(int len, uint x, ReadOnlySpan y, Span z) { ulong c = 0, xVal = x; @@ -1364,23 +612,12 @@ public static uint MulWord(int len, uint x, ReadOnlySpan y, Span z) while (++i < len); return (uint)c; } -#endif public static uint MulWordAddTo(int len, uint x, uint[] y, int yOff, uint[] z, int zOff) { - ulong c = 0, xVal = x; - int i = 0; - do - { - c += xVal * y[yOff + i] + z[zOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - while (++i < len); - return (uint)c; + return MulWordAddTo(len, x, y.AsSpan(yOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint MulWordAddTo(int len, uint x, ReadOnlySpan y, Span z) { ulong c = 0, xVal = x; @@ -1394,25 +631,7 @@ public static uint MulWordAddTo(int len, uint x, ReadOnlySpan y, Span>= 32; - c += xVal * (y >> 32) + z[zPos + 1]; - z[zPos + 1] = (uint)c; - c >>= 32; - c += z[zPos + 2]; - z[zPos + 2] = (uint)c; - c >>= 32; - return c == 0 ? 0 : IncAt(len, z, zPos + 3); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint MulWordDwordAddAt(int len, uint x, ulong y, Span z, int zPos) { Debug.Assert(zPos <= (len - 3)); @@ -1428,21 +647,7 @@ public static uint MulWordDwordAddAt(int len, uint x, ulong y, Span z, int c >>= 32; return c == 0 ? 0 : IncAt(len, z, zPos + 3); } -#endif - - public static int Negate(int len, uint[] x, uint[] z) - { - long c = 0L; - for (int i = 0; i < len; ++i) - { - c -= x[i]; - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int Negate(int len, ReadOnlySpan x, Span z) { long c = 0L; @@ -1454,33 +659,7 @@ public static int Negate(int len, ReadOnlySpan x, Span z) } return (int)c; } -#endif - - public static uint ShiftDownBit(int len, uint[] z, uint c) - { - int i = len; - while (--i >= 0) - { - uint next = z[i]; - z[i] = (next >> 1) | (c << 31); - c = next; - } - return c << 31; - } - - public static uint ShiftDownBit(int len, uint[] z, int zOff, uint c) - { - int i = len; - while (--i >= 0) - { - uint next = z[zOff + i]; - z[zOff + i] = (next >> 1) | (c << 31); - c = next; - } - return c << 31; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftDownBit(int len, Span z, uint c) { int i = len; @@ -1492,9 +671,8 @@ public static uint ShiftDownBit(int len, Span z, uint c) } return c << 31; } -#endif - public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z) + public static uint ShiftDownBit(int len, ReadOnlySpan x, uint c, Span z) { int i = len; while (--i >= 0) @@ -1506,302 +684,88 @@ public static uint ShiftDownBit(int len, uint[] x, uint c, uint[] z) return c << 31; } - public static uint ShiftDownBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) + public static uint ShiftDownBits(int len, Span z, int bits, uint c) { + Debug.Assert(bits > 0 && bits < 32); int i = len; while (--i >= 0) { - uint next = x[xOff + i]; - z[zOff + i] = (next >> 1) | (c << 31); + uint next = z[i]; + z[i] = (next >> bits) | (c << -bits); c = next; } - return c << 31; + return c << -bits; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftDownBit(int len, ReadOnlySpan x, uint c, Span z) + public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) { - int i = len; - while (--i >= 0) - { - uint next = x[i]; - z[i] = (next >> 1) | (c << 31); - c = next; - } - return c << 31; + return ShiftDownBits(len, x.AsSpan(xOff), bits, c, z.AsSpan(zOff)); } -#endif - public static uint ShiftDownBits(int len, uint[] z, int bits, uint c) + public static uint ShiftDownBits(int len, ReadOnlySpan x, int bits, uint c, Span z) { Debug.Assert(bits > 0 && bits < 32); int i = len; while (--i >= 0) { - uint next = z[i]; + uint next = x[i]; z[i] = (next >> bits) | (c << -bits); c = next; } return c << -bits; } - public static uint ShiftDownBits(int len, uint[] z, int zOff, int bits, uint c) + public static ulong ShiftDownBits64(int len, ulong[] z, int zOff, int bits, ulong c) { - Debug.Assert(bits > 0 && bits < 32); + Debug.Assert(bits > 0 && bits < 64); int i = len; while (--i >= 0) { - uint next = z[zOff + i]; + ulong next = z[zOff + i]; z[zOff + i] = (next >> bits) | (c << -bits); c = next; } return c << -bits; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftDownBits(int len, Span z, int bits, uint c) + public static uint ShiftDownWord(int len, Span z, uint c) { - Debug.Assert(bits > 0 && bits < 32); int i = len; while (--i >= 0) { uint next = z[i]; - z[i] = (next >> bits) | (c << -bits); + z[i] = c; c = next; } - return c << -bits; + return c; } -#endif - public static uint ShiftDownBits(int len, uint[] x, int bits, uint c, uint[] z) + public static uint ShiftUpBit(int len, Span z, uint c) { - Debug.Assert(bits > 0 && bits < 32); - int i = len; - while (--i >= 0) + int i = 0, limit4 = len - 4; + while (i <= limit4) { - uint next = x[i]; - z[i] = (next >> bits) | (c << -bits); + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; + z[i + 0] = (next0 << 1) | (c >> 31); + z[i + 1] = (next1 << 1) | (next0 >> 31); + z[i + 2] = (next2 << 1) | (next1 >> 31); + z[i + 3] = (next3 << 1) | (next2 >> 31); + c = next3; + i += 4; + } + while (i < len) + { + uint next = z[i]; + z[i] = (next << 1) | (c >> 31); c = next; + ++i; } - return c << -bits; + return c >> 31; } - public static uint ShiftDownBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) - { - Debug.Assert(bits > 0 && bits < 32); - int i = len; - while (--i >= 0) - { - uint next = x[xOff + i]; - z[zOff + i] = (next >> bits) | (c << -bits); - c = next; - } - return c << -bits; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftDownBits(int len, ReadOnlySpan x, int bits, uint c, Span z) - { - Debug.Assert(bits > 0 && bits < 32); - int i = len; - while (--i >= 0) - { - uint next = x[i]; - z[i] = (next >> bits) | (c << -bits); - c = next; - } - return c << -bits; - } -#endif - - public static ulong ShiftDownBits64(int len, ulong[] z, int zOff, int bits, ulong c) - { - Debug.Assert(bits > 0 && bits < 64); - int i = len; - while (--i >= 0) - { - ulong next = z[zOff + i]; - z[zOff + i] = (next >> bits) | (c << -bits); - c = next; - } - return c << -bits; - } - - public static uint ShiftDownWord(int len, uint[] z, uint c) - { - int i = len; - while (--i >= 0) - { - uint next = z[i]; - z[i] = c; - c = next; - } - return c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftDownWord(int len, Span z, uint c) - { - int i = len; - while (--i >= 0) - { - uint next = z[i]; - z[i] = c; - c = next; - } - return c; - } -#endif - - public static uint ShiftUpBit(int len, uint[] z, uint c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBit(len, z.AsSpan(0, len), c); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[i + 0]; - uint next1 = z[i + 1]; - uint next2 = z[i + 2]; - uint next3 = z[i + 3]; - z[i + 0] = (next0 << 1) | (c >> 31); - z[i + 1] = (next1 << 1) | (next0 >> 31); - z[i + 2] = (next2 << 1) | (next1 >> 31); - z[i + 3] = (next3 << 1) | (next2 >> 31); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[i]; - z[i] = (next << 1) | (c >> 31); - c = next; - ++i; - } - return c >> 31; -#endif - } - - public static uint ShiftUpBit(int len, uint[] z, int zOff, uint c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBit(len, z.AsSpan(zOff, len), c); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[zOff + i + 0]; - uint next1 = z[zOff + i + 1]; - uint next2 = z[zOff + i + 2]; - uint next3 = z[zOff + i + 3]; - z[zOff + i + 0] = (next0 << 1) | (c >> 31); - z[zOff + i + 1] = (next1 << 1) | (next0 >> 31); - z[zOff + i + 2] = (next2 << 1) | (next1 >> 31); - z[zOff + i + 3] = (next3 << 1) | (next2 >> 31); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[zOff + i]; - z[zOff + i] = (next << 1) | (c >> 31); - c = next; - ++i; - } - return c >> 31; -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftUpBit(int len, Span z, uint c) - { - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[i + 0]; - uint next1 = z[i + 1]; - uint next2 = z[i + 2]; - uint next3 = z[i + 3]; - z[i + 0] = (next0 << 1) | (c >> 31); - z[i + 1] = (next1 << 1) | (next0 >> 31); - z[i + 2] = (next2 << 1) | (next1 >> 31); - z[i + 3] = (next3 << 1) | (next2 >> 31); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[i]; - z[i] = (next << 1) | (c >> 31); - c = next; - ++i; - } - return c >> 31; - } -#endif - - public static uint ShiftUpBit(int len, uint[] x, uint c, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBit(len, x.AsSpan(0, len), c, z.AsSpan(0, len)); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = x[i + 0]; - uint next1 = x[i + 1]; - uint next2 = x[i + 2]; - uint next3 = x[i + 3]; - z[i + 0] = (next0 << 1) | (c >> 31); - z[i + 1] = (next1 << 1) | (next0 >> 31); - z[i + 2] = (next2 << 1) | (next1 >> 31); - z[i + 3] = (next3 << 1) | (next2 >> 31); - c = next3; - i += 4; - } - while (i < len) - { - uint next = x[i]; - z[i] = (next << 1) | (c >> 31); - c = next; - ++i; - } - return c >> 31; -#endif - } - - public static uint ShiftUpBit(int len, uint[] x, int xOff, uint c, uint[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBit(len, x.AsSpan(xOff, len), c, z.AsSpan(zOff, len)); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = x[xOff + i + 0]; - uint next1 = x[xOff + i + 1]; - uint next2 = x[xOff + i + 2]; - uint next3 = x[xOff + i + 3]; - z[zOff + i + 0] = (next0 << 1) | (c >> 31); - z[zOff + i + 1] = (next1 << 1) | (next0 >> 31); - z[zOff + i + 2] = (next2 << 1) | (next1 >> 31); - z[zOff + i + 3] = (next3 << 1) | (next2 >> 31); - c = next3; - i += 4; - } - while (i < len) - { - uint next = x[xOff + i]; - z[zOff + i] = (next << 1) | (c >> 31); - c = next; - ++i; - } - return c >> 31; -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint ShiftUpBit(int len, ReadOnlySpan x, uint c, Span z) { int i = 0, limit4 = len - 4; @@ -1827,69 +791,12 @@ public static uint ShiftUpBit(int len, ReadOnlySpan x, uint c, Span } return c >> 31; } -#endif - - public static ulong ShiftUpBit64(int len, ulong[] x, ulong c, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBit64(len, x.AsSpan(0, len), c, z.AsSpan(0, len)); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - ulong next0 = x[i + 0]; - ulong next1 = x[i + 1]; - ulong next2 = x[i + 2]; - ulong next3 = x[i + 3]; - z[i + 0] = (next0 << 1) | (c >> 63); - z[i + 1] = (next1 << 1) | (next0 >> 63); - z[i + 2] = (next2 << 1) | (next1 >> 63); - z[i + 3] = (next3 << 1) | (next2 >> 63); - c = next3; - i += 4; - } - while (i < len) - { - ulong next = x[i]; - z[i] = (next << 1) | (c >> 63); - c = next; - ++i; - } - return c >> 63; -#endif - } public static ulong ShiftUpBit64(int len, ulong[] x, int xOff, ulong c, ulong[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER return ShiftUpBit64(len, x.AsSpan(xOff, len), c, z.AsSpan(zOff, len)); -#else - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - ulong next0 = x[xOff + i + 0]; - ulong next1 = x[xOff + i + 1]; - ulong next2 = x[xOff + i + 2]; - ulong next3 = x[xOff + i + 3]; - z[zOff + i + 0] = (next0 << 1) | (c >> 63); - z[zOff + i + 1] = (next1 << 1) | (next0 >> 63); - z[zOff + i + 2] = (next2 << 1) | (next1 >> 63); - z[zOff + i + 3] = (next3 << 1) | (next2 >> 63); - c = next3; - i += 4; - } - while (i < len) - { - ulong next = x[xOff + i]; - z[zOff + i] = (next << 1) | (c >> 63); - c = next; - ++i; - } - return c >> 63; -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static ulong ShiftUpBit64(int len, ReadOnlySpan x, ulong c, Span z) { int i = 0, limit4 = len - 4; @@ -1912,266 +819,20 @@ public static ulong ShiftUpBit64(int len, ReadOnlySpan x, ulong c, Span> 63); c = next; ++i; - } - return c >> 63; - } -#endif - - public static uint ShiftUpBits(int len, uint[] z, int bits, uint c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits(len, z.AsSpan(0, len), bits, c); -#else - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[i + 0]; - uint next1 = z[i + 1]; - uint next2 = z[i + 2]; - uint next3 = z[i + 3]; - z[i + 0] = (next0 << bits) | (c >> -bits); - z[i + 1] = (next1 << bits) | (next0 >> -bits); - z[i + 2] = (next2 << bits) | (next1 >> -bits); - z[i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[i]; - z[i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif - } - - public static uint ShiftUpBits(int len, uint[] z, int zOff, int bits, uint c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits(len, z.AsSpan(zOff, len), bits, c); -#else - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[zOff + i + 0]; - uint next1 = z[zOff + i + 1]; - uint next2 = z[zOff + i + 2]; - uint next3 = z[zOff + i + 3]; - z[zOff + i + 0] = (next0 << bits) | (c >> -bits); - z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); - z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); - z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[zOff + i]; - z[zOff + i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftUpBits(int len, Span z, int bits, uint c) - { - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = z[i + 0]; - uint next1 = z[i + 1]; - uint next2 = z[i + 2]; - uint next3 = z[i + 3]; - z[i + 0] = (next0 << bits) | (c >> -bits); - z[i + 1] = (next1 << bits) | (next0 >> -bits); - z[i + 2] = (next2 << bits) | (next1 >> -bits); - z[i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = z[i]; - z[i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; - } -#endif - - public static uint ShiftUpBits(int len, uint[] x, int bits, uint c, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits(len, x.AsSpan(0, len), bits, c, z.AsSpan(0, len)); -#else - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = x[i + 0]; - uint next1 = x[i + 1]; - uint next2 = x[i + 2]; - uint next3 = x[i + 3]; - z[i + 0] = (next0 << bits) | (c >> -bits); - z[i + 1] = (next1 << bits) | (next0 >> -bits); - z[i + 2] = (next2 << bits) | (next1 >> -bits); - z[i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = x[i]; - z[i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif - } - - public static uint ShiftUpBits(int len, uint[] x, int xOff, int bits, uint c, uint[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits(len, x.AsSpan(xOff, len), bits, c, z.AsSpan(zOff, len)); -#else - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = x[xOff + i + 0]; - uint next1 = x[xOff + i + 1]; - uint next2 = x[xOff + i + 2]; - uint next3 = x[xOff + i + 3]; - z[zOff + i + 0] = (next0 << bits) | (c >> -bits); - z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); - z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); - z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = x[xOff + i]; - z[zOff + i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static uint ShiftUpBits(int len, ReadOnlySpan x, int bits, uint c, Span z) - { - Debug.Assert(bits > 0 && bits < 32); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - uint next0 = x[i + 0]; - uint next1 = x[i + 1]; - uint next2 = x[i + 2]; - uint next3 = x[i + 3]; - z[i + 0] = (next0 << bits) | (c >> -bits); - z[i + 1] = (next1 << bits) | (next0 >> -bits); - z[i + 2] = (next2 << bits) | (next1 >> -bits); - z[i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - uint next = x[i]; - z[i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; - } -#endif - - public static ulong ShiftUpBits64(int len, ulong[] z, int bits, ulong c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits64(len, z.AsSpan(0, len), bits, c); -#else - Debug.Assert(bits > 0 && bits < 64); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - ulong next0 = z[i + 0]; - ulong next1 = z[i + 1]; - ulong next2 = z[i + 2]; - ulong next3 = z[i + 3]; - z[i + 0] = (next0 << bits) | (c >> -bits); - z[i + 1] = (next1 << bits) | (next0 >> -bits); - z[i + 2] = (next2 << bits) | (next1 >> -bits); - z[i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - ulong next = z[i]; - z[i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif - } - - public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits64(len, z.AsSpan(zOff, len), bits, c); -#else - Debug.Assert(bits > 0 && bits < 64); - int i = 0, limit4 = len - 4; - while (i <= limit4) - { - ulong next0 = z[zOff + i + 0]; - ulong next1 = z[zOff + i + 1]; - ulong next2 = z[zOff + i + 2]; - ulong next3 = z[zOff + i + 3]; - z[zOff + i + 0] = (next0 << bits) | (c >> -bits); - z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); - z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); - z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); - c = next3; - i += 4; - } - while (i < len) - { - ulong next = z[zOff + i]; - z[zOff + i] = (next << bits) | (c >> -bits); - c = next; - ++i; - } - return c >> -bits; -#endif + } + return c >> 63; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static ulong ShiftUpBits64(int len, Span z, int bits, ulong c) + public static uint ShiftUpBits(int len, Span z, int bits, uint c) { - Debug.Assert(bits > 0 && bits < 64); + Debug.Assert(bits > 0 && bits < 32); int i = 0, limit4 = len - 4; while (i <= limit4) { - ulong next0 = z[i + 0]; - ulong next1 = z[i + 1]; - ulong next2 = z[i + 2]; - ulong next3 = z[i + 3]; + uint next0 = z[i + 0]; + uint next1 = z[i + 1]; + uint next2 = z[i + 2]; + uint next3 = z[i + 3]; z[i + 0] = (next0 << bits) | (c >> -bits); z[i + 1] = (next1 << bits) | (next0 >> -bits); z[i + 2] = (next2 << bits) | (next1 >> -bits); @@ -2181,28 +842,24 @@ public static ulong ShiftUpBits64(int len, Span z, int bits, ulong c) } while (i < len) { - ulong next = z[i]; + uint next = z[i]; z[i] = (next << bits) | (c >> -bits); c = next; ++i; } return c >> -bits; } -#endif - public static ulong ShiftUpBits64(int len, ulong[] x, int bits, ulong c, ulong[] z) + public static uint ShiftUpBits(int len, ReadOnlySpan x, int bits, uint c, Span z) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits64(len, x.AsSpan(0, len), bits, c, z.AsSpan(0, len)); -#else - Debug.Assert(bits > 0 && bits < 64); + Debug.Assert(bits > 0 && bits < 32); int i = 0, limit4 = len - 4; while (i <= limit4) { - ulong next0 = x[i + 0]; - ulong next1 = x[i + 1]; - ulong next2 = x[i + 2]; - ulong next3 = x[i + 3]; + uint next0 = x[i + 0]; + uint next1 = x[i + 1]; + uint next2 = x[i + 2]; + uint next3 = x[i + 3]; z[i + 0] = (next0 << bits) | (c >> -bits); z[i + 1] = (next1 << bits) | (next0 >> -bits); z[i + 2] = (next2 << bits) | (next1 >> -bits); @@ -2212,47 +869,51 @@ public static ulong ShiftUpBits64(int len, ulong[] x, int bits, ulong c, ulong[] } while (i < len) { - ulong next = x[i]; + uint next = x[i]; z[i] = (next << bits) | (c >> -bits); c = next; ++i; } return c >> -bits; -#endif } - public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff) + public static ulong ShiftUpBits64(int len, ulong[] z, int zOff, int bits, ulong c) + { + return ShiftUpBits64(len, z.AsSpan(zOff, len), bits, c); + } + + public static ulong ShiftUpBits64(int len, Span z, int bits, ulong c) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - return ShiftUpBits64(len, x.AsSpan(xOff, len), bits, c, z.AsSpan(zOff, len)); -#else Debug.Assert(bits > 0 && bits < 64); int i = 0, limit4 = len - 4; while (i <= limit4) { - ulong next0 = x[xOff + i + 0]; - ulong next1 = x[xOff + i + 1]; - ulong next2 = x[xOff + i + 2]; - ulong next3 = x[xOff + i + 3]; - z[zOff + i + 0] = (next0 << bits) | (c >> -bits); - z[zOff + i + 1] = (next1 << bits) | (next0 >> -bits); - z[zOff + i + 2] = (next2 << bits) | (next1 >> -bits); - z[zOff + i + 3] = (next3 << bits) | (next2 >> -bits); + ulong next0 = z[i + 0]; + ulong next1 = z[i + 1]; + ulong next2 = z[i + 2]; + ulong next3 = z[i + 3]; + z[i + 0] = (next0 << bits) | (c >> -bits); + z[i + 1] = (next1 << bits) | (next0 >> -bits); + z[i + 2] = (next2 << bits) | (next1 >> -bits); + z[i + 3] = (next3 << bits) | (next2 >> -bits); c = next3; i += 4; } while (i < len) { - ulong next = x[xOff + i]; - z[zOff + i] = (next << bits) | (c >> -bits); + ulong next = z[i]; + z[i] = (next << bits) | (c >> -bits); c = next; ++i; } return c >> -bits; -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static ulong ShiftUpBits64(int len, ulong[] x, int xOff, int bits, ulong c, ulong[] z, int zOff) + { + return ShiftUpBits64(len, x.AsSpan(xOff, len), bits, c, z.AsSpan(zOff, len)); + } + public static ulong ShiftUpBits64(int len, ReadOnlySpan x, int bits, ulong c, Span z) { Debug.Assert(bits > 0 && bits < 64); @@ -2279,71 +940,7 @@ public static ulong ShiftUpBits64(int len, ReadOnlySpan x, int bits, ulon } return c >> -bits; } -#endif - - public static void Square(int len, uint[] x, uint[] zz) - { - int extLen = len << 1; - uint c = 0; - int j = len, k = extLen; - do - { - ulong xVal = (ulong)x[--j]; - ulong p = xVal * xVal; - zz[--k] = (c << 31) | (uint)(p >> 33); - zz[--k] = (uint)(p >> 1); - c = (uint)p; - } - while (j > 0); - - ulong d = 0UL; - int zzPos = 2; - - for (int i = 1; i < len; ++i) - { - d += SquareWordAddTo(x, i, zz); - d += zz[zzPos]; - zz[zzPos++] = (uint)d; d >>= 32; - d += zz[zzPos]; - zz[zzPos++] = (uint)d; d >>= 32; - } - Debug.Assert(0UL == d); - - ShiftUpBit(extLen, zz, x[0] << 31); - } - - public static void Square(int len, uint[] x, int xOff, uint[] zz, int zzOff) - { - int extLen = len << 1; - uint c = 0; - int j = len, k = extLen; - do - { - ulong xVal = (ulong)x[xOff + --j]; - ulong p = xVal * xVal; - zz[zzOff + --k] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --k] = (uint)(p >> 1); - c = (uint)p; - } - while (j > 0); - - ulong d = 0UL; - int zzPos = zzOff + 2; - - for (int i = 1; i < len; ++i) - { - d += SquareWordAddTo(x, xOff, i, zz, zzOff); - d += zz[zzPos]; - zz[zzPos++] = (uint)d; d >>= 32; - d += zz[zzPos]; - zz[zzPos++] = (uint)d; d >>= 32; - } - Debug.Assert(0UL == d); - - ShiftUpBit(extLen, zz, zzOff, x[xOff] << 31); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Square(int len, ReadOnlySpan x, Span zz) { int extLen = len << 1; @@ -2374,38 +971,7 @@ public static void Square(int len, ReadOnlySpan x, Span zz) ShiftUpBit(extLen, zz, x[0] << 31); } -#endif - - public static uint SquareWordAddTo(uint[] x, int xPos, uint[] z) - { - ulong c = 0, xVal = (ulong)x[xPos]; - int i = 0; - do - { - c += xVal * x[i] + z[xPos + i]; - z[xPos + i] = (uint)c; - c >>= 32; - } - while (++i < xPos); - return (uint)c; - } - - public static uint SquareWordAddTo(uint[] x, int xOff, int xPos, uint[] z, int zOff) - { - ulong c = 0, xVal = (ulong)x[xOff + xPos]; - int i = 0; - do - { - c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); - z[xPos + zOff] = (uint)c; - c >>= 32; - ++zOff; - } - while (++i < xPos); - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint SquareWordAddTo(ReadOnlySpan x, int xPos, Span z) { ulong c = 0, xVal = x[xPos]; @@ -2417,184 +983,56 @@ public static uint SquareWordAddTo(ReadOnlySpan x, int xPos, Span z) c >>= 32; } while (++i < xPos); - return (uint)c; - } -#endif - - public static int Sub(int len, uint[] x, uint[] y, uint[] z) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)x[i] - y[i]; - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } - - public static int Sub(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)x[xOff + i] - y[yOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (int)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int Sub(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)x[i] - y[i]; - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } -#endif - - public static int Sub33At(int len, uint x, uint[] z, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - long c = (long)z[zPos + 0] - x; - z[zPos + 0] = (uint)c; - c >>= 32; - c += (long)z[zPos + 1] - 1; - z[zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zPos + 2); - } - - public static int Sub33At(int len, uint x, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - long c = (long)z[zOff + zPos] - x; - z[zOff + zPos] = (uint)c; - c >>= 32; - c += (long)z[zOff + zPos + 1] - 1; - z[zOff + zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int Sub33At(int len, uint x, Span z, int zPos) - { - Debug.Assert(zPos <= (len - 2)); - long c = (long)z[zPos + 0] - x; - z[zPos + 0] = (uint)c; - c >>= 32; - c += (long)z[zPos + 1] - 1; - z[zPos + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zPos + 2); - } -#endif - - public static int Sub33From(int len, uint x, uint[] z) - { - long c = (long)z[0] - x; - z[0] = (uint)c; - c >>= 32; - c += (long)z[1] - 1; - z[1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, 2); - } - - public static int Sub33From(int len, uint x, uint[] z, int zOff) - { - long c = (long)z[zOff + 0] - x; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - 1; - z[zOff + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, 2); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int Sub33From(int len, uint x, Span z) - { - long c = (long)z[0] - x; - z[0] = (uint)c; - c >>= 32; - c += (long)z[1] - 1; - z[1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, 2); - } -#endif - - public static int SubBothFrom(int len, uint[] x, uint[] y, uint[] z) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)z[i] - x[i] - y[i]; - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } - - public static int SubBothFrom(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)z[zOff + i] - x[xOff + i] - y[yOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (int)c; + return (uint)c; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int SubBothFrom(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) + public static int Sub(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; for (int i = 0; i < len; ++i) { - c += (long)z[i] - x[i] - y[i]; + c += (long)x[i] - y[i]; z[i] = (uint)c; c >>= 32; } return (int)c; } -#endif - public static int SubDWordAt(int len, ulong x, uint[] z, int zPos) + public static int Sub33At(int len, uint x, Span z, int zPos) { Debug.Assert(zPos <= (len - 2)); - long c = z[zPos + 0] - (long)(x & M); + long c = (long)z[zPos + 0] - x; z[zPos + 0] = (uint)c; c >>= 32; - c += z[zPos + 1] - (long)(x >> 32); + c += (long)z[zPos + 1] - 1; z[zPos + 1] = (uint)c; c >>= 32; return c == 0 ? 0 : DecAt(len, z, zPos + 2); } - public static int SubDWordAt(int len, ulong x, uint[] z, int zOff, int zPos) + public static int Sub33From(int len, uint x, Span z) { - Debug.Assert(zPos <= (len - 2)); - long c = z[zOff + zPos] - (long)(x & M); - z[zOff + zPos] = (uint)c; + long c = (long)z[0] - x; + z[0] = (uint)c; c >>= 32; - c += z[zOff + zPos + 1] - (long)(x >> 32); - z[zOff + zPos + 1] = (uint)c; + c += (long)z[1] - 1; + z[1] = (uint)c; c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 2); + return c == 0 ? 0 : DecAt(len, z, 2); + } + + public static int SubBothFrom(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (long)z[i] - x[i] - y[i]; + z[i] = (uint)c; + c >>= 32; + } + return (int)c; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubDWordAt(int len, ulong x, Span z, int zPos) { Debug.Assert(zPos <= (len - 2)); @@ -2606,31 +1044,7 @@ public static int SubDWordAt(int len, ulong x, Span z, int zPos) c >>= 32; return c == 0 ? 0 : DecAt(len, z, zPos + 2); } -#endif - - public static int SubDWordFrom(int len, ulong x, uint[] z) - { - long c = z[0] - (long)(x & M); - z[0] = (uint)c; - c >>= 32; - c += z[1] - (long)(x >> 32); - z[1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, 2); - } - - public static int SubDWordFrom(int len, ulong x, uint[] z, int zOff) - { - long c = z[zOff + 0] - (long)(x & M); - z[zOff + 0] = (uint)c; - c >>= 32; - c += z[zOff + 1] - (long)(x >> 32); - z[zOff + 1] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, 2); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubDWordFrom(int len, ulong x, Span z) { long c = z[0] - (long)(x & M); @@ -2641,33 +1055,12 @@ public static int SubDWordFrom(int len, ulong x, Span z) c >>= 32; return c == 0 ? 0 : DecAt(len, z, 2); } -#endif - - public static int SubFrom(int len, uint[] x, uint[] z) - { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)z[i] - x[i]; - z[i] = (uint)c; - c >>= 32; - } - return (int)c; - } public static int SubFrom(int len, uint[] x, int xOff, uint[] z, int zOff) { - long c = 0; - for (int i = 0; i < len; ++i) - { - c += (long)z[zOff + i] - x[xOff + i]; - z[zOff + i] = (uint)c; - c >>= 32; - } - return (int)c; + return SubFrom(len, x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubFrom(int len, ReadOnlySpan x, Span z) { long c = 0; @@ -2679,9 +1072,7 @@ public static int SubFrom(int len, ReadOnlySpan x, Span z) } return (int)c; } -#endif -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubInt32From(int len, int x, Span z) { long c = (long)z[0] - x; @@ -2698,27 +1089,7 @@ public static int SubInt32From(int len, int x, Span z) return (int)c; } -#endif - - public static int SubWordAt(int len, uint x, uint[] z, int zPos) - { - Debug.Assert(zPos <= (len - 1)); - long c = (long)z[zPos] - x; - z[zPos] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zPos + 1); - } - - public static int SubWordAt(int len, uint x, uint[] z, int zOff, int zPos) - { - Debug.Assert(zPos <= (len - 1)); - long c = (long)z[zOff + zPos] - x; - z[zOff + zPos] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, zPos + 1); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubWordAt(int len, uint x, Span z, int zPos) { Debug.Assert(zPos <= (len - 1)); @@ -2727,25 +1098,7 @@ public static int SubWordAt(int len, uint x, Span z, int zPos) c >>= 32; return c == 0 ? 0 : DecAt(len, z, zPos + 1); } -#endif - - public static int SubWordFrom(int len, uint x, uint[] z) - { - long c = (long)z[0] - x; - z[0] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, 1); - } - - public static int SubWordFrom(int len, uint x, uint[] z, int zOff) - { - long c = (long)z[zOff + 0] - x; - z[zOff + 0] = (uint)c; - c >>= 32; - return c == 0 ? 0 : DecAt(len, z, zOff, 1); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubWordFrom(int len, uint x, Span z) { long c = (long)z[0] - x; @@ -2753,7 +1106,6 @@ public static int SubWordFrom(int len, uint x, Span z) c >>= 32; return c == 0 ? 0 : DecAt(len, z, 1); } -#endif public static BigInteger ToBigInteger(int len, uint[] x) { @@ -2788,31 +1140,11 @@ public static BigInteger ToBigInteger(int len, ReadOnlySpan x) } #endif - public static void Xor(int len, uint[] x, uint[] y, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] = x[i] ^ y[i]; - } -#endif - } - public static void Xor(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER Xor(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] = x[xOff + i] ^ y[yOff + i]; - } -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { int i = 0, limit16 = len - 16; @@ -2827,36 +1159,16 @@ public static void Xor(int len, ReadOnlySpan x, ReadOnlySpan y, Span ++i; } } -#endif - - public static void Xor64(int len, ulong[] x, ulong y, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor64(len, x.AsSpan(0, len), y, z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] = x[i] ^ y; - } -#endif - } public static void Xor64(int len, ulong[] x, int xOff, ulong y, ulong[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER Xor64(len, x.AsSpan(xOff, len), y, z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] = x[xOff + i] ^ y; - } -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor64(int len, ReadOnlySpan x, ulong y, Span z) { int i = 0; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER if (Vector.IsHardwareAccelerated) { var vy = new Vector(y); @@ -2870,6 +1182,7 @@ public static void Xor64(int len, ReadOnlySpan x, ulong y, Span z) } } else +#endif { int limit = len - 4; while (i <= limit) @@ -2887,33 +1200,12 @@ public static void Xor64(int len, ReadOnlySpan x, ulong y, Span z) ++i; } } -#endif - - public static void Xor64(int len, ulong[] x, ulong[] y, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor64(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] = x[i] ^ y[i]; - } -#endif - } public static void Xor64(int len, ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER Xor64(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] = x[xOff + i] ^ y[yOff + i]; - } -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor64(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { int i = 0, limit8 = len - 8; @@ -2928,33 +1220,6 @@ public static void Xor64(int len, ReadOnlySpan x, ReadOnlySpan y, ++i; } } -#endif - - public static void XorBothTo(int len, uint[] x, uint[] y, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorBothTo(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] ^= x[i] ^ y[i]; - } -#endif - } - - public static void XorBothTo(int len, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorBothTo(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] ^= x[xOff + i] ^ y[yOff + i]; - } -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void XorBothTo(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { int i = 0, limit16 = len - 16; @@ -2969,33 +1234,7 @@ public static void XorBothTo(int len, ReadOnlySpan x, ReadOnlySpan y ++i; } } -#endif - - public static void XorBothTo64(int len, ulong[] x, ulong[] y, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorBothTo64(len, x.AsSpan(0, len), y.AsSpan(0, len), z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] ^= x[i] ^ y[i]; - } -#endif - } - - public static void XorBothTo64(int len, ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorBothTo64(len, x.AsSpan(xOff, len), y.AsSpan(yOff, len), z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] ^= x[xOff + i] ^ y[yOff + i]; - } -#endif - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void XorBothTo64(int len, ReadOnlySpan x, ReadOnlySpan y, Span z) { int i = 0, limit8 = len - 8; @@ -3010,33 +1249,12 @@ public static void XorBothTo64(int len, ReadOnlySpan x, ReadOnlySpan x, Span z) { int i = 0, limit16 = len - 16; @@ -3051,33 +1269,12 @@ public static void XorTo(int len, ReadOnlySpan x, Span z) ++i; } } -#endif - - public static void XorTo64(int len, ulong[] x, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorTo64(len, x.AsSpan(0, len), z.AsSpan(0, len)); -#else - for (int i = 0; i < len; ++i) - { - z[i] ^= x[i]; - } -#endif - } public static void XorTo64(int len, ulong[] x, int xOff, ulong[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER XorTo64(len, x.AsSpan(xOff, len), z.AsSpan(zOff, len)); -#else - for (int i = 0; i < len; ++i) - { - z[zOff + i] ^= x[xOff + i]; - } -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void XorTo64(int len, ReadOnlySpan x, Span z) { int i = 0, limit8 = len - 8; @@ -3092,44 +1289,15 @@ public static void XorTo64(int len, ReadOnlySpan x, Span z) ++i; } } -#endif - - public static void Zero(int len, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - z.AsSpan(0, len).Fill(0U); -#else - for (int i = 0; i < len; ++i) - { - z[i] = 0U; - } -#endif - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Zero(int len, Span z) { z[..len].Fill(0U); } -#endif - - public static void Zero64(int len, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - z.AsSpan(0, len).Fill(0UL); -#else - for (int i = 0; i < len; ++i) - { - z[i] = 0UL; - } -#endif - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Zero64(int len, Span z) { z[..len].Fill(0UL); } -#endif } } diff --git a/crypto/src/math/raw/Nat128.cs b/crypto/src/math/raw/Nat128.cs index d0cdc9985d..421922800c 100644 --- a/crypto/src/math/raw/Nat128.cs +++ b/crypto/src/math/raw/Nat128.cs @@ -9,7 +9,7 @@ internal static class Nat128 { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(uint[] x, uint[] y, uint[] z) + public static uint Add(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0]; @@ -27,7 +27,7 @@ public static uint Add(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + public static uint AddBothTo(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0] + z[0]; @@ -45,7 +45,7 @@ public static uint AddBothTo(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddTo(uint[] x, uint[] z) + public static uint AddTo(ReadOnlySpan x, Span z) { ulong c = 0; c += (ulong)x[0] + z[0]; @@ -63,24 +63,6 @@ public static uint AddTo(uint[] x, uint[] z) return (uint)c; } - public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) - { - ulong c = cIn; - c += (ulong)x[xOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - return (uint)c; - } - public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) { ulong c = 0; @@ -103,7 +85,7 @@ public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) return (uint)c; } - public static void Copy(uint[] x, uint[] z) + public static void Copy(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; @@ -113,31 +95,19 @@ public static void Copy(uint[] x, uint[] z) public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - } - - public static void Copy64(ulong[] x, ulong[] z) - { - z[0] = x[0]; - z[1] = x[1]; + Copy(x.AsSpan(xOff), z.AsSpan(zOff)); } public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; } -#endif public static uint[] Create() { @@ -159,16 +129,16 @@ public static ulong[] CreateExt64() return new ulong[4]; } - public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z) { - bool pos = Gte(x, xOff, y, yOff); + bool pos = Gte(x, y); if (pos) { - Sub(x, xOff, y, yOff, z, zOff); + Sub(x, y, z); } else { - Sub(y, yOff, x, xOff, z, zOff); + Sub(y, x, z); } return pos; } @@ -208,7 +178,7 @@ public static uint GetBit(uint[] x, int bit) return (x[w] >> b) & 1; } - public static bool Gte(uint[] x, uint[] y) + public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) { for (int i = 3; i >= 0; --i) { @@ -221,19 +191,6 @@ public static bool Gte(uint[] x, uint[] y) return true; } - public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) - { - for (int i = 3; i >= 0; --i) - { - uint x_i = x[xOff + i], y_i = y[yOff + i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - public static bool IsOne(uint[] x) { if (x[0] != 1) @@ -278,11 +235,7 @@ public static bool IsZero(uint[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 2; ++i) { @@ -294,7 +247,7 @@ public static bool IsZero64(ulong[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) + public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -337,51 +290,7 @@ public static void Mul(uint[] x, uint[] y, uint[] zz) } } - public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - - { - ulong c = 0, x_0 = x[xOff + 0]; - c += x_0 * y_0; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[zzOff + 3] = (uint)c; - c >>= 32; - zz[zzOff + 4] = (uint)c; - } - - for (int i = 1; i < 4; ++i) - { - ++zzOff; - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - zz[zzOff + 4] = (uint)c; - } - } - - public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + public static uint MulAddTo(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -412,38 +321,6 @@ public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) return (uint)zc; } - public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - - ulong zc = 0; - for (int i = 0; i < 4; ++i) - { - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - - zc += c + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } - public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { Debug.Assert(w >> 31 == 0); @@ -526,7 +403,7 @@ public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(4, z.AsSpan(zOff), 3); } public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) @@ -542,7 +419,7 @@ public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(4, z.AsSpan(zOff), 3); } public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) @@ -556,7 +433,7 @@ public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 1]; z[zOff + 1] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(4, z, zOff, 2); + return c == 0 ? 0 : Nat.IncAt(4, z.AsSpan(zOff), 2); } public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) @@ -573,7 +450,7 @@ public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) return (uint)c; } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { ulong x_0 = x[0]; ulong zz_1; @@ -649,83 +526,7 @@ public static void Square(uint[] x, uint[] zz) zz[7] = (w << 1) | c; } - public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) - { - ulong x_0 = x[xOff + 0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 3, j = 8; - do - { - ulong xVal = x[xOff + i--]; - ulong p = xVal * xVal; - zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[zzOff + 0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[xOff + 1]; - ulong zz_2 = zz[zzOff + 2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[zzOff + 1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[xOff + 2]; - ulong zz_3 = zz[zzOff + 3]; - ulong zz_4 = zz[zzOff + 4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[zzOff + 2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[xOff + 3]; - ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[zzOff + 3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_6 += zz_5 >> 32; - } - - w = (uint)zz_4; - zz[zzOff + 4] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_5; - zz[zzOff + 5] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_6; - zz[zzOff + 6] = (w << 1) | c; - c = w >> 31; - w = zz[zzOff + 7] + (uint)(zz_6 >> 32); - zz[zzOff + 7] = (w << 1) | c; - } - - public static int Sub(uint[] x, uint[] y, uint[] z) + public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)x[0] - y[0]; @@ -743,25 +544,7 @@ public static int Sub(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - c += (long)x[xOff + 0] - y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)x[xOff + 1] - y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)x[xOff + 2] - y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)x[xOff + 3] - y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - return (int)c; - } - - public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + public static int SubBothFrom(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)z[0] - x[0] - y[0]; @@ -779,7 +562,7 @@ public static int SubBothFrom(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, uint[] z) + public static int SubFrom(ReadOnlySpan x, Span z) { long c = 0; c += (long)z[0] - x[0]; @@ -797,24 +580,6 @@ public static int SubFrom(uint[] x, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) - { - long c = 0; - c += (long)z[zOff + 0] - x[xOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - x[xOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)z[zOff + 2] - x[xOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)z[zOff + 3] - x[xOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - return (int)c; - } - public static BigInteger ToBigInteger(uint[] x) { byte[] bs = new byte[16]; diff --git a/crypto/src/math/raw/Nat160.cs b/crypto/src/math/raw/Nat160.cs index 85e4aba583..d5dddd0fd7 100644 --- a/crypto/src/math/raw/Nat160.cs +++ b/crypto/src/math/raw/Nat160.cs @@ -9,7 +9,7 @@ internal static class Nat160 { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(uint[] x, uint[] y, uint[] z) + public static uint Add(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0]; @@ -30,7 +30,7 @@ public static uint Add(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + public static uint AddBothTo(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0] + z[0]; @@ -51,7 +51,7 @@ public static uint AddBothTo(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddTo(uint[] x, uint[] z) + public static uint AddTo(ReadOnlySpan x, Span z) { ulong c = 0; c += (ulong)x[0] + z[0]; @@ -120,7 +120,7 @@ public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) return (uint)c; } - public static void Copy(uint[] x, uint[] z) + public static void Copy(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; @@ -131,11 +131,7 @@ public static void Copy(uint[] x, uint[] z) public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; + Copy(x.AsSpan(xOff), z.AsSpan(zOff)); } public static uint[] Create() @@ -148,16 +144,16 @@ public static uint[] CreateExt() return new uint[10]; } - public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z) { - bool pos = Gte(x, xOff, y, yOff); + bool pos = Gte(x, y); if (pos) { - Sub(x, xOff, y, yOff, z, zOff); + Sub(x, y, z); } else { - Sub(y, yOff, x, xOff, z, zOff); + Sub(y, x, z); } return pos; } @@ -187,7 +183,7 @@ public static uint GetBit(uint[] x, int bit) return (x[w] >> b) & 1; } - public static bool Gte(uint[] x, uint[] y) + public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) { for (int i = 4; i >= 0; --i) { @@ -200,19 +196,6 @@ public static bool Gte(uint[] x, uint[] y) return true; } - public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) - { - for (int i = 4; i >= 0; --i) - { - uint x_i = x[xOff + i], y_i = y[yOff + i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - public static bool IsOne(uint[] x) { if (x[0] != 1) @@ -241,7 +224,7 @@ public static bool IsZero(uint[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) + public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -291,58 +274,7 @@ public static void Mul(uint[] x, uint[] y, uint[] zz) } } - public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - - { - ulong c = 0, x_0 = x[xOff + 0]; - c += x_0 * y_0; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[zzOff + 4] = (uint)c; - c >>= 32; - zz[zzOff + 5] = (uint)c; - } - - for (int i = 1; i < 5; ++i) - { - ++zzOff; - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - zz[zzOff + 5] = (uint)c; - } - } - - public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + public static uint MulAddTo(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -377,42 +309,6 @@ public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) return (uint)zc; } - public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - - ulong zc = 0; - for (int i = 0; i < 5; ++i) - { - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - - zc += c + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } - public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { Debug.Assert(w >> 31 == 0); @@ -485,7 +381,7 @@ public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 3]; z[zOff + 3] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 4); + return c == 0 ? 0 : Nat.IncAt(5, z.AsSpan(zOff), 4); } public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) @@ -502,7 +398,7 @@ public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(5, z.AsSpan(zOff), 3); } public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) @@ -518,7 +414,7 @@ public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(5, z.AsSpan(zOff), 3); } public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) @@ -532,7 +428,7 @@ public static uint MulWordsAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 1]; z[zOff + 1] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(5, z, zOff, 2); + return c == 0 ? 0 : Nat.IncAt(5, z.AsSpan(zOff), 2); } public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) @@ -549,7 +445,7 @@ public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) return (uint)c; } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { ulong x_0 = x[0]; ulong zz_1; @@ -644,102 +540,7 @@ public static void Square(uint[] x, uint[] zz) zz[9] = (w << 1) | c; } - public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) - { - ulong x_0 = x[xOff + 0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 4, j = 10; - do - { - ulong xVal = x[xOff + i--]; - ulong p = xVal * xVal; - zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[zzOff + 0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[xOff + 1]; - ulong zz_2 = zz[zzOff + 2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[zzOff + 1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[xOff + 2]; - ulong zz_3 = zz[zzOff + 3]; - ulong zz_4 = zz[zzOff + 4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[zzOff + 2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[xOff + 3]; - ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[zzOff + 3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[xOff + 4]; - ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[zzOff + 4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_8 += zz_7 >> 32; - } - - w = (uint)zz_5; - zz[zzOff + 5] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_6; - zz[zzOff + 6] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_7; - zz[zzOff + 7] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_8; - zz[zzOff + 8] = (w << 1) | c; - c = w >> 31; - w = zz[zzOff + 9] + (uint)(zz_8 >> 32); - zz[zzOff + 9] = (w << 1) | c; - } - - public static int Sub(uint[] x, uint[] y, uint[] z) + public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)x[0] - y[0]; @@ -760,28 +561,7 @@ public static int Sub(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - c += (long)x[xOff + 0] - y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)x[xOff + 1] - y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)x[xOff + 2] - y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)x[xOff + 3] - y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)x[xOff + 4] - y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - return (int)c; - } - - public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + public static int SubBothFrom(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)z[0] - x[0] - y[0]; @@ -802,7 +582,7 @@ public static int SubBothFrom(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, uint[] z) + public static int SubFrom(ReadOnlySpan x, Span z) { long c = 0; c += (long)z[0] - x[0]; @@ -823,27 +603,6 @@ public static int SubFrom(uint[] x, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) - { - long c = 0; - c += (long)z[zOff + 0] - x[xOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - x[xOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)z[zOff + 2] - x[xOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)z[zOff + 3] - x[xOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)z[zOff + 4] - x[xOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - return (int)c; - } - public static BigInteger ToBigInteger(uint[] x) { byte[] bs = new byte[20]; diff --git a/crypto/src/math/raw/Nat192.cs b/crypto/src/math/raw/Nat192.cs index 1980a47c66..a4d3a97a41 100644 --- a/crypto/src/math/raw/Nat192.cs +++ b/crypto/src/math/raw/Nat192.cs @@ -9,7 +9,7 @@ internal static class Nat192 { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(uint[] x, uint[] y, uint[] z) + public static uint Add(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0]; @@ -33,7 +33,7 @@ public static uint Add(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + public static uint AddBothTo(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0] + z[0]; @@ -57,7 +57,7 @@ public static uint AddBothTo(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddTo(uint[] x, uint[] z) + public static uint AddTo(ReadOnlySpan x, Span z) { ulong c = 0; c += (ulong)x[0] + z[0]; @@ -81,61 +81,61 @@ public static uint AddTo(uint[] x, uint[] z) return (uint)c; } - public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) + public static uint AddTo(ReadOnlySpan x, Span z, uint cIn) { ulong c = cIn; - c += (ulong)x[xOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; + c += (ulong)x[0] + z[0]; + z[0] = (uint)c; c >>= 32; - c += (ulong)x[xOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; + c += (ulong)x[1] + z[1]; + z[1] = (uint)c; c >>= 32; - c += (ulong)x[xOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; + c += (ulong)x[2] + z[2]; + z[2] = (uint)c; c >>= 32; - c += (ulong)x[xOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; + c += (ulong)x[3] + z[3]; + z[3] = (uint)c; c >>= 32; - c += (ulong)x[xOff + 4] + z[zOff + 4]; - z[zOff + 4] = (uint)c; + c += (ulong)x[4] + z[4]; + z[4] = (uint)c; c >>= 32; - c += (ulong)x[xOff + 5] + z[zOff + 5]; - z[zOff + 5] = (uint)c; + c += (ulong)x[5] + z[5]; + z[5] = (uint)c; c >>= 32; return (uint)c; } - public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + public static uint AddToEachOther(Span u, Span v) { ulong c = 0; - c += (ulong)u[uOff + 0] + v[vOff + 0]; - u[uOff + 0] = (uint)c; - v[vOff + 0] = (uint)c; + c += (ulong)u[0] + v[0]; + u[0] = (uint)c; + v[0] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 1] + v[vOff + 1]; - u[uOff + 1] = (uint)c; - v[vOff + 1] = (uint)c; + c += (ulong)u[1] + v[1]; + u[1] = (uint)c; + v[1] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 2] + v[vOff + 2]; - u[uOff + 2] = (uint)c; - v[vOff + 2] = (uint)c; + c += (ulong)u[2] + v[2]; + u[2] = (uint)c; + v[2] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 3] + v[vOff + 3]; - u[uOff + 3] = (uint)c; - v[vOff + 3] = (uint)c; + c += (ulong)u[3] + v[3]; + u[3] = (uint)c; + v[3] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 4] + v[vOff + 4]; - u[uOff + 4] = (uint)c; - v[vOff + 4] = (uint)c; + c += (ulong)u[4] + v[4]; + u[4] = (uint)c; + v[4] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 5] + v[vOff + 5]; - u[uOff + 5] = (uint)c; - v[vOff + 5] = (uint)c; + c += (ulong)u[5] + v[5]; + u[5] = (uint)c; + v[5] = (uint)c; c >>= 32; return (uint)c; } - public static void Copy(uint[] x, uint[] z) + public static void Copy(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; @@ -147,36 +147,20 @@ public static void Copy(uint[] x, uint[] z) public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; - z[zOff + 5] = x[xOff + 5]; - } - - public static void Copy64(ulong[] x, ulong[] z) - { - z[0] = x[0]; - z[1] = x[1]; - z[2] = x[2]; + Copy(x.AsSpan(xOff), z.AsSpan(zOff)); } public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; z[2] = x[2]; } -#endif public static uint[] Create() { @@ -198,16 +182,16 @@ public static ulong[] CreateExt64() return new ulong[6]; } - public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z) { - bool pos = Gte(x, xOff, y, yOff); + bool pos = Gte(x, y); if (pos) { - Sub(x, xOff, y, yOff, z, zOff); + Sub(x, y, z); } else { - Sub(y, yOff, x, xOff, z, zOff); + Sub(y, x, z); } return pos; } @@ -249,7 +233,7 @@ public static uint GetBit(uint[] x, int bit) return (x[w] >> b) & 1; } - public static bool Gte(uint[] x, uint[] y) + public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) { for (int i = 5; i >= 0; --i) { @@ -262,19 +246,6 @@ public static bool Gte(uint[] x, uint[] y) return true; } - public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) - { - for (int i = 5; i >= 0; --i) - { - uint x_i = x[xOff + i], y_i = y[yOff + i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - public static bool IsOne(uint[] x) { if (x[0] != 1) @@ -319,11 +290,7 @@ public static bool IsZero(uint[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 3; ++i) { @@ -335,7 +302,7 @@ public static bool IsZero64(ulong[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) + public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -392,65 +359,7 @@ public static void Mul(uint[] x, uint[] y, uint[] zz) } } - public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - - { - ulong c = 0, x_0 = x[xOff + 0]; - c += x_0 * y_0; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_0 * y_5; - zz[zzOff + 5] = (uint)c; - c >>= 32; - zz[zzOff + 6] = (uint)c; - } - - for (int i = 1; i < 6; ++i) - { - ++zzOff; - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - zz[zzOff + 6] = (uint)c; - } - } - - public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + public static uint MulAddTo(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -489,46 +398,6 @@ public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) return (uint)zc; } - public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - - ulong zc = 0; - for (int i = 0; i < 6; ++i) - { - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - - zc += c + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } - public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { Debug.Assert(w >> 31 == 0); @@ -607,7 +476,7 @@ public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 3]; z[zOff + 3] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 4); + return c == 0 ? 0 : Nat.IncAt(6, z.AsSpan(zOff), 4); } public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) @@ -624,7 +493,7 @@ public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(6, z.AsSpan(zOff), 3); } public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) @@ -640,7 +509,7 @@ public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(6, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(6, z.AsSpan(zOff), 3); } public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) @@ -657,7 +526,7 @@ public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) return (uint)c; } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { ulong x_0 = x[0]; ulong zz_1; @@ -773,123 +642,7 @@ public static void Square(uint[] x, uint[] zz) zz[11] = (w << 1) | c; } - public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) - { - ulong x_0 = x[xOff + 0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 5, j = 12; - do - { - ulong xVal = x[xOff + i--]; - ulong p = xVal * xVal; - zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[zzOff + 0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[xOff + 1]; - ulong zz_2 = zz[zzOff + 2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[zzOff + 1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[xOff + 2]; - ulong zz_3 = zz[zzOff + 3]; - ulong zz_4 = zz[zzOff + 4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[zzOff + 2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[xOff + 3]; - ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[zzOff + 3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[xOff + 4]; - ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[zzOff + 4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_5 &= M; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_6 &= M; - zz_8 += zz_7 >> 32; - zz_7 &= M; - } - - ulong x_5 = x[xOff + 5]; - ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; - ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; - { - zz_5 += x_5 * x_0; - w = (uint)zz_5; - zz[zzOff + 5] = (w << 1) | c; - c = w >> 31; - zz_6 += (zz_5 >> 32) + x_5 * x_1; - zz_7 += (zz_6 >> 32) + x_5 * x_2; - zz_8 += (zz_7 >> 32) + x_5 * x_3; - zz_9 += (zz_8 >> 32) + x_5 * x_4; - zz_10 += zz_9 >> 32; - } - - w = (uint)zz_6; - zz[zzOff + 6] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_7; - zz[zzOff + 7] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_8; - zz[zzOff + 8] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_9; - zz[zzOff + 9] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_10; - zz[zzOff + 10] = (w << 1) | c; - c = w >> 31; - w = zz[zzOff + 11] + (uint)(zz_10 >> 32); - zz[zzOff + 11] = (w << 1) | c; - } - - public static int Sub(uint[] x, uint[] y, uint[] z) + public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)x[0] - y[0]; @@ -913,31 +666,7 @@ public static int Sub(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - c += (long)x[xOff + 0] - y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)x[xOff + 1] - y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)x[xOff + 2] - y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)x[xOff + 3] - y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)x[xOff + 4] - y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)x[xOff + 5] - y[yOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - return (int)c; - } - - public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + public static int SubBothFrom(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)z[0] - x[0] - y[0]; @@ -961,7 +690,7 @@ public static int SubBothFrom(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, uint[] z) + public static int SubFrom(ReadOnlySpan x, Span z) { long c = 0; c += (long)z[0] - x[0]; @@ -985,30 +714,6 @@ public static int SubFrom(uint[] x, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) - { - long c = 0; - c += (long)z[zOff + 0] - x[xOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - x[xOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)z[zOff + 2] - x[xOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)z[zOff + 3] - x[xOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)z[zOff + 4] - x[xOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)z[zOff + 5] - x[xOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - return (int)c; - } - public static BigInteger ToBigInteger(uint[] x) { byte[] bs = new byte[24]; diff --git a/crypto/src/math/raw/Nat224.cs b/crypto/src/math/raw/Nat224.cs index 2182261aec..bf50e6409b 100644 --- a/crypto/src/math/raw/Nat224.cs +++ b/crypto/src/math/raw/Nat224.cs @@ -9,7 +9,7 @@ internal static class Nat224 { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(uint[] x, uint[] y, uint[] z) + public static uint Add(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0]; @@ -36,34 +36,7 @@ public static uint Add(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0; - c += (ulong)x[xOff + 0] + y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + y[yOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + y[yOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - return (uint)c; - } - - public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + public static uint AddBothTo(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0] + z[0]; @@ -90,88 +63,6 @@ public static uint AddBothTo(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0; - c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - return (uint)c; - } - - public static uint AddTo(uint[] x, uint[] z, uint cIn) - { - ulong c = cIn; - c += (ulong)x[0] + z[0]; - z[0] = (uint)c; - c >>= 32; - c += (ulong)x[1] + z[1]; - z[1] = (uint)c; - c >>= 32; - c += (ulong)x[2] + z[2]; - z[2] = (uint)c; - c >>= 32; - c += (ulong)x[3] + z[3]; - z[3] = (uint)c; - c >>= 32; - c += (ulong)x[4] + z[4]; - z[4] = (uint)c; - c >>= 32; - c += (ulong)x[5] + z[5]; - z[5] = (uint)c; - c >>= 32; - c += (ulong)x[6] + z[6]; - z[6] = (uint)c; - c >>= 32; - return (uint)c; - } - - public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) - { - ulong c = cIn; - c += (ulong)x[xOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + z[zOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + z[zOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + z[zOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - return (uint)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddTo(ReadOnlySpan x, Span z, uint cIn) { ulong c = cIn; @@ -198,43 +89,7 @@ public static uint AddTo(ReadOnlySpan x, Span z, uint cIn) c >>= 32; return (uint)c; } -#endif - - public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) - { - ulong c = 0; - c += (ulong)u[uOff + 0] + v[vOff + 0]; - u[uOff + 0] = (uint)c; - v[vOff + 0] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 1] + v[vOff + 1]; - u[uOff + 1] = (uint)c; - v[vOff + 1] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 2] + v[vOff + 2]; - u[uOff + 2] = (uint)c; - v[vOff + 2] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 3] + v[vOff + 3]; - u[uOff + 3] = (uint)c; - v[vOff + 3] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 4] + v[vOff + 4]; - u[uOff + 4] = (uint)c; - v[vOff + 4] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 5] + v[vOff + 5]; - u[uOff + 5] = (uint)c; - v[vOff + 5] = (uint)c; - c >>= 32; - c += (ulong)u[uOff + 6] + v[vOff + 6]; - u[uOff + 6] = (uint)c; - v[vOff + 6] = (uint)c; - c >>= 32; - return (uint)c; - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddToEachOther(Span u, Span v) { ulong c = 0; @@ -268,9 +123,8 @@ public static uint AddToEachOther(Span u, Span v) c >>= 32; return (uint)c; } -#endif - public static void Copy(uint[] x, uint[] z) + public static void Copy(ReadOnlySpan x, Span z) { z[0] = x[0]; z[1] = x[1]; @@ -283,13 +137,7 @@ public static void Copy(uint[] x, uint[] z) public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; - z[zOff + 5] = x[xOff + 5]; - z[zOff + 6] = x[xOff + 6]; + Copy(x.AsSpan(xOff), z.AsSpan(zOff)); } public static uint[] Create() @@ -302,21 +150,6 @@ public static uint[] CreateExt() return new uint[14]; } - public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - bool pos = Gte(x, xOff, y, yOff); - if (pos) - { - Sub(x, xOff, y, yOff, z, zOff); - } - else - { - Sub(y, yOff, x, xOff, z, zOff); - } - return pos; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z) { bool pos = Gte(x, y); @@ -330,7 +163,6 @@ public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z } return pos; } -#endif public static bool Eq(uint[] x, uint[] y) { @@ -357,33 +189,6 @@ public static uint GetBit(uint[] x, int bit) return (x[w] >> b) & 1; } - public static bool Gte(uint[] x, uint[] y) - { - for (int i = 6; i >= 0; --i) - { - uint x_i = x[i], y_i = y[i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - - public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) - { - for (int i = 6; i >= 0; --i) - { - uint x_i = x[xOff + i], y_i = y[yOff + i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) { for (int i = 6; i >= 0; --i) @@ -396,7 +201,6 @@ public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) } return true; } -#endif public static bool IsOne(uint[] x) { @@ -426,136 +230,6 @@ public static bool IsZero(uint[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) - { - ulong y_0 = y[0]; - ulong y_1 = y[1]; - ulong y_2 = y[2]; - ulong y_3 = y[3]; - ulong y_4 = y[4]; - ulong y_5 = y[5]; - ulong y_6 = y[6]; - - { - ulong c = 0, x_0 = x[0]; - c += x_0 * y_0; - zz[0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[4] = (uint)c; - c >>= 32; - c += x_0 * y_5; - zz[5] = (uint)c; - c >>= 32; - c += x_0 * y_6; - zz[6] = (uint)c; - c >>= 32; - zz[7] = (uint)c; - } - - for (int i = 1; i < 7; ++i) - { - ulong c = 0, x_i = x[i]; - c += x_i * y_0 + zz[i + 0]; - zz[i + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[i + 1]; - zz[i + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[i + 2]; - zz[i + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[i + 3]; - zz[i + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[i + 4]; - zz[i + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[i + 5]; - zz[i + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[i + 6]; - zz[i + 6] = (uint)c; - c >>= 32; - zz[i + 7] = (uint)c; - } - } - - public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - ulong y_6 = y[yOff + 6]; - - { - ulong c = 0, x_0 = x[xOff + 0]; - c += x_0 * y_0; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_0 * y_5; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_0 * y_6; - zz[zzOff + 6] = (uint)c; - c >>= 32; - zz[zzOff + 7] = (uint)c; - } - - for (int i = 1; i < 7; ++i) - { - ++zzOff; - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)c; - c >>= 32; - zz[zzOff + 7] = (uint)c; - } - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; @@ -619,9 +293,8 @@ public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz zz[i + 7] = (uint)c; } } -#endif - public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) + public static uint MulAddTo(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; ulong y_1 = y[1]; @@ -664,50 +337,6 @@ public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) return (uint)zc; } - public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - ulong y_6 = y[yOff + 6]; - - ulong zc = 0; - for (int i = 0; i < 7; ++i) - { - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)c; - c >>= 32; - - zc += c + zz[zzOff + 7]; - zz[zzOff + 7] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } - public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { Debug.Assert(w >> 31 == 0); @@ -845,7 +474,7 @@ public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 3]; z[zOff + 3] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 4); + return c == 0 ? 0 : Nat.IncAt(7, z.AsSpan(zOff), 4); } public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) @@ -862,7 +491,7 @@ public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(7, z.AsSpan(zOff), 3); } public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) @@ -878,7 +507,7 @@ public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(7, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(7, z.AsSpan(zOff), 3); } public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) @@ -895,7 +524,7 @@ public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) return (uint)c; } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { ulong x_0 = x[0]; ulong zz_1; @@ -1034,287 +663,7 @@ public static void Square(uint[] x, uint[] zz) zz[13] = (w << 1) | c; } - public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) - { - ulong x_0 = x[xOff + 0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 6, j = 14; - do - { - ulong xVal = x[xOff + i--]; - ulong p = xVal * xVal; - zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[zzOff + 0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[xOff + 1]; - ulong zz_2 = zz[zzOff + 2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[zzOff + 1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[xOff + 2]; - ulong zz_3 = zz[zzOff + 3]; - ulong zz_4 = zz[zzOff + 4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[zzOff + 2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[xOff + 3]; - ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[zzOff + 3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[xOff + 4]; - ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[zzOff + 4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_5 &= M; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_6 &= M; - zz_8 += zz_7 >> 32; - zz_7 &= M; - } - - ulong x_5 = x[xOff + 5]; - ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; - ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; - { - zz_5 += x_5 * x_0; - w = (uint)zz_5; - zz[zzOff + 5] = (w << 1) | c; - c = w >> 31; - zz_6 += (zz_5 >> 32) + x_5 * x_1; - zz_7 += (zz_6 >> 32) + x_5 * x_2; - zz_6 &= M; - zz_8 += (zz_7 >> 32) + x_5 * x_3; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_5 * x_4; - zz_8 &= M; - zz_10 += zz_9 >> 32; - zz_9 &= M; - } - - ulong x_6 = x[xOff + 6]; - ulong zz_11 = zz[zzOff + 11] + (zz_10 >> 32); zz_10 &= M; - ulong zz_12 = zz[zzOff + 12] + (zz_11 >> 32); zz_11 &= M; - { - zz_6 += x_6 * x_0; - w = (uint)zz_6; - zz[zzOff + 6] = (w << 1) | c; - c = w >> 31; - zz_7 += (zz_6 >> 32) + x_6 * x_1; - zz_8 += (zz_7 >> 32) + x_6 * x_2; - zz_9 += (zz_8 >> 32) + x_6 * x_3; - zz_10 += (zz_9 >> 32) + x_6 * x_4; - zz_11 += (zz_10 >> 32) + x_6 * x_5; - zz_12 += zz_11 >> 32; - } - - w = (uint)zz_7; - zz[zzOff + 7] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_8; - zz[zzOff + 8] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_9; - zz[zzOff + 9] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_10; - zz[zzOff + 10] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_11; - zz[zzOff + 11] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_12; - zz[zzOff + 12] = (w << 1) | c; - c = w >> 31; - w = zz[zzOff + 13] + (uint)(zz_12 >> 32); - zz[zzOff + 13] = (w << 1) | c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Square(ReadOnlySpan x, Span zz) - { - ulong x_0 = x[0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 6, j = 14; - do - { - ulong xVal = x[i--]; - ulong p = xVal * xVal; - zz[--j] = (c << 31) | (uint)(p >> 33); - zz[--j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[1]; - ulong zz_2 = zz[2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[2]; - ulong zz_3 = zz[3]; - ulong zz_4 = zz[4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[3]; - ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[4]; - ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_5 &= M; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_6 &= M; - zz_8 += zz_7 >> 32; - zz_7 &= M; - } - - ulong x_5 = x[5]; - ulong zz_9 = zz[9] + (zz_8 >> 32); zz_8 &= M; - ulong zz_10 = zz[10] + (zz_9 >> 32); zz_9 &= M; - { - zz_5 += x_5 * x_0; - w = (uint)zz_5; - zz[5] = (w << 1) | c; - c = w >> 31; - zz_6 += (zz_5 >> 32) + x_5 * x_1; - zz_7 += (zz_6 >> 32) + x_5 * x_2; - zz_6 &= M; - zz_8 += (zz_7 >> 32) + x_5 * x_3; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_5 * x_4; - zz_8 &= M; - zz_10 += zz_9 >> 32; - zz_9 &= M; - } - - ulong x_6 = x[6]; - ulong zz_11 = zz[11] + (zz_10 >> 32); zz_10 &= M; - ulong zz_12 = zz[12] + (zz_11 >> 32); zz_11 &= M; - { - zz_6 += x_6 * x_0; - w = (uint)zz_6; - zz[6] = (w << 1) | c; - c = w >> 31; - zz_7 += (zz_6 >> 32) + x_6 * x_1; - zz_8 += (zz_7 >> 32) + x_6 * x_2; - zz_9 += (zz_8 >> 32) + x_6 * x_3; - zz_10 += (zz_9 >> 32) + x_6 * x_4; - zz_11 += (zz_10 >> 32) + x_6 * x_5; - zz_12 += zz_11 >> 32; - } - - w = (uint)zz_7; - zz[7] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_8; - zz[8] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_9; - zz[9] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_10; - zz[10] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_11; - zz[11] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_12; - zz[12] = (w << 1) | c; - c = w >> 31; - w = zz[13] + (uint)(zz_12 >> 32); - zz[13] = (w << 1) | c; - } -#endif - - public static int Sub(uint[] x, uint[] y, uint[] z) + public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)x[0] - y[0]; @@ -1341,63 +690,7 @@ public static int Sub(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - c += (long)x[xOff + 0] - y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)x[xOff + 1] - y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)x[xOff + 2] - y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)x[xOff + 3] - y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)x[xOff + 4] - y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)x[xOff + 5] - y[yOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (long)x[xOff + 6] - y[yOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - return (int)c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) - { - long c = 0; - c += (long)x[0] - y[0]; - z[0] = (uint)c; - c >>= 32; - c += (long)x[1] - y[1]; - z[1] = (uint)c; - c >>= 32; - c += (long)x[2] - y[2]; - z[2] = (uint)c; - c >>= 32; - c += (long)x[3] - y[3]; - z[3] = (uint)c; - c >>= 32; - c += (long)x[4] - y[4]; - z[4] = (uint)c; - c >>= 32; - c += (long)x[5] - y[5]; - z[5] = (uint)c; - c >>= 32; - c += (long)x[6] - y[6]; - z[6] = (uint)c; - c >>= 32; - return (int)c; - } -#endif - - public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + public static int SubBothFrom(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)z[0] - x[0] - y[0]; @@ -1424,7 +717,7 @@ public static int SubBothFrom(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, uint[] z) + public static int SubFrom(ReadOnlySpan x, Span z) { long c = 0; c += (long)z[0] - x[0]; @@ -1451,33 +744,6 @@ public static int SubFrom(uint[] x, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff) - { - long c = 0; - c += (long)z[zOff + 0] - x[xOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - x[xOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)z[zOff + 2] - x[xOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)z[zOff + 3] - x[xOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)z[zOff + 4] - x[xOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)z[zOff + 5] - x[xOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (long)z[zOff + 6] - x[xOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - return (int)c; - } - public static BigInteger ToBigInteger(uint[] x) { byte[] bs = new byte[28]; diff --git a/crypto/src/math/raw/Nat256.cs b/crypto/src/math/raw/Nat256.cs index 49adf04afd..dedc6a4e85 100644 --- a/crypto/src/math/raw/Nat256.cs +++ b/crypto/src/math/raw/Nat256.cs @@ -15,7 +15,7 @@ internal static class Nat256 { private const ulong M = 0xFFFFFFFFUL; - public static uint Add(uint[] x, uint[] y, uint[] z) + public static uint Add(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0]; @@ -45,37 +45,7 @@ public static uint Add(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint Add(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0; - c += (ulong)x[xOff + 0] + y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + y[yOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + y[yOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 7] + y[yOff + 7]; - z[zOff + 7] = (uint)c; - c >>= 32; - return (uint)c; - } - - public static uint AddBothTo(uint[] x, uint[] y, uint[] z) + public static uint AddBothTo(ReadOnlySpan x, ReadOnlySpan y, Span z) { ulong c = 0; c += (ulong)x[0] + y[0] + z[0]; @@ -105,97 +75,11 @@ public static uint AddBothTo(uint[] x, uint[] y, uint[] z) return (uint)c; } - public static uint AddBothTo(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - ulong c = 0; - c += (ulong)x[xOff + 0] + y[yOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + y[yOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + y[yOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + y[yOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + y[yOff + 4] + z[zOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + y[yOff + 5] + z[zOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + y[yOff + 6] + z[zOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 7] + y[yOff + 7] + z[zOff + 7]; - z[zOff + 7] = (uint)c; - c >>= 32; - return (uint)c; - } - - public static uint AddTo(uint[] x, uint[] z, uint cIn) - { - ulong c = cIn; - c += (ulong)x[0] + z[0]; - z[0] = (uint)c; - c >>= 32; - c += (ulong)x[1] + z[1]; - z[1] = (uint)c; - c >>= 32; - c += (ulong)x[2] + z[2]; - z[2] = (uint)c; - c >>= 32; - c += (ulong)x[3] + z[3]; - z[3] = (uint)c; - c >>= 32; - c += (ulong)x[4] + z[4]; - z[4] = (uint)c; - c >>= 32; - c += (ulong)x[5] + z[5]; - z[5] = (uint)c; - c >>= 32; - c += (ulong)x[6] + z[6]; - z[6] = (uint)c; - c >>= 32; - c += (ulong)x[7] + z[7]; - z[7] = (uint)c; - c >>= 32; - return (uint)c; - } - public static uint AddTo(uint[] x, int xOff, uint[] z, int zOff, uint cIn) { - ulong c = cIn; - c += (ulong)x[xOff + 0] + z[zOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 1] + z[zOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 2] + z[zOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 3] + z[zOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 4] + z[zOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 5] + z[zOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 6] + z[zOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - c += (ulong)x[xOff + 7] + z[zOff + 7]; - z[zOff + 7] = (uint)c; - c >>= 32; - return (uint)c; + return AddTo(x.AsSpan(xOff), z.AsSpan(zOff), cIn); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static uint AddTo(ReadOnlySpan x, Span z, uint cIn) { ulong c = cIn; @@ -225,87 +109,55 @@ public static uint AddTo(ReadOnlySpan x, Span z, uint cIn) c >>= 32; return (uint)c; } -#endif - public static uint AddToEachOther(uint[] u, int uOff, uint[] v, int vOff) + public static uint AddToEachOther(Span u, Span v) { ulong c = 0; - c += (ulong)u[uOff + 0] + v[vOff + 0]; - u[uOff + 0] = (uint)c; - v[vOff + 0] = (uint)c; + c += (ulong)u[0] + v[0]; + u[0] = (uint)c; + v[0] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 1] + v[vOff + 1]; - u[uOff + 1] = (uint)c; - v[vOff + 1] = (uint)c; + c += (ulong)u[1] + v[1]; + u[1] = (uint)c; + v[1] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 2] + v[vOff + 2]; - u[uOff + 2] = (uint)c; - v[vOff + 2] = (uint)c; + c += (ulong)u[2] + v[2]; + u[2] = (uint)c; + v[2] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 3] + v[vOff + 3]; - u[uOff + 3] = (uint)c; - v[vOff + 3] = (uint)c; + c += (ulong)u[3] + v[3]; + u[3] = (uint)c; + v[3] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 4] + v[vOff + 4]; - u[uOff + 4] = (uint)c; - v[vOff + 4] = (uint)c; + c += (ulong)u[4] + v[4]; + u[4] = (uint)c; + v[4] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 5] + v[vOff + 5]; - u[uOff + 5] = (uint)c; - v[vOff + 5] = (uint)c; + c += (ulong)u[5] + v[5]; + u[5] = (uint)c; + v[5] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 6] + v[vOff + 6]; - u[uOff + 6] = (uint)c; - v[vOff + 6] = (uint)c; + c += (ulong)u[6] + v[6]; + u[6] = (uint)c; + v[6] = (uint)c; c >>= 32; - c += (ulong)u[uOff + 7] + v[vOff + 7]; - u[uOff + 7] = (uint)c; - v[vOff + 7] = (uint)c; + c += (ulong)u[7] + v[7]; + u[7] = (uint)c; + v[7] = (uint)c; c >>= 32; return (uint)c; } - public static void Copy(uint[] x, uint[] z) - { - z[0] = x[0]; - z[1] = x[1]; - z[2] = x[2]; - z[3] = x[3]; - z[4] = x[4]; - z[5] = x[5]; - z[6] = x[6]; - z[7] = x[7]; - } - public static void Copy(uint[] x, int xOff, uint[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; - z[zOff + 5] = x[xOff + 5]; - z[zOff + 6] = x[xOff + 6]; - z[zOff + 7] = x[xOff + 7]; - } - - public static void Copy64(ulong[] x, ulong[] z) - { - z[0] = x[0]; - z[1] = x[1]; - z[2] = x[2]; - z[3] = x[3]; + x.AsSpan(xOff, 8).CopyTo(z.AsSpan(zOff)); } public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; @@ -313,7 +165,6 @@ public static void Copy64(ReadOnlySpan x, Span z) z[2] = x[2]; z[3] = x[3]; } -#endif public static uint[] Create() { @@ -335,16 +186,16 @@ public static ulong[] CreateExt64() return new ulong[8]; } - public static bool Diff(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) + public static bool Diff(ReadOnlySpan x, ReadOnlySpan y, Span z) { - bool pos = Gte(x, xOff, y, yOff); + bool pos = Gte(x, y); if (pos) { - Sub(x, xOff, y, yOff, z, zOff); + Sub(x, y, z); } else { - Sub(y, yOff, x, xOff, z, zOff); + Sub(y, x, z); } return pos; } @@ -386,33 +237,6 @@ public static uint GetBit(uint[] x, int bit) return (x[w] >> b) & 1; } - public static bool Gte(uint[] x, uint[] y) - { - for (int i = 7; i >= 0; --i) - { - uint x_i = x[i], y_i = y[i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - - public static bool Gte(uint[] x, int xOff, uint[] y, int yOff) - { - for (int i = 7; i >= 0; --i) - { - uint x_i = x[xOff + i], y_i = y[yOff + i]; - if (x_i < y_i) - return false; - if (x_i > y_i) - return true; - } - return true; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) { for (int i = 7; i >= 0; --i) @@ -425,7 +249,6 @@ public static bool Gte(ReadOnlySpan x, ReadOnlySpan y) } return true; } -#endif public static bool IsOne(uint[] x) { @@ -459,11 +282,7 @@ public static bool IsOne64(ulong[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero(ReadOnlySpan x) -#else - public static bool IsZero(uint[] x) -#endif { for (int i = 0; i < 8; ++i) { @@ -473,11 +292,7 @@ public static bool IsZero(uint[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 4; ++i) { @@ -487,150 +302,6 @@ public static bool IsZero64(ulong[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) - { - ulong y_0 = y[0]; - ulong y_1 = y[1]; - ulong y_2 = y[2]; - ulong y_3 = y[3]; - ulong y_4 = y[4]; - ulong y_5 = y[5]; - ulong y_6 = y[6]; - ulong y_7 = y[7]; - - { - ulong c = 0, x_0 = x[0]; - c += x_0 * y_0; - zz[0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[4] = (uint)c; - c >>= 32; - c += x_0 * y_5; - zz[5] = (uint)c; - c >>= 32; - c += x_0 * y_6; - zz[6] = (uint)c; - c >>= 32; - c += x_0 * y_7; - zz[7] = (uint)c; - c >>= 32; - zz[8] = (uint)c; - } - - for (int i = 1; i < 8; ++i) - { - ulong c = 0, x_i = x[i]; - c += x_i * y_0 + zz[i + 0]; - zz[i + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[i + 1]; - zz[i + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[i + 2]; - zz[i + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[i + 3]; - zz[i + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[i + 4]; - zz[i + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[i + 5]; - zz[i + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[i + 6]; - zz[i + 6] = (uint)c; - c >>= 32; - c += x_i * y_7 + zz[i + 7]; - zz[i + 7] = (uint)c; - c >>= 32; - zz[i + 8] = (uint)c; - } - } - - public static void Mul(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - ulong y_6 = y[yOff + 6]; - ulong y_7 = y[yOff + 7]; - - { - ulong c = 0, x_0 = x[xOff + 0]; - c += x_0 * y_0; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_0 * y_1; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_0 * y_2; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_0 * y_3; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_0 * y_4; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_0 * y_5; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_0 * y_6; - zz[zzOff + 6] = (uint)c; - c >>= 32; - c += x_0 * y_7; - zz[zzOff + 7] = (uint)c; - c >>= 32; - zz[zzOff + 8] = (uint)c; - } - - for (int i = 1; i < 8; ++i) - { - ++zzOff; - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)c; - c >>= 32; - c += x_i * y_7 + zz[zzOff + 7]; - zz[zzOff + 7] = (uint)c; - c >>= 32; - zz[zzOff + 8] = (uint)c; - } - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { ulong y_0 = y[0]; @@ -701,9 +372,8 @@ public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz zz[i + 8] = (uint)c; } } -#endif - public static void Mul128(uint[] x, uint[] y128, uint[] zz) + public static void Mul128(ReadOnlySpan x, ReadOnlySpan y128, Span zz) { ulong x_0 = x[0]; ulong x_1 = x[1]; @@ -774,92 +444,19 @@ public static void Mul128(uint[] x, uint[] y128, uint[] zz) } } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public static void Mul128(ReadOnlySpan x, ReadOnlySpan y128, Span zz) + public static uint MulAddTo(ReadOnlySpan x, ReadOnlySpan y, Span zz) { - ulong x_0 = x[0]; - ulong x_1 = x[1]; - ulong x_2 = x[2]; - ulong x_3 = x[3]; - ulong x_4 = x[4]; - ulong x_5 = x[5]; - ulong x_6 = x[6]; - ulong x_7 = x[7]; + ulong y_0 = y[0]; + ulong y_1 = y[1]; + ulong y_2 = y[2]; + ulong y_3 = y[3]; + ulong y_4 = y[4]; + ulong y_5 = y[5]; + ulong y_6 = y[6]; + ulong y_7 = y[7]; - { - ulong c = 0, y_0 = y128[0]; - c += y_0 * x_0; - zz[0] = (uint)c; - c >>= 32; - c += y_0 * x_1; - zz[1] = (uint)c; - c >>= 32; - c += y_0 * x_2; - zz[2] = (uint)c; - c >>= 32; - c += y_0 * x_3; - zz[3] = (uint)c; - c >>= 32; - c += y_0 * x_4; - zz[4] = (uint)c; - c >>= 32; - c += y_0 * x_5; - zz[5] = (uint)c; - c >>= 32; - c += y_0 * x_6; - zz[6] = (uint)c; - c >>= 32; - c += y_0 * x_7; - zz[7] = (uint)c; - c >>= 32; - zz[8] = (uint)c; - } - - for (int i = 1; i < 4; ++i) - { - ulong c = 0, y_i = y128[i]; - c += y_i * x_0 + zz[i + 0]; - zz[i + 0] = (uint)c; - c >>= 32; - c += y_i * x_1 + zz[i + 1]; - zz[i + 1] = (uint)c; - c >>= 32; - c += y_i * x_2 + zz[i + 2]; - zz[i + 2] = (uint)c; - c >>= 32; - c += y_i * x_3 + zz[i + 3]; - zz[i + 3] = (uint)c; - c >>= 32; - c += y_i * x_4 + zz[i + 4]; - zz[i + 4] = (uint)c; - c >>= 32; - c += y_i * x_5 + zz[i + 5]; - zz[i + 5] = (uint)c; - c >>= 32; - c += y_i * x_6 + zz[i + 6]; - zz[i + 6] = (uint)c; - c >>= 32; - c += y_i * x_7 + zz[i + 7]; - zz[i + 7] = (uint)c; - c >>= 32; - zz[i + 8] = (uint)c; - } - } -#endif - - public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) - { - ulong y_0 = y[0]; - ulong y_1 = y[1]; - ulong y_2 = y[2]; - ulong y_3 = y[3]; - ulong y_4 = y[4]; - ulong y_5 = y[5]; - ulong y_6 = y[6]; - ulong y_7 = y[7]; - - ulong zc = 0; - for (int i = 0; i < 8; ++i) + ulong zc = 0; + for (int i = 0; i < 8; ++i) { ulong c = 0, x_i = x[i]; c += x_i * y_0 + zz[i + 0]; @@ -894,54 +491,6 @@ public static uint MulAddTo(uint[] x, uint[] y, uint[] zz) return (uint)zc; } - public static uint MulAddTo(uint[] x, int xOff, uint[] y, int yOff, uint[] zz, int zzOff) - { - ulong y_0 = y[yOff + 0]; - ulong y_1 = y[yOff + 1]; - ulong y_2 = y[yOff + 2]; - ulong y_3 = y[yOff + 3]; - ulong y_4 = y[yOff + 4]; - ulong y_5 = y[yOff + 5]; - ulong y_6 = y[yOff + 6]; - ulong y_7 = y[yOff + 7]; - - ulong zc = 0; - for (int i = 0; i < 8; ++i) - { - ulong c = 0, x_i = x[xOff + i]; - c += x_i * y_0 + zz[zzOff + 0]; - zz[zzOff + 0] = (uint)c; - c >>= 32; - c += x_i * y_1 + zz[zzOff + 1]; - zz[zzOff + 1] = (uint)c; - c >>= 32; - c += x_i * y_2 + zz[zzOff + 2]; - zz[zzOff + 2] = (uint)c; - c >>= 32; - c += x_i * y_3 + zz[zzOff + 3]; - zz[zzOff + 3] = (uint)c; - c >>= 32; - c += x_i * y_4 + zz[zzOff + 4]; - zz[zzOff + 4] = (uint)c; - c >>= 32; - c += x_i * y_5 + zz[zzOff + 5]; - zz[zzOff + 5] = (uint)c; - c >>= 32; - c += x_i * y_6 + zz[zzOff + 6]; - zz[zzOff + 6] = (uint)c; - c >>= 32; - c += x_i * y_7 + zz[zzOff + 7]; - zz[zzOff + 7] = (uint)c; - c >>= 32; - - zc += c + zz[zzOff + 8]; - zz[zzOff + 8] = (uint)zc; - zc >>= 32; - ++zzOff; - } - return (uint)zc; - } - public static ulong Mul33Add(uint w, uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) { Debug.Assert(w >> 31 == 0); @@ -1092,7 +641,7 @@ public static uint Mul33DWordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 3]; z[zOff + 3] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 4); + return c == 0 ? 0 : Nat.IncAt(8, z.AsSpan(zOff), 4); } public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) @@ -1109,7 +658,7 @@ public static uint Mul33WordAdd(uint x, uint y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(8, z.AsSpan(zOff), 3); } public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) @@ -1125,7 +674,7 @@ public static uint MulWordDwordAdd(uint x, ulong y, uint[] z, int zOff) c += z[zOff + 2]; z[zOff + 2] = (uint)c; c >>= 32; - return c == 0 ? 0 : Nat.IncAt(8, z, zOff, 3); + return c == 0 ? 0 : Nat.IncAt(8, z.AsSpan(zOff), 3); } public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) @@ -1142,335 +691,6 @@ public static uint MulWord(uint x, uint[] y, uint[] z, int zOff) return (uint)c; } - public static void Square(uint[] x, uint[] zz) - { - ulong x_0 = x[0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 7, j = 16; - do - { - ulong xVal = x[i--]; - ulong p = xVal * xVal; - zz[--j] = (c << 31) | (uint)(p >> 33); - zz[--j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[1]; - ulong zz_2 = zz[2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[2]; - ulong zz_3 = zz[3]; - ulong zz_4 = zz[4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[3]; - ulong zz_5 = zz[5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[4]; - ulong zz_7 = zz[7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_5 &= M; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_6 &= M; - zz_8 += zz_7 >> 32; - zz_7 &= M; - } - - ulong x_5 = x[5]; - ulong zz_9 = zz[9] + (zz_8 >> 32); zz_8 &= M; - ulong zz_10 = zz[10] + (zz_9 >> 32); zz_9 &= M; - { - zz_5 += x_5 * x_0; - w = (uint)zz_5; - zz[5] = (w << 1) | c; - c = w >> 31; - zz_6 += (zz_5 >> 32) + x_5 * x_1; - zz_7 += (zz_6 >> 32) + x_5 * x_2; - zz_6 &= M; - zz_8 += (zz_7 >> 32) + x_5 * x_3; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_5 * x_4; - zz_8 &= M; - zz_10 += zz_9 >> 32; - zz_9 &= M; - } - - ulong x_6 = x[6]; - ulong zz_11 = zz[11] + (zz_10 >> 32); zz_10 &= M; - ulong zz_12 = zz[12] + (zz_11 >> 32); zz_11 &= M; - { - zz_6 += x_6 * x_0; - w = (uint)zz_6; - zz[6] = (w << 1) | c; - c = w >> 31; - zz_7 += (zz_6 >> 32) + x_6 * x_1; - zz_8 += (zz_7 >> 32) + x_6 * x_2; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_6 * x_3; - zz_8 &= M; - zz_10 += (zz_9 >> 32) + x_6 * x_4; - zz_9 &= M; - zz_11 += (zz_10 >> 32) + x_6 * x_5; - zz_10 &= M; - zz_12 += zz_11 >> 32; - zz_11 &= M; - } - - ulong x_7 = x[7]; - ulong zz_13 = zz[13] + (zz_12 >> 32); zz_12 &= M; - ulong zz_14 = zz[14] + (zz_13 >> 32); zz_13 &= M; - { - zz_7 += x_7 * x_0; - w = (uint)zz_7; - zz[7] = (w << 1) | c; - c = w >> 31; - zz_8 += (zz_7 >> 32) + x_7 * x_1; - zz_9 += (zz_8 >> 32) + x_7 * x_2; - zz_10 += (zz_9 >> 32) + x_7 * x_3; - zz_11 += (zz_10 >> 32) + x_7 * x_4; - zz_12 += (zz_11 >> 32) + x_7 * x_5; - zz_13 += (zz_12 >> 32) + x_7 * x_6; - zz_14 += zz_13 >> 32; - } - - w = (uint)zz_8; - zz[8] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_9; - zz[9] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_10; - zz[10] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_11; - zz[11] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_12; - zz[12] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_13; - zz[13] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_14; - zz[14] = (w << 1) | c; - c = w >> 31; - w = zz[15] + (uint)(zz_14 >> 32); - zz[15] = (w << 1) | c; - } - - public static void Square(uint[] x, int xOff, uint[] zz, int zzOff) - { - ulong x_0 = x[xOff + 0]; - ulong zz_1; - - uint c = 0, w; - { - int i = 7, j = 16; - do - { - ulong xVal = x[xOff + i--]; - ulong p = xVal * xVal; - zz[zzOff + --j] = (c << 31) | (uint)(p >> 33); - zz[zzOff + --j] = (uint)(p >> 1); - c = (uint)p; - } - while (i > 0); - - { - ulong p = x_0 * x_0; - zz_1 = (ulong)(c << 31) | (p >> 33); - zz[zzOff + 0] = (uint)p; - c = (uint)(p >> 32) & 1; - } - } - - ulong x_1 = x[xOff + 1]; - ulong zz_2 = zz[zzOff + 2]; - - { - zz_1 += x_1 * x_0; - w = (uint)zz_1; - zz[zzOff + 1] = (w << 1) | c; - c = w >> 31; - zz_2 += zz_1 >> 32; - } - - ulong x_2 = x[xOff + 2]; - ulong zz_3 = zz[zzOff + 3]; - ulong zz_4 = zz[zzOff + 4]; - { - zz_2 += x_2 * x_0; - w = (uint)zz_2; - zz[zzOff + 2] = (w << 1) | c; - c = w >> 31; - zz_3 += (zz_2 >> 32) + x_2 * x_1; - zz_4 += zz_3 >> 32; - zz_3 &= M; - } - - ulong x_3 = x[xOff + 3]; - ulong zz_5 = zz[zzOff + 5] + (zz_4 >> 32); zz_4 &= M; - ulong zz_6 = zz[zzOff + 6] + (zz_5 >> 32); zz_5 &= M; - { - zz_3 += x_3 * x_0; - w = (uint)zz_3; - zz[zzOff + 3] = (w << 1) | c; - c = w >> 31; - zz_4 += (zz_3 >> 32) + x_3 * x_1; - zz_5 += (zz_4 >> 32) + x_3 * x_2; - zz_4 &= M; - zz_6 += zz_5 >> 32; - zz_5 &= M; - } - - ulong x_4 = x[xOff + 4]; - ulong zz_7 = zz[zzOff + 7] + (zz_6 >> 32); zz_6 &= M; - ulong zz_8 = zz[zzOff + 8] + (zz_7 >> 32); zz_7 &= M; - { - zz_4 += x_4 * x_0; - w = (uint)zz_4; - zz[zzOff + 4] = (w << 1) | c; - c = w >> 31; - zz_5 += (zz_4 >> 32) + x_4 * x_1; - zz_6 += (zz_5 >> 32) + x_4 * x_2; - zz_5 &= M; - zz_7 += (zz_6 >> 32) + x_4 * x_3; - zz_6 &= M; - zz_8 += zz_7 >> 32; - zz_7 &= M; - } - - ulong x_5 = x[xOff + 5]; - ulong zz_9 = zz[zzOff + 9] + (zz_8 >> 32); zz_8 &= M; - ulong zz_10 = zz[zzOff + 10] + (zz_9 >> 32); zz_9 &= M; - { - zz_5 += x_5 * x_0; - w = (uint)zz_5; - zz[zzOff + 5] = (w << 1) | c; - c = w >> 31; - zz_6 += (zz_5 >> 32) + x_5 * x_1; - zz_7 += (zz_6 >> 32) + x_5 * x_2; - zz_6 &= M; - zz_8 += (zz_7 >> 32) + x_5 * x_3; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_5 * x_4; - zz_8 &= M; - zz_10 += zz_9 >> 32; - zz_9 &= M; - } - - ulong x_6 = x[xOff + 6]; - ulong zz_11 = zz[zzOff + 11] + (zz_10 >> 32); zz_10 &= M; - ulong zz_12 = zz[zzOff + 12] + (zz_11 >> 32); zz_11 &= M; - { - zz_6 += x_6 * x_0; - w = (uint)zz_6; - zz[zzOff + 6] = (w << 1) | c; - c = w >> 31; - zz_7 += (zz_6 >> 32) + x_6 * x_1; - zz_8 += (zz_7 >> 32) + x_6 * x_2; - zz_7 &= M; - zz_9 += (zz_8 >> 32) + x_6 * x_3; - zz_8 &= M; - zz_10 += (zz_9 >> 32) + x_6 * x_4; - zz_9 &= M; - zz_11 += (zz_10 >> 32) + x_6 * x_5; - zz_10 &= M; - zz_12 += zz_11 >> 32; - zz_11 &= M; - } - - ulong x_7 = x[xOff + 7]; - ulong zz_13 = zz[zzOff + 13] + (zz_12 >> 32); zz_12 &= M; - ulong zz_14 = zz[zzOff + 14] + (zz_13 >> 32); zz_13 &= M; - { - zz_7 += x_7 * x_0; - w = (uint)zz_7; - zz[zzOff + 7] = (w << 1) | c; - c = w >> 31; - zz_8 += (zz_7 >> 32) + x_7 * x_1; - zz_9 += (zz_8 >> 32) + x_7 * x_2; - zz_10 += (zz_9 >> 32) + x_7 * x_3; - zz_11 += (zz_10 >> 32) + x_7 * x_4; - zz_12 += (zz_11 >> 32) + x_7 * x_5; - zz_13 += (zz_12 >> 32) + x_7 * x_6; - zz_14 += zz_13 >> 32; - } - - w = (uint)zz_8; - zz[zzOff + 8] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_9; - zz[zzOff + 9] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_10; - zz[zzOff + 10] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_11; - zz[zzOff + 11] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_12; - zz[zzOff + 12] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_13; - zz[zzOff + 13] = (w << 1) | c; - c = w >> 31; - w = (uint)zz_14; - zz[zzOff + 14] = (w << 1) | c; - c = w >> 31; - w = zz[zzOff + 15] + (uint)(zz_14 >> 32); - zz[zzOff + 15] = (w << 1) | c; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Square(ReadOnlySpan x, Span zz) { ulong x_0 = x[0]; @@ -1634,9 +854,8 @@ public static void Square(ReadOnlySpan x, Span zz) w = zz[15] + (uint)(zz_14 >> 32); zz[15] = (w << 1) | c; } -#endif - public static int Sub(uint[] x, uint[] y, uint[] z) + public static int Sub(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)x[0] - y[0]; @@ -1666,37 +885,7 @@ public static int Sub(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int Sub(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { - long c = 0; - c += (long)x[xOff + 0] - y[yOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)x[xOff + 1] - y[yOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)x[xOff + 2] - y[yOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)x[xOff + 3] - y[yOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)x[xOff + 4] - y[yOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)x[xOff + 5] - y[yOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (long)x[xOff + 6] - y[yOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - c += (long)x[xOff + 7] - y[yOff + 7]; - z[zOff + 7] = (uint)c; - c >>= 32; - return (int)c; - } - - public static int SubBothFrom(uint[] x, uint[] y, uint[] z) + public static int SubBothFrom(ReadOnlySpan x, ReadOnlySpan y, Span z) { long c = 0; c += (long)z[0] - x[0] - y[0]; @@ -1726,67 +915,11 @@ public static int SubBothFrom(uint[] x, uint[] y, uint[] z) return (int)c; } - public static int SubFrom(uint[] x, uint[] z, int cIn) - { - long c = cIn; - c += (long)z[0] - x[0]; - z[0] = (uint)c; - c >>= 32; - c += (long)z[1] - x[1]; - z[1] = (uint)c; - c >>= 32; - c += (long)z[2] - x[2]; - z[2] = (uint)c; - c >>= 32; - c += (long)z[3] - x[3]; - z[3] = (uint)c; - c >>= 32; - c += (long)z[4] - x[4]; - z[4] = (uint)c; - c >>= 32; - c += (long)z[5] - x[5]; - z[5] = (uint)c; - c >>= 32; - c += (long)z[6] - x[6]; - z[6] = (uint)c; - c >>= 32; - c += (long)z[7] - x[7]; - z[7] = (uint)c; - c >>= 32; - return (int)c; - } - public static int SubFrom(uint[] x, int xOff, uint[] z, int zOff, int cIn) { - long c = cIn; - c += (long)z[zOff + 0] - x[xOff + 0]; - z[zOff + 0] = (uint)c; - c >>= 32; - c += (long)z[zOff + 1] - x[xOff + 1]; - z[zOff + 1] = (uint)c; - c >>= 32; - c += (long)z[zOff + 2] - x[xOff + 2]; - z[zOff + 2] = (uint)c; - c >>= 32; - c += (long)z[zOff + 3] - x[xOff + 3]; - z[zOff + 3] = (uint)c; - c >>= 32; - c += (long)z[zOff + 4] - x[xOff + 4]; - z[zOff + 4] = (uint)c; - c >>= 32; - c += (long)z[zOff + 5] - x[xOff + 5]; - z[zOff + 5] = (uint)c; - c >>= 32; - c += (long)z[zOff + 6] - x[xOff + 6]; - z[zOff + 6] = (uint)c; - c >>= 32; - c += (long)z[zOff + 7] - x[xOff + 7]; - z[zOff + 7] = (uint)c; - c >>= 32; - return (int)c; + return SubFrom(x.AsSpan(xOff), z.AsSpan(zOff), cIn); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static int SubFrom(ReadOnlySpan x, Span z, int cIn) { long c = cIn; @@ -1816,7 +949,6 @@ public static int SubFrom(ReadOnlySpan x, Span z, int cIn) c >>= 32; return (int)c; } -#endif public static BigInteger ToBigInteger(uint[] x) { @@ -1846,22 +978,6 @@ public static BigInteger ToBigInteger64(ulong[] x) return new BigInteger(1, bs); } - public static void Xor(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); -#else - for (int i = 0; i < 8; i += 4) - { - z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; - z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; - z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; - z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; - } -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor(ReadOnlySpan x, ReadOnlySpan y, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -1911,18 +1027,5 @@ public static void Xor(ReadOnlySpan x, ReadOnlySpan y, Span z) z[i + 3] = x[i + 3] ^ y[i + 3]; } } -#endif - - public static void Zero(uint[] z) - { - z[0] = 0; - z[1] = 0; - z[2] = 0; - z[3] = 0; - z[4] = 0; - z[5] = 0; - z[6] = 0; - z[7] = 0; - } } } diff --git a/crypto/src/math/raw/Nat320.cs b/crypto/src/math/raw/Nat320.cs index d52389cb18..37aaaea14f 100644 --- a/crypto/src/math/raw/Nat320.cs +++ b/crypto/src/math/raw/Nat320.cs @@ -7,25 +7,11 @@ namespace Org.BouncyCastle.Math.Raw { internal static class Nat320 { - public static void Copy64(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 void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; @@ -34,7 +20,6 @@ public static void Copy64(ReadOnlySpan x, Span z) z[3] = x[3]; z[4] = x[4]; } -#endif public static ulong[] Create64() { @@ -74,11 +59,7 @@ public static bool IsOne64(ulong[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 5; ++i) { diff --git a/crypto/src/math/raw/Nat384.cs b/crypto/src/math/raw/Nat384.cs index 2373d46102..5be872b99e 100644 --- a/crypto/src/math/raw/Nat384.cs +++ b/crypto/src/math/raw/Nat384.cs @@ -5,41 +5,41 @@ namespace Org.BouncyCastle.Math.Raw { internal static class Nat384 { - public static void Mul(uint[] x, uint[] y, uint[] zz) + public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { Nat192.Mul(x, y, zz); - Nat192.Mul(x, 6, y, 6, zz, 12); + Nat192.Mul(x[6..], y[6..], zz[12..]); - uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); - uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); - c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + uint c18 = Nat192.AddToEachOther(zz[6..], zz[12..]); + uint c12 = c18 + Nat192.AddTo(zz, zz[6..], 0); + c18 += Nat192.AddTo(zz[18..], zz[12..], c12); uint[] dx = Nat192.Create(), dy = Nat192.Create(); - bool neg = Nat192.Diff(x, 6, x, 0, dx, 0) != Nat192.Diff(y, 6, y, 0, dy, 0); + bool neg = Nat192.Diff(x[6..], x, dx) != Nat192.Diff(y[6..], y, dy); uint[] tt = Nat192.CreateExt(); Nat192.Mul(dx, dy, tt); - c18 += neg ? Nat.AddTo(12, tt, 0, zz, 6) : (uint)Nat.SubFrom(12, tt, 0, zz, 6); + c18 += neg ? Nat.AddTo(12, tt, zz[6..]) : (uint)Nat.SubFrom(12, tt, zz[6..]); Nat.AddWordAt(24, c18, zz, 18); } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { Nat192.Square(x, zz); - Nat192.Square(x, 6, zz, 12); + Nat192.Square(x[6..], zz[12..]); - uint c18 = Nat192.AddToEachOther(zz, 6, zz, 12); - uint c12 = c18 + Nat192.AddTo(zz, 0, zz, 6, 0); - c18 += Nat192.AddTo(zz, 18, zz, 12, c12); + uint c18 = Nat192.AddToEachOther(zz[6..], zz[12..]); + uint c12 = c18 + Nat192.AddTo(zz, zz[6..], 0); + c18 += Nat192.AddTo(zz[18..], zz[12..], c12); uint[] dx = Nat192.Create(); - Nat192.Diff(x, 6, x, 0, dx, 0); + Nat192.Diff(x[6..], x, dx); uint[] m = Nat192.CreateExt(); Nat192.Square(dx, m); - c18 += (uint)Nat.SubFrom(12, m, 0, zz, 6); + c18 += (uint)Nat.SubFrom(12, m, zz[6..]); Nat.AddWordAt(24, c18, zz, 18); } } diff --git a/crypto/src/math/raw/Nat448.cs b/crypto/src/math/raw/Nat448.cs index ac29ca9afc..0c0199f654 100644 --- a/crypto/src/math/raw/Nat448.cs +++ b/crypto/src/math/raw/Nat448.cs @@ -1,35 +1,16 @@ using System; using System.Diagnostics; - using Org.BouncyCastle.Crypto.Utilities; namespace Org.BouncyCastle.Math.Raw { internal static class Nat448 { - public static void Copy64(ulong[] x, ulong[] z) - { - z[0] = x[0]; - z[1] = x[1]; - z[2] = x[2]; - z[3] = x[3]; - z[4] = x[4]; - z[5] = x[5]; - z[6] = x[6]; - } - public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; - z[zOff + 5] = x[xOff + 5]; - z[zOff + 6] = x[xOff + 6]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; @@ -40,7 +21,6 @@ public static void Copy64(ReadOnlySpan x, Span z) z[5] = x[5]; z[6] = x[6]; } -#endif public static ulong[] Create64() { @@ -80,11 +60,7 @@ public static bool IsOne64(ulong[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 7; ++i) { @@ -96,26 +72,6 @@ public static bool IsZero64(ulong[] x) return true; } - public static void Mul(uint[] x, uint[] y, uint[] zz) - { - Nat224.Mul(x, y, zz); - Nat224.Mul(x, 7, y, 7, zz, 14); - - uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14); - uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0U); - c21 += Nat224.AddTo(zz, 21, zz, 14, c14); - - uint[] dx = Nat224.Create(), dy = Nat224.Create(); - bool neg = Nat224.Diff(x, 7, x, 0, dx, 0) != Nat224.Diff(y, 7, y, 0, dy, 0); - - uint[] tt = Nat224.CreateExt(); - Nat224.Mul(dx, dy, tt); - - c21 += neg ? Nat.AddTo(14, tt, 0, zz, 7) : (uint)Nat.SubFrom(14, tt, 0, zz, 7); - Nat.AddWordAt(28, c21, zz, 21); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { Nat224.Mul(x, y, zz); @@ -135,28 +91,7 @@ public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz c21 += neg ? Nat.AddTo(14, tt, zz[7..]) : (uint)Nat.SubFrom(14, tt, zz[7..]); Nat.AddWordAt(28, c21, zz, 21); } -#endif - - public static void Square(uint[] x, uint[] zz) - { - Nat224.Square(x, zz); - Nat224.Square(x, 7, zz, 14); - - uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14); - uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0U); - c21 += Nat224.AddTo(zz, 21, zz, 14, c14); - - uint[] dx = Nat224.Create(); - Nat224.Diff(x, 7, x, 0, dx, 0); - - uint[] tt = Nat224.CreateExt(); - Nat224.Square(dx, tt); - - c21 += (uint)Nat.SubFrom(14, tt, 0, zz, 7); - Nat.AddWordAt(28, c21, zz, 21); - } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Square(ReadOnlySpan x, Span zz) { Nat224.Square(x, zz); @@ -175,7 +110,6 @@ public static void Square(ReadOnlySpan x, Span zz) c21 += (uint)Nat.SubFrom(14, tt, zz[7..]); Nat.AddWordAt(28, c21, zz, 21); } -#endif public static BigInteger ToBigInteger64(ulong[] x) { diff --git a/crypto/src/math/raw/Nat512.cs b/crypto/src/math/raw/Nat512.cs index 8e98c37df6..a73b4f0417 100644 --- a/crypto/src/math/raw/Nat512.cs +++ b/crypto/src/math/raw/Nat512.cs @@ -10,75 +10,44 @@ namespace Org.BouncyCastle.Math.Raw { internal static class Nat512 { - public static void Mul(uint[] x, uint[] y, uint[] zz) + public static void Mul(ReadOnlySpan x, ReadOnlySpan y, Span zz) { Nat256.Mul(x, y, zz); - Nat256.Mul(x, 8, y, 8, zz, 16); + Nat256.Mul(x[8..], y[8..], zz[16..]); - uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); - uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0U); - c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + uint c24 = Nat256.AddToEachOther(zz[8..], zz[16..]); + uint c16 = c24 + Nat256.AddTo(zz, zz[8..], 0U); + c24 += Nat256.AddTo(zz[24..], zz[16..], c16); uint[] dx = Nat256.Create(), dy = Nat256.Create(); - bool neg = Nat256.Diff(x, 8, x, 0, dx, 0) != Nat256.Diff(y, 8, y, 0, dy, 0); + bool neg = Nat256.Diff(x[8..], x, dx) != Nat256.Diff(y[8..], y, dy); uint[] tt = Nat256.CreateExt(); Nat256.Mul(dx, dy, tt); - c24 += neg ? Nat.AddTo(16, tt, 0, zz, 8) : (uint)Nat.SubFrom(16, tt, 0, zz, 8); + c24 += neg ? Nat.AddTo(16, tt, zz[8..]) : (uint)Nat.SubFrom(16, tt, zz[8..]); Nat.AddWordAt(32, c24, zz, 24); } - public static void Square(uint[] x, uint[] zz) + public static void Square(ReadOnlySpan x, Span zz) { Nat256.Square(x, zz); - Nat256.Square(x, 8, zz, 16); + Nat256.Square(x[8..], zz[16..]); - uint c24 = Nat256.AddToEachOther(zz, 8, zz, 16); - uint c16 = c24 + Nat256.AddTo(zz, 0, zz, 8, 0U); - c24 += Nat256.AddTo(zz, 24, zz, 16, c16); + uint c24 = Nat256.AddToEachOther(zz[8..], zz[16..]); + uint c16 = c24 + Nat256.AddTo(zz, zz[8..], 0U); + c24 += Nat256.AddTo(zz[24..], zz[16..], c16); uint[] dx = Nat256.Create(); - Nat256.Diff(x, 8, x, 0, dx, 0); + Nat256.Diff(x[8..], x, dx); uint[] m = Nat256.CreateExt(); Nat256.Square(dx, m); - c24 += (uint)Nat.SubFrom(16, m, 0, zz, 8); + c24 += (uint)Nat.SubFrom(16, m, zz[8..]); Nat.AddWordAt(32, c24, zz, 24); } - public static void Xor(uint[] x, uint[] y, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor(x.AsSpan(), y.AsSpan(), z.AsSpan()); -#else - for (int i = 0; i < 16; i += 4) - { - z[i + 0] = x[i + 0] ^ y[i + 0]; - z[i + 1] = x[i + 1] ^ y[i + 1]; - z[i + 2] = x[i + 2] ^ y[i + 2]; - z[i + 3] = x[i + 3] ^ y[i + 3]; - } -#endif - } - - public static void Xor(uint[] x, int xOff, uint[] y, int yOff, uint[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); -#else - for (int i = 0; i < 16; i += 4) - { - z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; - z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; - z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; - z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; - } -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor(ReadOnlySpan x, ReadOnlySpan y, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -141,39 +110,7 @@ public static void Xor(ReadOnlySpan x, ReadOnlySpan y, Span z) z[i + 3] = x[i + 3] ^ y[i + 3]; } } -#endif - - public static void Xor64(ulong[] x, ulong[] y, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor64(x.AsSpan(), y.AsSpan(), z.AsSpan()); -#else - for (int i = 0; i < 8; i += 4) - { - z[i + 0] = x[i + 0] ^ y[i + 0]; - z[i + 1] = x[i + 1] ^ y[i + 1]; - z[i + 2] = x[i + 2] ^ y[i + 2]; - z[i + 3] = x[i + 3] ^ y[i + 3]; - } -#endif - } - public static void Xor64(ulong[] x, int xOff, ulong[] y, int yOff, ulong[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - Xor64(x.AsSpan(xOff), y.AsSpan(yOff), z.AsSpan(zOff)); -#else - for (int i = 0; i < 8; i += 4) - { - z[zOff + i + 0] = x[xOff + i + 0] ^ y[yOff + i + 0]; - z[zOff + i + 1] = x[xOff + i + 1] ^ y[yOff + i + 1]; - z[zOff + i + 2] = x[xOff + i + 2] ^ y[yOff + i + 2]; - z[zOff + i + 3] = x[xOff + i + 3] ^ y[yOff + i + 3]; - } -#endif - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Xor64(ReadOnlySpan x, ReadOnlySpan y, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -236,39 +173,7 @@ public static void Xor64(ReadOnlySpan x, ReadOnlySpan y, Span x, ReadOnlySpan y, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -339,39 +244,7 @@ public static void XorBothTo(ReadOnlySpan x, ReadOnlySpan y, Span x, ReadOnlySpan y, Span z) { #if NETCOREAPP3_0_OR_GREATER @@ -442,192 +315,20 @@ public static void XorBothTo64(ReadOnlySpan x, ReadOnlySpan y, Spa z[i + 3] ^= x[i + 3] ^ y[i + 3]; } } -#endif - - public static void XorTo(uint[] x, uint[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorTo(x.AsSpan(), z.AsSpan()); -#else - for (int i = 0; i < 16; i += 4) - { - z[i + 0] ^= x[i + 0]; - z[i + 1] ^= x[i + 1]; - z[i + 2] ^= x[i + 2]; - z[i + 3] ^= x[i + 3]; - } -#endif - } public static void XorTo(uint[] x, int xOff, uint[] z, int zOff) { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER XorTo(x.AsSpan(xOff), z.AsSpan(zOff)); -#else - for (int i = 0; i < 16; i += 4) - { - z[zOff + i + 0] ^= x[xOff + i + 0]; - z[zOff + i + 1] ^= x[xOff + i + 1]; - z[zOff + i + 2] ^= x[xOff + i + 2]; - z[zOff + i + 3] ^= x[xOff + i + 3]; - } -#endif } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void XorTo(ReadOnlySpan x, Span z) { -#if NETCOREAPP3_0_OR_GREATER - if (Org.BouncyCastle.Runtime.Intrinsics.X86.Avx2.IsEnabled && - Org.BouncyCastle.Runtime.Intrinsics.Vector.IsPacked) - { - var X = MemoryMarshal.AsBytes(x[..16]); - var Z = MemoryMarshal.AsBytes(z[..16]); - - var X0 = MemoryMarshal.Read>(X[0x00..0x20]); - var X1 = MemoryMarshal.Read>(X[0x20..0x40]); - - var Z0 = MemoryMarshal.Read>(Z[0x00..0x20]); - var Z1 = MemoryMarshal.Read>(Z[0x20..0x40]); - - Z0 = Avx2.Xor(Z0, X0); - Z1 = Avx2.Xor(Z1, X1); - - MemoryMarshal.Write(Z[0x00..0x20], ref Z0); - MemoryMarshal.Write(Z[0x20..0x40], ref Z1); - return; - } - - if (Org.BouncyCastle.Runtime.Intrinsics.X86.Sse2.IsEnabled && - Org.BouncyCastle.Runtime.Intrinsics.Vector.IsPacked) - { - var X = MemoryMarshal.AsBytes(x[..16]); - var Z = MemoryMarshal.AsBytes(z[..16]); - - var X0 = MemoryMarshal.Read>(X[0x00..0x10]); - var X1 = MemoryMarshal.Read>(X[0x10..0x20]); - var X2 = MemoryMarshal.Read>(X[0x20..0x30]); - var X3 = MemoryMarshal.Read>(X[0x30..0x40]); - - var Z0 = MemoryMarshal.Read>(Z[0x00..0x10]); - var Z1 = MemoryMarshal.Read>(Z[0x10..0x20]); - var Z2 = MemoryMarshal.Read>(Z[0x20..0x30]); - var Z3 = MemoryMarshal.Read>(Z[0x30..0x40]); - - Z0 = Sse2.Xor(Z0, X0); - Z1 = Sse2.Xor(Z1, X1); - Z2 = Sse2.Xor(Z2, X2); - Z3 = Sse2.Xor(Z3, X3); - - MemoryMarshal.Write(Z[0x00..0x10], ref Z0); - MemoryMarshal.Write(Z[0x10..0x20], ref Z1); - MemoryMarshal.Write(Z[0x20..0x30], ref Z2); - MemoryMarshal.Write(Z[0x30..0x40], ref Z3); - return; - } -#endif - - for (int i = 0; i < 16; i += 4) - { - z[i + 0] ^= x[i + 0]; - z[i + 1] ^= x[i + 1]; - z[i + 2] ^= x[i + 2]; - z[i + 3] ^= x[i + 3]; - } - } -#endif - - public static void XorTo64(ulong[] x, ulong[] z) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorTo64(x.AsSpan(), z.AsSpan()); -#else - for (int i = 0; i < 8; i += 4) - { - z[i + 0] ^= x[i + 0]; - z[i + 1] ^= x[i + 1]; - z[i + 2] ^= x[i + 2]; - z[i + 3] ^= x[i + 3]; - } -#endif - } - - public static void XorTo64(ulong[] x, int xOff, ulong[] z, int zOff) - { -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - XorTo64(x.AsSpan(xOff), z.AsSpan(zOff)); -#else - for (int i = 0; i < 8; i += 4) - { - z[zOff + i + 0] ^= x[xOff + i + 0]; - z[zOff + i + 1] ^= x[xOff + i + 1]; - z[zOff + i + 2] ^= x[xOff + i + 2]; - z[zOff + i + 3] ^= x[xOff + i + 3]; - } -#endif + Xor(x, z, z); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void XorTo64(ReadOnlySpan x, Span z) { -#if NETCOREAPP3_0_OR_GREATER - if (Org.BouncyCastle.Runtime.Intrinsics.X86.Avx2.IsEnabled && - Org.BouncyCastle.Runtime.Intrinsics.Vector.IsPacked) - { - var X = MemoryMarshal.AsBytes(x[..8]); - var Z = MemoryMarshal.AsBytes(z[..8]); - - var X0 = MemoryMarshal.Read>(X[0x00..0x20]); - var X1 = MemoryMarshal.Read>(X[0x20..0x40]); - - var Y0 = MemoryMarshal.Read>(Z[0x00..0x20]); - var Y1 = MemoryMarshal.Read>(Z[0x20..0x40]); - - var Z0 = Avx2.Xor(X0, Y0); - var Z1 = Avx2.Xor(X1, Y1); - - MemoryMarshal.Write(Z[0x00..0x20], ref Z0); - MemoryMarshal.Write(Z[0x20..0x40], ref Z1); - return; - } - - if (Org.BouncyCastle.Runtime.Intrinsics.X86.Sse2.IsEnabled && - Org.BouncyCastle.Runtime.Intrinsics.Vector.IsPacked) - { - var X = MemoryMarshal.AsBytes(x[..8]); - var Z = MemoryMarshal.AsBytes(z[..8]); - - var X0 = MemoryMarshal.Read>(X[0x00..0x10]); - var X1 = MemoryMarshal.Read>(X[0x10..0x20]); - var X2 = MemoryMarshal.Read>(X[0x20..0x30]); - var X3 = MemoryMarshal.Read>(X[0x30..0x40]); - - var Y0 = MemoryMarshal.Read>(Z[0x00..0x10]); - var Y1 = MemoryMarshal.Read>(Z[0x10..0x20]); - var Y2 = MemoryMarshal.Read>(Z[0x20..0x30]); - var Y3 = MemoryMarshal.Read>(Z[0x30..0x40]); - - var Z0 = Sse2.Xor(X0, Y0); - var Z1 = Sse2.Xor(X1, Y1); - var Z2 = Sse2.Xor(X2, Y2); - var Z3 = Sse2.Xor(X3, Y3); - - MemoryMarshal.Write(Z[0x00..0x10], ref Z0); - MemoryMarshal.Write(Z[0x10..0x20], ref Z1); - MemoryMarshal.Write(Z[0x20..0x30], ref Z2); - MemoryMarshal.Write(Z[0x30..0x40], ref Z3); - return; - } -#endif - - for (int i = 0; i < 8; i += 4) - { - z[i + 0] ^= x[i + 0]; - z[i + 1] ^= x[i + 1]; - z[i + 2] ^= x[i + 2]; - z[i + 3] ^= x[i + 3]; - } + Xor64(x, z, z); } -#endif } } diff --git a/crypto/src/math/raw/Nat576.cs b/crypto/src/math/raw/Nat576.cs index 73b9593663..ad4c85a9ca 100644 --- a/crypto/src/math/raw/Nat576.cs +++ b/crypto/src/math/raw/Nat576.cs @@ -7,33 +7,11 @@ namespace Org.BouncyCastle.Math.Raw { internal static class Nat576 { - public static void Copy64(ulong[] x, ulong[] z) - { - z[0] = x[0]; - z[1] = x[1]; - z[2] = x[2]; - z[3] = x[3]; - z[4] = x[4]; - z[5] = x[5]; - z[6] = x[6]; - z[7] = x[7]; - z[8] = x[8]; - } - public static void Copy64(ulong[] x, int xOff, ulong[] z, int zOff) { - z[zOff + 0] = x[xOff + 0]; - z[zOff + 1] = x[xOff + 1]; - z[zOff + 2] = x[xOff + 2]; - z[zOff + 3] = x[xOff + 3]; - z[zOff + 4] = x[xOff + 4]; - z[zOff + 5] = x[xOff + 5]; - z[zOff + 6] = x[xOff + 6]; - z[zOff + 7] = x[xOff + 7]; - z[zOff + 8] = x[xOff + 8]; + Copy64(x.AsSpan(xOff), z.AsSpan(zOff)); } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Copy64(ReadOnlySpan x, Span z) { z[0] = x[0]; @@ -46,7 +24,6 @@ public static void Copy64(ReadOnlySpan x, Span z) z[7] = x[7]; z[8] = x[8]; } -#endif public static ulong[] Create64() { @@ -86,11 +63,7 @@ public static bool IsOne64(ulong[] x) return true; } -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static bool IsZero64(ReadOnlySpan x) -#else - public static bool IsZero64(ulong[] x) -#endif { for (int i = 0; i < 9; ++i) {