From 17b0cc528f52df638d1261fb872fea7bf4228c95 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 2 Aug 2022 01:22:48 +0700 Subject: Use intrinsics in custom binary curves --- crypto/src/math/ec/custom/sec/SecT113Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT131Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT163Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT193Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT233Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT239Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT283Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT409Field.cs | 18 ++++++++++++++++++ crypto/src/math/ec/custom/sec/SecT571Field.cs | 10 ++++++++++ 9 files changed, 154 insertions(+) diff --git a/crypto/src/math/ec/custom/sec/SecT113Field.cs b/crypto/src/math/ec/custom/sec/SecT113Field.cs index c41d9f7d7..1b3fcc542 100644 --- a/crypto/src/math/ec/custom/sec/SecT113Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT113Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -202,6 +206,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 57 == 0); Debug.Assert(y >> 57 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] = z0 & M57; + z[zOff + 1] = (z0 >> 57) ^ (z1 << 7); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT131Field.cs b/crypto/src/math/ec/custom/sec/SecT131Field.cs index 4ff5999a4..53a9b832f 100644 --- a/crypto/src/math/ec/custom/sec/SecT131Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT131Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -301,6 +305,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 45 == 0); Debug.Assert(y >> 45 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] = z0 & M44; + z[zOff + 1] = (z0 >> 44) ^ (z1 << 20); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT163Field.cs b/crypto/src/math/ec/custom/sec/SecT163Field.cs index 44105039d..22d41882f 100644 --- a/crypto/src/math/ec/custom/sec/SecT163Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT163Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -312,6 +316,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 56 == 0); Debug.Assert(y >> 56 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] = z0 & M55; + z[zOff + 1] = (z0 >> 55) ^ (z1 << 9); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT193Field.cs b/crypto/src/math/ec/custom/sec/SecT193Field.cs index 59da8b000..795e4fb35 100644 --- a/crypto/src/math/ec/custom/sec/SecT193Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT193Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -279,6 +283,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 49 == 0); Debug.Assert(y >> 49 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] ^= z0 & M49; + z[zOff + 1] ^= (z0 >> 49) ^ (z1 << 15); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT233Field.cs b/crypto/src/math/ec/custom/sec/SecT233Field.cs index c16a3d612..08819f5ac 100644 --- a/crypto/src/math/ec/custom/sec/SecT233Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT233Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -290,6 +294,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 59 == 0); Debug.Assert(y >> 59 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] ^= z0 & M59; + z[zOff + 1] ^= (z0 >> 59) ^ (z1 << 5); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT239Field.cs b/crypto/src/math/ec/custom/sec/SecT239Field.cs index de87b18a2..d377667ae 100644 --- a/crypto/src/math/ec/custom/sec/SecT239Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT239Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -299,6 +303,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 60 == 0); Debug.Assert(y >> 60 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] ^= z0 & M60; + z[zOff + 1] ^= (z0 >> 60) ^ (z1 << 4); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT283Field.cs b/crypto/src/math/ec/custom/sec/SecT283Field.cs index ee5ad89c5..2ee96048f 100644 --- a/crypto/src/math/ec/custom/sec/SecT283Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT283Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -373,6 +377,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 57 == 0); Debug.Assert(y >> 57 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] = z0 & M57; + z[zOff + 1] = (z0 >> 57) ^ (z1 << 7); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT409Field.cs b/crypto/src/math/ec/custom/sec/SecT409Field.cs index 0fb7377f6..414a094a8 100644 --- a/crypto/src/math/ec/custom/sec/SecT409Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT409Field.cs @@ -1,5 +1,9 @@ using System; using System.Diagnostics; +#if NETCOREAPP3_0_OR_GREATER +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +#endif using Org.BouncyCastle.Math.Raw; @@ -344,6 +348,20 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Debug.Assert(x >> 59 == 0); Debug.Assert(y >> 59 == 0); +#if NETCOREAPP3_0_OR_GREATER + if (Pclmulqdq.IsSupported) + { + var X = Vector128.CreateScalar(x); + var Y = Vector128.CreateScalar(y); + var Z = Pclmulqdq.CarrylessMultiply(X, Y, 0x00); + ulong z0 = Z.GetElement(0); + ulong z1 = Z.GetElement(1); + z[zOff ] ^= z0 & M59; + z[zOff + 1] ^= (z0 >> 59) ^ (z1 << 5); + return; + } +#endif + //u[0] = 0; u[1] = y; u[2] = u[1] << 1; diff --git a/crypto/src/math/ec/custom/sec/SecT571Field.cs b/crypto/src/math/ec/custom/sec/SecT571Field.cs index 91a3fde9d..5a393409a 100644 --- a/crypto/src/math/ec/custom/sec/SecT571Field.cs +++ b/crypto/src/math/ec/custom/sec/SecT571Field.cs @@ -175,6 +175,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec public static ulong[] PrecompMultiplicand(ulong[] x) { +#if NETCOREAPP3_0_OR_GREATER + ulong[] z = Nat576.Create64(); + Nat576.Copy64(x, z); + return z; +#else /* * Precompute table of all 4-bit products of x (first section) */ @@ -197,6 +202,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Nat.ShiftUpBits64(len, t, 0, 4, 0UL, t, len); return t; +#endif } public static void Reduce(ulong[] xx, ulong[] z) @@ -367,6 +373,9 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec protected static void ImplMultiplyPrecomp(ulong[] x, ulong[] precomp, ulong[] zz) { +#if NETCOREAPP3_0_OR_GREATER + ImplMultiply(x, precomp, zz); +#else uint MASK = 0xF; /* @@ -399,6 +408,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec Nat.ShiftUpBits64(18, zz, 0, 8, 0UL); } } +#endif } protected static void ImplMulwAcc(ulong[] u, ulong x, ulong y, ulong[] z, int zOff) -- cgit 1.4.1