summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs30
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs32
-rw-r--r--crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs27
3 files changed, 83 insertions, 6 deletions
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
index 2e22bfea1..90a5a0dbb 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS256Digest.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             return 32;
         }
 
-        public void BlockUpdate(byte input)
+        public void Update(byte input)
         {
             if (off > 32 - 1)
                 throw new ArgumentException("total input cannot be more than 32 bytes");
@@ -34,6 +34,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             off += len;
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public void BlockUpdate(ReadOnlySpan<byte> input)
+        {
+            if (off > 32 - input.Length)
+                throw new ArgumentException("total input cannot be more than 32 bytes");
+
+            input.CopyTo(buffer.AsSpan(off));
+            off += input.Length;
+        }
+#endif
+
         public int DoFinal(byte[] output, int outOff)
         {
             // TODO Check received all 32 bytes of input?
@@ -44,7 +55,22 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
             Reset();
 
-            return output.Length;
+            return 32;
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int DoFinal(Span<byte> output)
+        {
+            // TODO Check received all 32 bytes of input?
+
+            Span<byte> s = stackalloc byte[32];
+            Haraka256Perm(s);
+            Xor(s, buffer, output[..32]);
+
+            Reset();
+
+            return 32;
         }
+#endif
     }
 }
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
index c83eb8d8c..d96509f62 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaS512Digest.cs
@@ -40,6 +40,17 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             off += len;
         }
 
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public void BlockUpdate(ReadOnlySpan<byte> input)
+        {
+            if (off > 64 - input.Length)
+                throw new ArgumentException("total input cannot be more than 64 bytes");
+
+            input.CopyTo(buffer.AsSpan(off));
+            off += input.Length;
+        }
+#endif
+
         public int DoFinal(byte[] output, int outOff)
         {
             // TODO Check received all 64 bytes of input?
@@ -52,7 +63,24 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
 
             Reset();
 
-            return s.Length;
+            return 32;
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        public int DoFinal(Span<byte> output)
+        {
+            // TODO Check received all 64 bytes of input?
+
+            Span<byte> s = stackalloc byte[64];
+            Haraka512Perm(s);
+            Xor(s[8..], buffer.AsSpan(8), output[..8]);
+            Xor(s[24..], buffer.AsSpan(24), output[8..24]);
+            Xor(s[48..], buffer.AsSpan(48), output[24..32]);
+
+            Reset();
+
+            return 32;
         }
+#endif
     }
-}
\ No newline at end of file
+}
diff --git a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
index fa96512ea..5efafc1db 100644
--- a/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
+++ b/crypto/src/pqc/crypto/sphincsplus/HarakaSBase.cs
@@ -65,7 +65,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             BrAesCtOrtho(output);
         }
 
-        protected void Haraka512Perm(byte[] output)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal void Haraka512Perm(Span<byte> output)
+#else
+        internal void Haraka512Perm(byte[] output)
+#endif
         {
             uint[] w = new uint[16];
             ulong[] q = new ulong[8];
@@ -116,7 +120,11 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             }
         }
 
-        protected void Haraka256Perm(byte[] output)
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal void Haraka256Perm(Span<byte> output)
+#else
+        internal void Haraka256Perm(byte[] output)
+#endif
         {
             uint[] q = new uint[8];
             InterleaveConstant32(q, buffer, 0);
@@ -138,8 +146,13 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
             BrAesCtOrtho(q);
             for (int i = 0; i < 4; i++)
             {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+                Pack.UInt32_To_LE(q[i << 1], output[(i << 2)..]);
+                Pack.UInt32_To_LE(q[(i << 1) + 1], output[((i << 2) + 16)..]);
+#else
                 Pack.UInt32_To_LE(q[i << 1], output, i << 2);
                 Pack.UInt32_To_LE(q[(i << 1) + 1], output, (i << 2) + 16);
+#endif
             }
         }
 
@@ -678,5 +691,15 @@ namespace Org.BouncyCastle.Pqc.Crypto.SphincsPlus
                 z[zOff + i] = (byte)(x[xOff + i] ^ y[yOff + i]);
             }
         }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        protected static void Xor(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y, Span<byte> z)
+        {
+            for (int i = 0; i < z.Length; i++)
+            {
+                z[i] = (byte)(x[i] ^ y[i]);
+            }
+        }
+#endif
     }
 }