From 19a9b08c6cb1a4924b7c1dd9956c4ab791f34853 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 11 Nov 2022 16:51:30 +0700 Subject: Add Xor methods --- crypto/src/util/Bytes.cs | 123 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'crypto/src') 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 x, ReadOnlySpan y, Span z) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + int limit = len - Vector.Count; + while (i <= limit) + { + var vx = new Vector(x[i..]); + var vy = new Vector(y[i..]); + (vx ^ vy).CopyTo(z[i..]); + i += Vector.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 x, Span z) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + int limit = len - Vector.Count; + while (i <= limit) + { + var vx = new Vector(x[i..]); + var vz = new Vector(z[i..]); + (vx ^ vz).CopyTo(z[i..]); + i += Vector.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 } } -- cgit 1.4.1