summary refs log tree commit diff
path: root/crypto/src/math/raw/Nat.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/math/raw/Nat.cs')
-rw-r--r--crypto/src/math/raw/Nat.cs63
1 files changed, 63 insertions, 0 deletions
diff --git a/crypto/src/math/raw/Nat.cs b/crypto/src/math/raw/Nat.cs
index 3bc983430..b3b670954 100644
--- a/crypto/src/math/raw/Nat.cs
+++ b/crypto/src/math/raw/Nat.cs
@@ -1,5 +1,8 @@
 using System;
 using System.Diagnostics;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+using System.Numerics;
+#endif
 
 using Org.BouncyCastle.Crypto.Utilities;
 
@@ -2737,6 +2740,66 @@ namespace Org.BouncyCastle.Math.Raw
         }
 #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<ulong> x, ulong y, Span<ulong> z)
+        {
+            int i = 0;
+            if (Vector.IsHardwareAccelerated)
+            {
+                var vy = new Vector<ulong>(y);
+
+                int limit = len - Vector<ulong>.Count;
+                while (i <= limit)
+                {
+                    var vx = new Vector<ulong>(x[i..]);
+                    (vx ^ vy).CopyTo(z[i..]);
+                    i += Vector<ulong>.Count;
+                }
+            }
+            else
+            {
+                int limit = len - 4;
+                while (i <= limit)
+                {
+                    z[i + 0] = x[i + 0] ^ y;
+                    z[i + 1] = x[i + 1] ^ y;
+                    z[i + 2] = x[i + 2] ^ y;
+                    z[i + 3] = x[i + 3] ^ y;
+                    i += 4;
+                }
+            }
+            while (i < len)
+            {
+                z[i] = x[i] ^ y;
+                ++i;
+            }
+        }
+#endif
+
         public static void Xor64(int len, ulong[] x, ulong[] y, ulong[] z)
         {
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER