summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/util/Bytes.cs123
1 files changed, 123 insertions, 0 deletions
diff --git a/crypto/src/util/Bytes.cs b/crypto/src/util/Bytes.cs
index 466eba576..e808555f5 100644
--- a/crypto/src/util/Bytes.cs
+++ b/crypto/src/util/Bytes.cs
@@ -1,4 +1,7 @@
 using System;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+using System.Numerics;
+#endif
 
 namespace Org.BouncyCastle.Utilities
 {
@@ -6,5 +9,125 @@ namespace Org.BouncyCastle.Utilities
     {
         public const int NumBits = 8;
         public const int NumBytes = 1;
+
+        public static void Xor(int len, byte[] x, byte[] y, byte[] 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] = (byte)(x[i] ^ y[i]);
+            }
+#endif
+        }
+
+        public static void Xor(int len, byte[] x, int xOff, byte[] y, int yOff, byte[] 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] = (byte)(x[xOff + i] ^ y[yOff + i]);
+            }
+#endif
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public static void Xor(int len, ReadOnlySpan<byte> x, ReadOnlySpan<byte> y, Span<byte> z)
+        {
+            int i = 0;
+            if (Vector.IsHardwareAccelerated)
+            {
+                int limit = len - Vector<byte>.Count;
+                while (i <= limit)
+                {
+                    var vx = new Vector<byte>(x[i..]);
+                    var vy = new Vector<byte>(y[i..]);
+                    (vx ^ vy).CopyTo(z[i..]);
+                    i += Vector<byte>.Count;
+                }
+            }
+            {
+                int limit = len - 4;
+                while (i <= limit)
+                {
+                    z[i + 0] = (byte)(x[i + 0] ^ y[i + 0]);
+                    z[i + 1] = (byte)(x[i + 1] ^ y[i + 1]);
+                    z[i + 2] = (byte)(x[i + 2] ^ y[i + 2]);
+                    z[i + 3] = (byte)(x[i + 3] ^ y[i + 3]);
+                    i += 4;
+                }
+            }
+            {
+                while (i < len)
+                {
+                    z[i] = (byte)(x[i] ^ y[i]);
+                    ++i;
+                }
+            }
+        }
+#endif
+
+        public static void XorTo(int len, byte[] x, byte[] z)
+        {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            XorTo(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 XorTo(int len, byte[] x, int xOff, byte[] z, int zOff)
+        {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            XorTo(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 XorTo(int len, ReadOnlySpan<byte> x, Span<byte> z)
+        {
+            int i = 0;
+            if (Vector.IsHardwareAccelerated)
+            {
+                int limit = len - Vector<byte>.Count;
+                while (i <= limit)
+                {
+                    var vx = new Vector<byte>(x[i..]);
+                    var vz = new Vector<byte>(z[i..]);
+                    (vx ^ vz).CopyTo(z[i..]);
+                    i += Vector<byte>.Count;
+                }
+            }
+            {
+                int limit = len - 4;
+                while (i <= limit)
+                {
+                    z[i + 0] ^= x[i + 0];
+                    z[i + 1] ^= x[i + 1];
+                    z[i + 2] ^= x[i + 2];
+                    z[i + 3] ^= x[i + 3];
+                    i += 4;
+                }
+            }
+            {
+                while (i < len)
+                {
+                    z[i] ^= x[i];
+                    ++i;
+                }
+            }
+        }
+#endif
     }
 }