diff options
-rw-r--r-- | crypto/src/asn1/DerBitString.cs | 2 | ||||
-rw-r--r-- | crypto/src/math/BigInteger.cs | 39 | ||||
-rw-r--r-- | crypto/src/math/ec/custom/sec/SecT571Field.cs | 16 | ||||
-rw-r--r-- | crypto/src/math/raw/Interleave.cs | 55 | ||||
-rw-r--r-- | crypto/src/util/Integers.cs | 17 | ||||
-rw-r--r-- | crypto/src/util/Longs.cs | 17 |
6 files changed, 124 insertions, 22 deletions
diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index 2b1ff3354..8aab88353 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -125,7 +125,7 @@ namespace Org.BouncyCastle.Asn1 return; } - int bits = BigInteger.BitLen(namedBits); + int bits = 32 - Integers.NumberOfLeadingZeros(namedBits); int bytes = (bits + 7) / 8; Debug.Assert(0 < bytes && bytes <= 4); diff --git a/crypto/src/math/BigInteger.cs b/crypto/src/math/BigInteger.cs index 50229e2db..f915beafc 100644 --- a/crypto/src/math/BigInteger.cs +++ b/crypto/src/math/BigInteger.cs @@ -2,6 +2,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; +#if NET5_0_OR_GREATER +using System.Runtime.Intrinsics.X86; +#endif using System.Runtime.Serialization; using System.Text; @@ -136,26 +139,6 @@ namespace Org.BouncyCastle.Math public static readonly BigInteger Four; public static readonly BigInteger Ten; - //private readonly static byte[] BitCountTable = - //{ - // 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - // 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - // 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - // 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - // 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 - //}; - private readonly static byte[] BitLengthTable = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, @@ -911,6 +894,13 @@ namespace Org.BouncyCastle.Math public static int BitCnt(int i) { +#if NET5_0_OR_GREATER + if (Popcnt.IsSupported) + { + return (int)Popcnt.PopCount((uint)i); + } +#endif + uint u = (uint)i; u = u - ((u >> 1) & 0x55555555); u = (u & 0x33333333) + ((u >> 2) & 0x33333333); @@ -976,8 +966,15 @@ namespace Org.BouncyCastle.Math // // BitLen(value) is the number of bits in value. // - internal static int BitLen(int w) + private static int BitLen(int w) { +#if NET5_0_OR_GREATER + if (Lzcnt.IsSupported) + { + return 32 - (int)Lzcnt.LeadingZeroCount((uint)w); + } +#endif + uint v = (uint)w; uint t = v >> 24; if (t != 0) diff --git a/crypto/src/math/ec/custom/sec/SecT571Field.cs b/crypto/src/math/ec/custom/sec/SecT571Field.cs index 4d3f715fa..97bc08d67 100644 --- a/crypto/src/math/ec/custom/sec/SecT571Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT571Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NET5_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -399,6 +403,18 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) { +#if NET5_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + z[zOff ] ^= Z.GetElement(0); + z[zOff + 1] ^= Z.GetElement(1); + return; + } +#endif + //u[0] = 0; u[1] = y; for (int i = 2; i < 16; i += 2) diff --git a/crypto/src/math/raw/Interleave.cs b/crypto/src/math/raw/Interleave.cs index 409ab83e8..560fd76fb 100644 --- a/crypto/src/math/raw/Interleave.cs +++ b/crypto/src/math/raw/Interleave.cs @@ -1,4 +1,7 @@ using System; +#if NET5_0_OR_GREATER +using System.Runtime.Intrinsics.X86; +#endif namespace Org.BouncyCastle.Math.Raw { @@ -29,6 +32,14 @@ namespace Org.BouncyCastle.Math.Raw internal static ulong Expand32to64(uint x) { +#if NET5_0_OR_GREATER + if (Bmi2.IsSupported) + { + return (ulong)Bmi2.ParallelBitDeposit(x >> 16, 0x55555555U) << 32 + | Bmi2.ParallelBitDeposit(x , 0x55555555U); + } +#endif + // "shuffle" low half to even bits and high half to odd bits x = Bits.BitPermuteStep(x, 0x0000FF00U, 8); x = Bits.BitPermuteStep(x, 0x00F000F0U, 4); @@ -40,6 +51,15 @@ namespace Org.BouncyCastle.Math.Raw internal static void Expand64To128(ulong x, ulong[] z, int zOff) { +#if NET5_0_OR_GREATER + if (Bmi2.X64.IsSupported) + { + 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); @@ -72,6 +92,15 @@ namespace Org.BouncyCastle.Math.Raw internal static void Expand64To128Rev(ulong x, ulong[] z, int zOff) { +#if NET5_0_OR_GREATER + if (Bmi2.X64.IsSupported) + { + z[zOff ] = Bmi2.X64.ParallelBitDeposit(x >> 32, 0xAAAAAAAAAAAAAAAAUL); + z[zOff + 1] = Bmi2.X64.ParallelBitDeposit(x , 0xAAAAAAAAAAAAAAAAUL); + 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); @@ -126,6 +155,14 @@ namespace Org.BouncyCastle.Math.Raw internal static ulong Unshuffle(ulong x) { +#if NET5_0_OR_GREATER + if (Bmi2.X64.IsSupported) + { + return Bmi2.X64.ParallelBitExtract(x, 0xAAAAAAAAAAAAAAAAUL) << 32 + | Bmi2.X64.ParallelBitExtract(x, 0x5555555555555555UL); + } +#endif + // "unshuffle" even bits to low half and odd bits to high half x = Bits.BitPermuteStep(x, 0x2222222222222222UL, 1); x = Bits.BitPermuteStep(x, 0x0C0C0C0C0C0C0C0CUL, 2); @@ -137,6 +174,14 @@ namespace Org.BouncyCastle.Math.Raw internal static ulong Unshuffle(ulong x, out ulong even) { +#if NET5_0_OR_GREATER + if (Bmi2.X64.IsSupported) + { + even = Bmi2.X64.ParallelBitExtract(x, 0x5555555555555555UL); + return Bmi2.X64.ParallelBitExtract(x, 0xAAAAAAAAAAAAAAAAUL); + } +#endif + ulong u0 = Unshuffle(x); even = u0 & 0x00000000FFFFFFFFUL; return u0 >> 32; @@ -144,6 +189,16 @@ namespace Org.BouncyCastle.Math.Raw internal static ulong Unshuffle(ulong x0, ulong x1, out ulong even) { +#if NET5_0_OR_GREATER + if (Bmi2.X64.IsSupported) + { + even = Bmi2.X64.ParallelBitExtract(x0, 0x5555555555555555UL) + | Bmi2.X64.ParallelBitExtract(x1, 0x5555555555555555UL) << 32; + return Bmi2.X64.ParallelBitExtract(x0, 0xAAAAAAAAAAAAAAAAUL) + | Bmi2.X64.ParallelBitExtract(x1, 0xAAAAAAAAAAAAAAAAUL) << 32; + } +#endif + ulong u0 = Unshuffle(x0); ulong u1 = Unshuffle(x1); even = (u1 << 32) | (u0 & 0x00000000FFFFFFFFUL); diff --git a/crypto/src/util/Integers.cs b/crypto/src/util/Integers.cs index 116250375..b32cdfc30 100644 --- a/crypto/src/util/Integers.cs +++ b/crypto/src/util/Integers.cs @@ -1,4 +1,7 @@ using System; +#if NET5_0_OR_GREATER +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -42,6 +45,13 @@ namespace Org.BouncyCastle.Utilities public static int NumberOfLeadingZeros(int i) { +#if NET5_0_OR_GREATER + if (Lzcnt.IsSupported) + { + return (int)Lzcnt.LeadingZeroCount((uint)i); + } +#endif + if (i <= 0) return (~i >> (31 - 5)) & (1 << 5); @@ -57,6 +67,13 @@ namespace Org.BouncyCastle.Utilities public static int NumberOfTrailingZeros(int i) { +#if NET5_0_OR_GREATER + if (Bmi1.IsSupported) + { + return (int)Bmi1.TrailingZeroCount((uint)i); + } +#endif + int n = DeBruijnTZ[(uint)((i & -i) * 0x0EF96A62) >> 27]; int m = (((i & 0xFFFF) | (int)((uint)i >> 16)) - 1) >> 31; return n - m; diff --git a/crypto/src/util/Longs.cs b/crypto/src/util/Longs.cs index e6ff2ea39..ff45a8143 100644 --- a/crypto/src/util/Longs.cs +++ b/crypto/src/util/Longs.cs @@ -1,4 +1,7 @@ using System; +#if NET5_0_OR_GREATER +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -45,6 +48,13 @@ namespace Org.BouncyCastle.Utilities public static int NumberOfLeadingZeros(long i) { +#if NET5_0_OR_GREATER + if (Lzcnt.X64.IsSupported) + { + return (int)Lzcnt.X64.LeadingZeroCount((ulong)i); + } +#endif + int x = (int)(i >> 32), n = 0; if (x == 0) { @@ -56,6 +66,13 @@ namespace Org.BouncyCastle.Utilities public static int NumberOfTrailingZeros(long i) { +#if NET5_0_OR_GREATER + if (Bmi1.X64.IsSupported) + { + return (int)Bmi1.X64.TrailingZeroCount((ulong)i); + } +#endif + int n = DeBruijnTZ[(uint)((ulong)((i & -i) * 0x045FBAC7992A70DAL) >> 58)]; long m = (((i & 0xFFFFFFFFL) | (long)((ulong)i >> 32)) - 1L) >> 63; return n - (int)m; |