summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-21 01:00:40 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-21 01:00:40 +0700
commit975ccde41b51c6ca564f67b678aeca77b51c02a3 (patch)
treefb1aa374dc01e588e5ed01431d8808b5e3e28516
parentRemove unnecessary special cases (diff)
downloadBouncyCastle.NET-ed25519-975ccde41b51c6ca564f67b678aeca77b51c02a3.tar.xz
Refactoring in Pqc.Crypto.Cmce (performance)
-rw-r--r--crypto/src/pqc/crypto/cmce/CmceEngine.cs50
1 files changed, 44 insertions, 6 deletions
diff --git a/crypto/src/pqc/crypto/cmce/CmceEngine.cs b/crypto/src/pqc/crypto/cmce/CmceEngine.cs
index 9641cb6fb..10b08e708 100644
--- a/crypto/src/pqc/crypto/cmce/CmceEngine.cs
+++ b/crypto/src/pqc/crypto/cmce/CmceEngine.cs
@@ -1,4 +1,7 @@
 using System;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+using System.Runtime.InteropServices;
+#endif
 
 using Org.BouncyCastle.Asn1.Nist;
 using Org.BouncyCastle.Crypto;
@@ -1482,11 +1485,25 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
                         mask = (byte)(mat_row[i] ^ mat_k[i]);
                         mask >>= j;
                         mask &= 1;
-                        mask = (byte)-mask;
 
-                        for (c = 0; c < SYS_N / 8; c++)
+                        c = 0;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+                        ulong mask64 = 0UL - mask;
+                        int limit64 = (SYS_N / 8) - 8;
+                        while (c <= limit64)
+                        {
+                            ulong t0 = MemoryMarshal.Read<ulong>(mat_k.AsSpan(c)) & mask64;
+                            ulong t1 = MemoryMarshal.Read<ulong>(mat_row.AsSpan(c)) ^ t0;
+                            MemoryMarshal.Write(mat_row.AsSpan(c), ref t1);
+                            c += 8;
+                        }
+#endif
+                        byte maskByte = (byte)-mask;
+                        while (c < SYS_N / 8)
                         {
-                            mat_row[c] ^= (byte)(mat_k[c] & mask);
+                            mat_row[c] ^= (byte)(mat_k[c] & maskByte);
+                            ++c;
                         }
                     }
 
@@ -1505,11 +1522,32 @@ namespace Org.BouncyCastle.Pqc.Crypto.Cmce
                             byte[] mat_k = mat[k];
                             mask = (byte)(mat_k[i] >> j);
                             mask &= 1;
-                            mask = (byte)-mask;
 
-                            for (c = 0; c < SYS_N / 8; c++)
+                            //mask = (byte)-mask;
+
+                            //for (c = 0; c < SYS_N / 8; c++)
+                            //{
+                            //    mat_k[c] ^= (byte)(mat_row[c] & mask);
+                            //}
+
+                            c = 0;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+                            ulong mask64 = 0UL - mask;
+                            int limit64 = (SYS_N / 8) - 8;
+                            while (c <= limit64)
+                            {
+                                ulong t0 = MemoryMarshal.Read<ulong>(mat_row.AsSpan(c)) & mask64;
+                                ulong t1 = MemoryMarshal.Read<ulong>(mat_k.AsSpan(c)) ^ t0;
+                                MemoryMarshal.Write(mat_k.AsSpan(c), ref t1);
+                                c += 8;
+                            }
+#endif
+                            byte maskByte = (byte)-mask;
+                            while (c < SYS_N / 8)
                             {
-                                mat_k[c] ^= (byte)(mat_row[c] & mask);
+                                mat_k[c] ^= (byte)(mat_row[c] & maskByte);
+                                ++c;
                             }
                         }
                     }